/* compile using:               */
/* gcc ./connect4.c -o connect4 */
/* By: Michael K. Pellegrino    */
/* Free for public use          */
/* Just keep this heading       */

#include <stdio.h>
static int board[9][8];
static int fullness[9];

int checkX(int r, int c)
{
  int piece=board[r+1][c];
  int count;
  /* determine bounds */
  int upper=r-2;
  int lower=r+4;
  int left=c-3;
  int right=c+3;
  if( upper<0 ) upper=0;
  if( lower>5 ) lower=5;
  if( left<0 ) left=0;
  if( right>6 ) right=6;
  int Top=upper;
  int Bottom=lower;
  int Left=left;
  int Right=right;

  /* check \ */
  count=0;
  {
    int m=Left;
    for(int i=Top;i<=Bottom;i++)
      {
	if( board[i][m++] == piece )
	  {
	    count++;
	    if( count== 4) return(piece);
	  }
	else
	  {
	    count=0;
	  }
      }
  }
   count=0;
  /* check / */
  int j=Bottom;
  int k=Left;
  
  for(int i=1; i<=4; i++ )
    {
      if( board[j--][k++] == piece )
	{
	  count++;
	  if( count== 4) return(piece);
	}
      else
	{
	  count=0;
	}
    }
 
  count=0;
  /* check | */
  for( int i=r;i<=Bottom;i++ )
    {
      if( board[i][c] == piece )
	{
	  count++;
	  if( count==4) return(piece);
	}
      else
	{
	  count=0;
	}
    }
  count=0;
  /* check - */
  for( int i=Left; i<=Right;i++ )
    {
      if( board[r][i] == piece )
	{
	  count++;
	  if( count==4) return(piece);
	}
      else
	{
	  count=0;
	}
    }
  return(-1);
}

void showBoard()
{
  char P;
  printf( "\n\n\n\n---------------\n 1 2 3 4 5 6 7\n---------------\n" );
  for( int r=0;r<6;r++)
    {
      for( int c=0;c<7;c++ )
	{
	  switch( (int)board[r][c] )
	    {
	    case 0:
	      P=' ';
	      break;
	    case 1:
	      P='X';
	      break;
	    default:
	      P='O';
	    }
	  printf( "|%c",P );
	}
      printf( "|\n" );
    }
  printf( "---------------\n 1 2 3 4 5 6 7\n---------------\n" );
  return;
}

int putPiece( int c, int p)
{
  /* c = column, p = player */
  if( c<0 || c>6 ) return(-1);
  if( fullness[c] < 0 ) return(-1);
  board[fullness[c]--][c]=p;
  return 0;    
}

void initBoard()
{
  for( int r=0;r<6;r++)
    {
      for( int c=0;c<7;c++ )
	{
	  board[r][c]=0;
	}
    }
  return;
}

int main()
{
  printf( "* ------------------------------------- *\n" );
  printf( "* Connect-4 | By: Michael K. Pellegrino *\n" );
  printf( "*                                       *\n" );
  printf( "*         Play/Distrubute/Modify        *\n" );
  printf( "*         Just keep this header         *\n" );
  printf( "* ------------------------------------- *\n" );
  printf( "\n\n\nEnter Column Number or -1 to end game\n");
  int move=0;
  int turn=1;
  int playing=1;
  int w=0;
  char again[5]={"     "};
  int a=1;  
  while( a )
    {
      move=0;
      turn=1;
      playing=1;
      w=0;
      
      /* init the board and fullness arrays */
      for( int r=0;r<6;r++)
	{
	  for( int c=0;c<7;c++ )
	    {
	      board[r][c]=0;
	      fullness[c]=5;
	      
	    }
	}
      
      /* ------------------- */
      while( playing )
	{
	  showBoard();
	  printf( "Player %d:",turn );
	  scanf( "%d", &move ); 
	  if( move == -1 )
	    {
	      playing=0;
	      break;
	    }
	  if( putPiece( move-1, turn ) < 0 )
	    {
	      printf( "oops...\n" );
	    }
	  else
	    {
	      w=checkX(fullness[move-1],move-1);
	      turn++;
	      if( turn>2 ) turn=1;
	      
	    }
	  
	  if( w > 0 )
	    {
	      showBoard();
	      printf( "Player %d wins!!!!\n\n", w );
	      playing=0;
	    }
	}
      
      printf( "\n\nWould you like to play again? (y/n)\n" );
      scanf( "%s", &again );
      if( again[0]=='Y' || again[0]=='y' )
	{
	  a=1;
	}
      else
	{
	  return(0);
	}
    }
  return(0);
}