Tuesday, 9 June 2015

Tic-Tac-Toe game



Code for Tic-Tac-Toe game in C++ Programming



 



 



 



 
#include<iostream.h>
#include<graphics.h>
#include<stdlib.h>
#include<stdio.h>
#include<conio.h>
#include<ctype.h>
#include<dos.h>

// MACROS USED#define full 1
#define empty 0
#define radius 15
#define OutOfRange 1
#define OccupiedCell 2

// CONSTANTS ... x,y coordinates and labels for circlesconstint midx[9]={50,100,150,50,100,150,50,100,150};
constint midy[9]={150,150,150,200,200,200,250,250,250};
constchar label[9][2]={"1","2","3","4","5","6","7","8","9"};

// ENUMERATED DATATYPESenum turn { human1, human2};
enumbool { false, true};

// FUNCTIONS USEDvoid IllegalMove(int type);        // validates the entered cell no.void DeclareWinner(turn player);    // declare the winnervoid IllegalMove(int type)
{
   int x;
   x=getmaxx();
   setcolor(BLACK);

   settextjustify(CENTER_TEXT, CENTER_TEXT);
   settextstyle(DEFAULT_FONT, HORIZ_DIR, 1);

   outtextxy(x/2-10,375,"Illegal Move !!! Enter Again ...");
   if(type==OutOfRange)
      outtextxy(x/2-10,400,"Invalid Cell Number");
   else
      outtextxy(x/2-10,400,"Cell Is Pre-occupied");
   while(!kbhit())
   {
      setcolor(BROWN);
      outtextxy(x/2-10,375,"Illegal Move !!! Enter Again ...");
      if(type==OutOfRange)
     outtextxy(x/2-10,400,"Invalid Cell Number");
      else
     outtextxy(x/2-10,400,"Cell Is Pre-occupied");
      sound(2000);    delay(20);     nosound();
   }
   setcolor(BLACK);
   outtextxy(getmaxx()/2-10,375,"Illegal Move !!! Enter Again ...");
   if(type==OutOfRange)
      outtextxy(x/2-10,400,"Invalid Cell Number");
   else
      outtextxy(x/2-10,400,"Cell Is Pre-occupied");
}// end IllegalMove()void DeclareWinner(turn player)
{
   setcolor(WHITE);

   settextjustify(CENTER_TEXT, CENTER_TEXT);
   settextstyle(DEFAULT_FONT, HORIZ_DIR, 1);

   if(player==human1)
      outtextxy(getmaxx()/2-10,375,"P L A Y E R - 1  is the  W I N N E R !!!");
   else
      outtextxy(getmaxx()/2-10,375,"P L A Y E R - 2  is the  W I N N E R !!!");
   sound(5000); sleep(2); nosound();
}// end DeclareWinner()//**************************************************************************// CLASS Board//**************************************************************************class Board{
   private:
      int p1[9];        // cells marked with player1 movesint p2[9];        // cells marked with player2 moves
      turn player;        // human1 / human2 / machine to play nextint p1_turns;        // number of turns p1 hadint p2_turns;        // number of turns p2 hadpublic:
      Board();            // constructorbool IsWin(void);        // is there a win in this position?bool IsLegal(int pos);    // is the move legal?void MakeMove(int pos);    // make a movevoid SetPlayer(turn p);    // swap player1 and player2
      turn WhoPlays(void);    // returns the player currently playingint GetTurn(void);    // get the turn player is takingvoid plot_board(void);    // displays the boardvoid fill_cell(constint pos, constint player); // displays boards statusvoid ResetAll(void);       // resets everything
};// end class Board

Board::Board()
{
   for(int i=0; i<9; i++)
   {
      p1[i]=empty;          // reset all cells to empty
      p2[i]=empty;
   }

   player=human1;        // set 1st player as human1// set initial turns of p1 and p2 to 0 (zero)
   p1_turns=0;
   p2_turns=0;
}// end Board()bool Board::IsWin()
{
   int *ptr;

   if(player==human1)
      ptr=p1;                // point to appropriate arrayelse
      ptr=p2;

   // check for 3 in a Row or 3 in a Columnif( (ptr[0] && ptr[1] && ptr[2]) ||    // horizontal
       (ptr[3] && ptr[4] && ptr[5]) ||
       (ptr[6] && ptr[7] && ptr[8]) ||
       (ptr[0] && ptr[3] && ptr[6]) ||    // vertical
       (ptr[1] && ptr[4] && ptr[7]) ||
       (ptr[2] && ptr[5] && ptr[8]) ||
       (ptr[0] && ptr[4] && ptr[8]) ||    // diagonal
       (ptr[2] && ptr[4] && ptr[6]) )
   {
      setcolor(BLACK);
      setlinestyle(SOLID_LINE,1,THICK_WIDTH);

      if(ptr[0] && ptr[1] && ptr[2])
     line(midx[0],midy[0],midx[2],midy[2]);
      if(ptr[3] && ptr[4] && ptr[5])
     line(midx[3],midy[3],midx[5],midy[5]);
      if(ptr[6] && ptr[7] && ptr[8])
     line(midx[6],midy[6],midx[8],midy[8]);

      if(ptr[0] && ptr[3] && ptr[6])
     line(midx[0],midy[0],midx[6],midy[6]);
      if(ptr[1] && ptr[4] && ptr[7])
     line(midx[1],midy[1],midx[7],midy[7]);
      if(ptr[2] && ptr[5] && ptr[8])
     line(midx[2],midy[2],midx[8],midy[8]);

      if(ptr[0] && ptr[4] && ptr[8])
     line(midx[0],midy[0],midx[8],midy[8]);
      if(ptr[2] && ptr[4] && ptr[6])
     line(midx[2],midy[2],midx[6],midy[6]);

      returntrue;
   }
   returnfalse;
}// end IsWin()bool Board::IsLegal(int pos)
{
   if(p1[pos-1]==empty && p2[pos-1]==empty)
      returntrue;
   returnfalse;
}// end IsLegal()void Board::MakeMove(int pos)
{
   if(player==human1)
   {
      p1[pos-1]=full;
      p1_turns++;
      fill_cell(pos-1,human1);
   }
   else
   {
      p2[pos-1]=full;
      p2_turns++;
      fill_cell(pos-1,2);
   }
}// end MakeMove()void Board::SetPlayer(turn p)
{
   player=p;
}// end SetPlayer()

turn Board::WhoPlays(void)
{
   return player;
}// end WhoPlays()int Board::GetTurn()
{
   if(player==human1)
      return p1_turns;
   return p2_turns;
}// end GetTurnvoid Board::plot_board()
{
   int maxx,maxy;
   setcolor(BLUE);

   // draw the border
   setlinestyle(SOLID_LINE,1,NORM_WIDTH);
   rectangle(15,115,185,285);
   setfillstyle(SOLID_FILL,BROWN);
   floodfill(30,130,BLUE);

   setlinestyle(SOLID_LINE,1,NORM_WIDTH);
   rectangle(20,120,180,280);
   setfillstyle(SOLID_FILL,YELLOW);
   floodfill(30,130,BLUE);

   setlinestyle(SOLID_LINE,1,THICK_WIDTH);
   rectangle(25,125,175,275);
   setfillstyle(SOLID_FILL,MAGENTA);
   floodfill(30,130,BLUE);

   setlinestyle(SOLID_LINE,1,NORM_WIDTH);

   // draw 9 circlefor(int i=0,j=0; i<9,j<9; i++,j++)
      circle(midx[i],midy[i],radius);

   // fill the circles with black colourfor(i=0,j=0; i<9,j<9; i++,j++)
   {
      setfillstyle(SOLID_FILL,WHITE);
      floodfill(midx[i],midy[i],BLUE);
   }// end for// label each circlefor(i=0,j=0; i<9,j<9; i++,j++)
   {
      setcolor(BLUE);
      settextjustify(CENTER_TEXT, CENTER_TEXT);
      settextstyle(DEFAULT_FONT, HORIZ_DIR, 1);
      outtextxy(midx[i],midy[i],label[i]);
   }// end for// cursor positions where moves will be made
   {
      int px,p1y,p2y;
      maxx=getmaxx();
      maxy=getmaxy();
      setcolor(YELLOW);
      settextjustify(CENTER_TEXT, CENTER_TEXT);
      settextstyle(SANS_SERIF_FONT, HORIZ_DIR, 1);
      outtextxy(maxx/2-10, maxy/2-100, "M O V E S . . .");
      setcolor(RED);
      outtextxy(maxx/2+80, maxy/2-40, "Player1 : |");

      px=maxx/2+135; p1y=maxy/2-40;
      for(i=1; i<=5; i++)
      {
     outtextxy(px, p1y, "_|");
     px += 23;
      }// end for

      setcolor(GREEN);
      outtextxy(maxx/2+80, maxy/2+9, "Player2 : |");

      px=maxx/2+135; p2y=maxy/2+9;
      for(i=1; i<=5; i++)
      {
     outtextxy(px, p2y, "_|");
     px += 23;
      }// end for
   }
}// end plot_board()void Board::fill_cell(constint pos, constint player)
{
   int i=pos;
   if(i==3 || i==5 || i==7 || i==8)
   {
      setfillstyle(SOLID_FILL,BLUE);
      floodfill(midx[i]+10,midy[i]+10,BLUE);

      setfillstyle(SOLID_FILL,WHITE);
      floodfill(midx[i]+10,midy[i]+10,MAGENTA);

      setlinestyle(SOLID_LINE,1,NORM_WIDTH);
      setcolor(BLUE);
      circle(midx[i],midy[i],radius);

      if(player==human1)
     setfillstyle(SOLID_FILL,RED);
      else
     setfillstyle(SOLID_FILL,GREEN);

      floodfill(midx[i]+10,midy[i]+10,BLUE);

      settextjustify(CENTER_TEXT, CENTER_TEXT);
      settextstyle(DEFAULT_FONT, HORIZ_DIR, 1);
      outtextxy(midx[i],midy[i],label[i]);
   }
   else
   {
      if(player==human1)
     setfillstyle(SOLID_FILL,RED);
      elseif(player==2)
     setfillstyle(SOLID_FILL,GREEN);
      floodfill(midx[i]+10,midy[i]+10,BLUE);
   }
}// end fill_cell()void Board::ResetAll(void)
{
   for(int i=0; i<9; i++)
   {
      p1[i]=empty;          // reset all cells to empty
      p2[i]=empty;
   }

   player=human1;        // set 1st player as human1// set initial turns of p1 and p2 to 0 (zero)
   p1_turns=0;
   p2_turns=0;
}// end ResetAll()//**************************************************************************// FUNCTION main()//**************************************************************************void main(void)
{
   void main_menu(void);

   Board Board1;    // object of class Board
   turn  Turn;        // whos turn is it (human1, human2)char ans='y';    // users choice .. continue play or notint count;        // counts total number of movesconst xcoord[5]={57,60,63,66,69};  // coordinates where player is gonnaconst ycoord[2]={13,16};          // enter the cell no.int p_turn;        // no. of turns player hadint cell_no=0;    // cell no. entered by userint x,y;

   // request auto detectionint gmode,gdriver=DETECT,errorcode;

   // initialize graphics and local variables
   initgraph(&gdriver,&gmode,"\\tc\\BGI");

   // read result of initialization
   errorcode = graphresult();
   if (errorcode != grOk)      // an error occurred
   {
      cout<<"Graphics error: %s\n"<< grapherrormsg(errorcode);
      cout<<"Press any key to exit:";
      getch();
      exit(1);             // terminate with an error code
   }

   while(tolower(ans)!='n')
   {
      // clear the device (screen)
      cleardevice();

      setcolor(YELLOW);
      settextstyle(DEFAULT_FONT,HORIZ_DIR,1);
      outtextxy(getmaxx()/2-90,4,"TIC - TAC - TOE");
      outtextxy(getmaxx()/2-90,16,"***************");

      Board1.plot_board();
      count=1;

      while(count<=9)
      {
     Turn=Board1.WhoPlays();
     p_turn=Board1.GetTurn();

     if(Turn==human1)
     {
        setcolor(BLACK);
        settextjustify(CENTER_TEXT, CENTER_TEXT);
        settextstyle(DEFAULT_FONT, HORIZ_DIR, 1);
        outtextxy(getmaxx()/2-12,350," Player 2's Turn . . .");
        setcolor(YELLOW);
        outtextxy(getmaxx()/2-12,350," Player 1's Turn . . .");
        sound(500); delay(50); nosound();
     }
     else
     {
        setcolor(BLACK);
        settextjustify(CENTER_TEXT, CENTER_TEXT);
        settextstyle(DEFAULT_FONT, HORIZ_DIR, 1);
        outtextxy(getmaxx()/2-12,350," Player 1's Turn . . .");
        setcolor(YELLOW);
        outtextxy(getmaxx()/2-12,350," Player 2's Turn . . .");
        sound(1000); delay(50); nosound();
     }

     // get cell number from the player
     gotoxy(xcoord[p_turn],ycoord[Turn]);
     cell_no=getch()-'0';

     // check if valid cell no. is entered if not keep on askingwhile(cell_no<1 || cell_no>9)
     {
        IllegalMove(OutOfRange);
        gotoxy(xcoord[p_turn],ycoord[Turn]);
        cell_no=getch()-'0';
     }

     // check if the entered cell_no is legal (is not pre-occupied)while(Board1.IsLegal(cell_no) == false)
     {
        IllegalMove(OccupiedCell);
        gotoxy(xcoord[p_turn],ycoord[Turn]);
        cell_no=getch()-'0';
     }

     // display the cell no at proper position
     gotoxy(xcoord[p_turn],ycoord[Turn]);
     cout<<cell_no;

     // if not fill the cell
     Board1.MakeMove(cell_no);

     // if number of turns of a player exceeds 2 then check if this move// made him win or not as atleast 3 moves are required for a player// to win this gameif(p_turn>=2)
        if(Board1.IsWin())
        {
           DeclareWinner(Turn);
           count=10;
        }

     // swap playersif(Turn==human1)
        Board1.SetPlayer(human2);
     else
        Board1.SetPlayer(human1);

     // increment count
     count++;
      }// end while(count<=9)// count = 10 means there is no winner ... game is a drawif(count==10)
      {
     setcolor(WHITE);
     outtextxy(getmaxx()/2-10,375,"I T  I S  A   D R A W !!!");
     sound(5000); sleep(2); nosound();
      }// end if// clear the device (screen)
      cleardevice();

      // ask the user if he wnts to continue
      setcolor(YELLOW);
      settextjustify(CENTER_TEXT, CENTER_TEXT);
      settextstyle(DEFAULT_FONT, HORIZ_DIR, 1);
      outtextxy(getmaxx()/2,getmaxy()/2-7,"DO YOU WANT TO PLAY MORE : (y / n) : ");
      gotoxy(60,15);
      ans=getch();

      while(tolower(ans)!='y' && tolower(ans)!='n')
      {
     setcolor(BLACK);
     settextjustify(CENTER_TEXT, CENTER_TEXT);
     settextstyle(DEFAULT_FONT, HORIZ_DIR, 1);
     outtextxy(getmaxx()/2,getmaxy()/2-7,"DO YOU WANT TO PLAY MORE : (y / n) :   ");
     setcolor(YELLOW);
     outtextxy(getmaxx()/2,getmaxy()/2-7,"DO YOU WANT TO PLAY MORE : (y / n) : ");
     gotoxy(60,15);
     ans=getch();
      }

      gotoxy(60,15);
      cout<<ans;
      getch();

      if(tolower(ans)=='y')
     Board1.ResetAll();
      else
      {
     y=350;
     int bk=getbkcolor();
     for(int i=640;;i--)
     {
        setcolor(BROWN);
        outtextxy(i,y,"THANK YOU ... HAVE NICE TIME");
        delay(5);
        if(i==330)
           break;
        else
        {
           setcolor(bk);
           outtextxy(i,y,"THANK YOU ... HAVE NICE TIME");
        }
     }// end for
      }// end if(ans=='y')
   }// end while(tolower(ans)!='n')// get user end key stroke
   getch();

   // clean up ... close the graph
   closegraph();
}// end main()

No comments:

Post a Comment