C Programming Reference >> C Games Programming Tutorials >>
Tic Tac Toe 1.0equisite Knowledege
27/12/06 - 3924 Views - Ratings :     4.84 of 5 / 125 Votes
Level - Intermediate
Here you will learn how to create a game called Tic Tac Toe through C . Tic Tac Toe is a very old game, nobody knows its origin but its so simple thier is even a probability that early man had its own version of the game.All you have to do is to get your three symbol in straight line. Tic Tac Toe game using C is relatively easy to program and beginners can give it a shot if they undestand carry on otherwise read the basic tutorials first and then comeback and learn how to create there very own tic tac toe game using C. Read last section for source code, executable and copyright.
Graphic Library Used - Turbo C/C++ Bgi
Operating System Used - Windows XP Professional
Contents -
1. Requirements
2. Getting Started
3. Coding Main
4. Intializing Graphics
5. Game Data
6. Board Intilization
7. Mapping Board
8. Game Engine
9. Taking Input
10. Computer Move using AI
11. Checking Winner
12. Final Words
13. What Next?
1. Requirements
From Programming point of view i am assuming you have some knowledge of C and we will build this program from scratch for better understanding . If you absolute beginner check this out if you dont understand go through basic tutorials first.
But before you start you need some tools. You must install Turbo C++ 3.0 IDE and install it in folder C:\TC (Please Choose same directory name and drive if you are beginner). Thats all now you are all done to start your games programming fantasies.
Back To Top
2. Getting Started
Go to C:\TC\Bin there you will find a executable file called TC execute it and IDE will load itself.
Now go to File Menu and choose New.
Now Press F2 to save the file. Give it name tictacto.c (only 8 character filename is allowed).
Now you are all set to rock. The screen should be something like this -

Back To Top
3. Coding Main
First Thing a program should do is to include header files and code main only header we will be needing is graphics.h and conio.h. Including unnecessary header files increase the size of the code and compile time. Next we create an parameterless int returning main with no code at present. Your Code should look like this -
#include <graphics.h>
#include <conio.h>
int main ()
{
return 0;
} |
Back To Top
4. Intializing Graphics
Now we intialise graphics in main, stop for a key press and then close the graphics. When we stop you should se a blank page and not any error. If you face an error make sure your installation path is correct. All our game activity occurs in this opening and closing of graphics. It will generally give you a 640*480 mode with VGA graphics. These graphics are good enough to code any descent looking games. If you get different settings try to set them as above. Your code should be now -
#include <graphics.h>
#include <conio.h>
int main ()
{
int gdriver = DETECT, gmode;
initgraph(&gdriver, &gmode, "c:\\tc\\bgi"); // Intializes Graphics
getch (); // Key Press
closegraph (); // Close Graphics
return 0;
} |
Back To Top
5. Game Data
Now we create data your game needs . In this game we need following data -
We need a 2D 3 X 3 Matrix To Store the board. Each member of the board contains one the three values -
'O' if there is a zero at that place.
'X' if there is a cross at that place
'*' if there is no element at that place ie. placed has not yet been filled.
Now accomodating storage our code becomes -
#include <graphics.h>
#include <conio.h>
char board [3] [3]; // Remeber Indexing Starts at Zero.
int main ()
{
int gdriver = DETECT, gmode;
initgraph(&gdriver, &gmode, "c:\\tc\\bgi"); // Intializes Graphics
getch (); // Key Press
closegraph (); // Close Graphics
return 0;
} |
Back To Top
6. Board Initialization
Now we create a function which intializes the entire board to '*'.
This indicates that no block is filled.
We use a function called initiateboard called in main to do this job for us.
#include <graphics.h>
#include <conio.h>
char board [3] [3]; // Remeber Indexing Starts at zero
void initiateboard ()
{
int i,j;
for (i = 0; i <= 2 ; i++)
{
for (j = 0; j <= 2; j++)
{
board [i] [j] = '*';
}
}
}
int main ()
{
int gdriver = DETECT, gmode;
initgraph (&gdriver, &gmode, "c:\\tc\\bgi");
initiateboard ();
getch ();
closegraph ();
return 0;
}
|
Back To Top
7. Mapping Board
This is a very important function in our program. Its job is to create a graphical image of the game form the data array board.
It first clears all the graphics on the present screen.
Then its initate the graphics and redraw the entire screen.
First the function draws the border lines. Then it draws a cross, a circle or nothing depending upon the values in the array.
It uses function drawcircle and drawcross to draw circles and cross respectively. These function take input value 0 to 9 depending upon the array positon to decide what to draw.
This function is first called in intialisation but will be called several times
Here some screenshot of the game developed till now -
We call this function mapboard and our code now becomes -
#include <graphics.h>
#include <conio.h>
char board [2] [2]; // Remeber Indexing Starts at zero
void drawcircle (int position) // Draws a circle on basis of Input use mathematics reduce complexity
{
int centrex;
int centrey;
centrex = 245 + (50*(position%3)) + 25;
centrey = 165 + (50*(position/3)) + 25;
fillellipse (centrex,centrey, 10,10);
}
void drawcross (int position)
{
int centrex;
int centrey;
centrex = 245 + (50*(position%3)) + 25;
centrey = 165 + (50*(position/3)) + 25;
line (centrex-5,centrey+5,centrex+5,centrey-5);
line (centrex+5,centrey+5,centrex-5,centrey-5);
}
void mapboard ()
{
int gdriver = DETECT, gmode;
int i,j;
closegraph ();
initgraph (&gdriver, &gmode, "c:\\tc\\bgi");
// Draw 4 Lines to Form Board
line (295,165,295,315);
line (345,165,345,315);
line (245,215,395,215);
line (245,265,395,265);
for (i = 0; i <= 2; i++)
{
for (j = 0; j <= 2; j++)
{
if ( board [i] [j] == 'X') drawcross (3*i + j);
if ( board [i] [j] == 'O') drawcircle (3*i + j);
}
}
outtextxy (40,472,"Remove This Line by Learn Coding It yourself at www.cencyclopedia.com");
}
void initiateboard ()
{
int i,j;
for (i = 0; i <= 2 ; i++)
{
for (j = 0; j <= 2; j++)
{
board [i] [j] = '*';
}
}
mapboard ();
}
int main ()
{
int gdriver = DETECT, gmode;
initgraph (&gdriver, &gmode, "c:\\tc\\bgi");
initiateboard ();
getch ();
closegraph ();
return 0;
}
|
Back To Top
8. Game Engine -
Now we design a game engine for this game. This Game engine will contain an which end after 5 Users moves assuming user moves first. Now our game engine must do the following jobs in one sequence.
1. Take user input .
2. Place user move on board.
3. Calculate computer move.
4. Place computer move on board.
5. Refresh Screen for next round.
6. Check wether there is a winner.
we use fuction play to be name of our game engine and game exits when the function exits. This function is called once in main.
Now we have designed mapboard function in such a way that it can be used to refresh screen and can do the 5th job. We discuss the rest next.
Back To Top
9. Taking Input
We create a function name input which does the first two jobs of our game engine. It takes user input and if valid place that on to the data.
User is asked to input X coordinate (1 - 3) and Y coordinate (1 - 3).
If in our data board [X-1] and [Y-1] position is '*' then we place a 'X' There otherwise reprompt for input.
Here is a screenshot of the Game Developed Till Now -

Code Now Becomes -
#include <graphics.h>
#include <conio.h>
char board [3] [3]; // Remeber Indexing Starts at zero
void drawcircle (int position) // Draws a circle on basis of Input use mathematics reduce complexity
{
int centrex;
int centrey;
centrex = 245 + (50*(position%3)) + 25;
centrey = 165 + (50*(position/3)) + 25;
fillellipse (centrex,centrey, 10,10);
}
void drawcross (int position)
{
int centrex;
int centrey;
centrex = 245 + (50*(position%3)) + 25;
centrey = 165 + (50*(position/3)) + 25;
line (centrex-5,centrey+5,centrex+5,centrey-5);
line (centrex+5,centrey+5,centrex-5,centrey-5);
}
void mapboard ()
{
int gdriver = DETECT, gmode;
int i,j;
closegraph ();
initgraph (&gdriver, &gmode, "c:\\tc\\bgi");
// Draw 4 Lines to Form Board
line (295,165,295,315);
line (345,165,345,315);
line (245,215,395,215);
line (245,265,395,265);
for (i = 0; i <= 2; i++)
{
for (j = 0; j <= 2; j++)
{
if ( board [i] [j] == 'X') drawcross (3*i + j);
if ( board [i] [j] == 'O') drawcircle (3*i + j);
}
}
outtextxy (40,472,"Remove This Line by Learn Coding It yourself at www.cencyclopedia.com");
}
void initiateboard ()
{
int i,j;
for (i = 0; i < 3 ; i++)
{
for (j = 0; j < 3; j++)
{
board [i] [j] = '*';
putchar (board [i] [j]);
}
}
mapboard ();
}
void input ()
{
int x,y;
printf ("\nEnter X Coordinate - ");
scanf ("%d",&x);
printf ("\nEnter Y Coordinate - ");
scanf ("%d", &y);
if (board [x-1] [y-1] == '*')
{
board [x-1] [y-1] = 'X';
}
else
{
mapboard ();
printf ("\nWrong Coordinates");
input ();
}
}
void play () // Ladies and Gentleman I give you our game engine.
{
int i;
for (i = 0; i<5;i++)
{
input ();
mapboard ();
}
}
int main ()
{
int gdriver = DETECT, gmode;
initgraph (&gdriver, &gmode, "c:\\tc\\bgi");
initiateboard ();
play ();
getch ();
closegraph ();
return 0;
}
|
Back To Top
10. Computer Move Using AI
Now after user move we need to make the computer move. Since this first version of the Article we will be using simple AI which maybe stupid but is AI nevertheless.
Our AI starts from the first box and where ever it finds first empty space it puts a zero. Is that complicated, well its not because its AI at its badest. May be we can improve this in next version.
We call this function computer.
Now Code Becomes -
#include <graphics.h>
#include <conio.h>
char board [3] [3]; // Remeber Indexing Starts at zero
void drawcircle (int position) // Draws a circle on basis of Input use mathematics reduce complexity
{
int centrex;
int centrey;
centrex = 245 + (50*(position%3)) + 25;
centrey = 165 + (50*(position/3)) + 25;
fillellipse (centrex,centrey, 10,10);
}
void drawcross (int position)
{
int centrex;
int centrey;
centrex = 245 + (50*(position%3)) + 25;
centrey = 165 + (50*(position/3)) + 25;
line (centrex-5,centrey+5,centrex+5,centrey-5);
line (centrex+5,centrey+5,centrex-5,centrey-5);
}
void mapboard ()
{
int gdriver = DETECT, gmode;
int i,j;
closegraph ();
initgraph (&gdriver, &gmode, "c:\\tc\\bgi");
// Draw 4 Lines to Form Board
line (295,165,295,315);
line (345,165,345,315);
line (245,215,395,215);
line (245,265,395,265);
for (i = 0; i <= 2; i++)
{
for (j = 0; j <= 2; j++)
{
if ( board [i] [j] == 'X') drawcross (3*i + j);
if ( board [i] [j] == 'O') drawcircle (3*i + j);
}
}
outtextxy (40,472,"Remove This Line by Learn Coding It yourself at www.cencyclopedia.com");
}
void initiateboard ()
{
int i,j;
for (i = 0; i < 3 ; i++)
{
for (j = 0; j < 3; j++)
{
board [i] [j] = '*';
putchar (board [i] [j]);
}
}
mapboard ();
}
void input ()
{
int x,y;
printf ("\nEnter X Coordinate - ");
scanf ("%d",&x);
printf ("\nEnter Y Coordinate - ");
scanf ("%d", &y);
if (board [x-1] [y-1] == '*')
{
board [x-1] [y-1] = 'X';
}
else
{
mapboard ();
printf ("\nWrong Coordinates");
input ();
}
}
void computer ()
{
int i,j;
for (i = 0; i < 3; i++)
for (j = 0; j < 3; j++)
{
if (board [i] [j] == '*')
{
board [i] [j] = 'O';
return;
}
}
}
void play () // Ladies and Gentleman I give you our game engine.
{
int i;
for (i = 0; i<5;i++)
{
input ();
computer ();
mapboard ();
}
printf ("\n\nGAME DRAW");
}
int main ()
{
int gdriver = DETECT, gmode;
initgraph (&gdriver, &gmode, "c:\\tc\\bgi");
initiateboard ();
play ();
getch ();
closegraph ();
return 0;
}
|
Back To Top
11. Checking Winner
Now last thing our gameengine must do is to see wether we have a winner or not.
This function use a flag variable key (arbitary name) which is initialise to '*'
Then our function checks all possible combination of winning and if it finds a character other than '*' in series of 3 it sets key value to it.
Then we calculate wether player wins, computer wins or nobody wins and game is still on.
Here is a final screenshot -
Now here is the final code of this version -
#include <graphics.h>
#include <conio.h>
char board [3] [3]; // Remeber Indexing Starts at zero
void drawcircle (int position) // Draws a circle on basis of Input use mathematics reduce complexity
{
int centrex;
int centrey;
centrex = 245 + (50*(position%3)) + 25;
centrey = 165 + (50*(position/3)) + 25;
fillellipse (centrex,centrey, 10,10);
}
void drawcross (int position)
{
int centrex;
int centrey;
centrex = 245 + (50*(position%3)) + 25;
centrey = 165 + (50*(position/3)) + 25;
line (centrex-5,centrey+5,centrex+5,centrey-5);
line (centrex+5,centrey+5,centrex-5,centrey-5);
}
void mapboard ()
{
int gdriver = DETECT, gmode;
int i,j;
closegraph ();
initgraph (&gdriver, &gmode, "c:\\tc\\bgi");
// Draw 4 Lines to Form Board
line (295,165,295,315);
line (345,165,345,315);
line (245,215,395,215);
line (245,265,395,265);
for (i = 0; i <= 2; i++)
{
for (j = 0; j <= 2; j++)
{
if ( board [i] [j] == 'X') drawcross (3*i + j);
if ( board [i] [j] == 'O') drawcircle (3*i + j);
}
}
outtextxy (40,472,"Remove This Line by Learn Coding It yourself at www.cencyclopedia.com");
}
void initiateboard ()
{
int i,j;
for (i = 0; i < 3 ; i++)
{
for (j = 0; j < 3; j++)
{
board [i] [j] = '*';
putchar (board [i] [j]);
}
}
mapboard ();
}
void input ()
{
int x,y;
printf ("\nEnter X Coordinate - ");
scanf ("%d",&x);
printf ("\nEnter Y Coordinate - ");
scanf ("%d", &y);
if (board [x-1] [y-1] == '*')
{
board [x-1] [y-1] = 'X';
}
else
{
mapboard ();
printf ("\nWrong Coordinates");
input ();
}
}
void computer ()
{
int i,j;
for (i = 0; i < 3; i++)
for (j = 0; j < 3; j++)
{
if (board [i] [j] == '*')
{
board [i] [j] = 'O';
return;
}
}
}
void check ()
{
int i;
char key = '*';
// Check Rows
for (i=0; i<3;i++)
if (board [i][0] == board [i] [1] && board [i][0] == board [i] [2] && board [i] [0] != '*') key = board [i] [0];
// Check Columns
for (i=0; i<3;i++)
if (board [0][i] == board [1] [i] && board [0][i] == board [2] [i] && board [0] [i] != '*') key = board [0] [i];
// Check Diagonals
if (board [0][0] == board [1] [1] && board [1][1] == board [2] [2] && board [1] [1] != '*') key = board [1] [1];
if (board [0][2] == board [1] [1] && board [1][1] == board [2] [0] && board [1] [1] != '*') key = board [1] [1];
//Declare Winner if any
if (key == 'X')
{
printf ("You Win");
getch ();
exit ();
}
if (key == 'O')
{
printf ("Computer Win");
getch ();
exit ();
}
}
void play () // Ladies and Gentleman I give you our game engine.
{
int i;
for (i = 0; i<5;i++)
{
input ();
computer ();
mapboard ();
check ();
}
printf ("\n\nGAME DRAW");
}
int main ()
{
int gdriver = DETECT, gmode;
initgraph (&gdriver, &gmode, "c:\\tc\\bgi");
initiateboard ();
play ();
getch ();
closegraph ();
return 0;
} |
Back To Top
12. Final Words
I Know what you must be thinking "Thats a Huge Code for a Tic Tac Toe ".
Is it difficult than you assumed, isnt it. Well one reason for its difficulty is it is build from scratch ie. very basic.
This tutorial teaches you some very important programming concepts such as mapping it will be used extensively in games programming.
If you finished this tutorial easily congratulate yourself because only a good c programmer could have done that.
If you got overwhelmed by it, dont worry study some more game tutorials and within days things will start making sense.
Well code has been tested several time and 100% functional if you still experience problem we are always there for you contanct.
Its 120 Lines of pure C Code!!! Enjoy It, Tinker with It and let your imagination run wild.
Back To Top
13. Whats Next ?
This is the first version of game and needs improvement. We will be getting back to it as soon as we can.
You have permission to copy this game executable and source code and modify it, Improve it, anything you want.
You can even publish this content on your website, we just ask you to pop us a mail and place a small link to us if you find this stuff worthy enough to be a part of your website!!!
If you have improved our Version of game contanct us and we will publish it on our website with proper credit given to you.
For All those programmers excited to get thier hands dirty heres where you can start -
1. Introducing Menu
2. 2-Player Game
3.Advance AI based on probability.
4. Trendy Colours
5. Enhanced Portability
6. 3-D Board
7. Difficulty levels
8. Sound Effects
9. Background music and much more....
Next Version of Game will have this and much more. Contribute your share, get credited for it and become world famous ;-)
Now get started with this source code and executable file -
Source Code
Executable
Back To Top
Reader Comments -
| vishal kedia
|
nice stuff......
|
| indu
|
you are doing an excellent job its really fabulous
|
| gerlyn
|
hey can u help me make my own game?
|
| rio
|
HI!! i am first timer in your web,can you pls give me asimple code for a simple C++ game programming
|
| ashis mohanty
|
really nice program
|
| kevin
|
Got me into c programming, way to go!!
|
| SUNIL
|
YAAR,THE BEST GAME TUTORIAL ON THE WEB. KUDOS TO U. YAAR,U R REALLY DOING A WONDERFUL BY SHARING UR KNOWLEDGE. THANKSSSSSSSSSSSS
|
| sachin sakle
|
the game "TIC TAC TOE" created is one of the best game that I have ever seen.
|
| Priyo
|
Awsome.But please increase the chances of the xomputer winning.
|
| Tsu
|
very helpful to those who want to know about game programming
|
| Sweet
|
Hello how can I find the link????
|
| nihar
|
i have added the two player mode too.Just the draw case in two player u have to enter the cord even though the table is full but do it once after that u get the output as draw.
#include #include #include char board [3] [3]; // Remeber Indexing Starts at zero void drawcircle (int position) // Draws a circle on basis of Input use mathematics reduce complexity { int centrex; int centrey; centrex = 245 + (50*(position%3)) + 25; centrey = 165 + (50*(position/3)) + 25; fillellipse (centrex,centrey, 10,10); } void drawcross (int position)
{ int centrex; int centrey; centrex = 245 + (50*(position%3)) + 25; centrey = 165 + (50*(position/3)) + 25; line (centrex-5,centrey+5,centrex+5,centrey-5); line (centrex+5,centrey+5,centrex-5,centrey-5); } void mapboard ()
{ int gdriver = DETECT, gmode; int i,j; closegraph (); initgraph (&gdriver, &gmode, "c:tcbgi"); // Draw 4 Lines to Form Board line (295,165,295,315); line (345,165,345,315); line (245,215,395,215); line (245,265,395,265); for (i = 0; i <= 2; i++) { for (j = 0; j <= 2; j++) { if ( board [i] [j] == 'X') drawcross (3*i + j); if ( board [i] [j] == 'O') drawcircle (3*i + j); } } } void initiateboard ()
{ int i,j; for (i = 0; i < 3 ; i++) { for (j = 0; j < 3; j++) { board [i] [j] = '*'; putchar (board [i] [j]); } } mapboard (); } void input () { int x,y; printf ("nEnter X Coordinate - "); scanf ("%d",&x); printf ("nEnter Y Coordinate - "); scanf ("%d", &y); if (board [x-1] [y-1] == '*') { board [x-1] [y-1] = 'X'; } else { mapboard (); printf ("nWrong Coordinates"); input (); } } void input2 () { int x,y; printf ("nEnter X Coordinate - "); scanf ("%d",&x); printf ("nEnter Y Coordinate - "); scanf ("%d", &y); if (board [x-1] [y-1] == '*') { board [x-1] [y-1] = 'O'; } else { mapboard (); printf ("ndraw"); } } void computer ()
{ int i,j; for (i = 0; i < 3; i++) for (j = 0; j < 3; j++) { if (board [i] [j] == '*') { board [i] [j] = 'O'; return; } } } void check () { int i; char key = '*'; // Check Rows for (i=0; i<3;i++) if (board [i][0] == board [i] [1] && board [i][0] == board [i] [2] && board [i] [0] != '*') key = board [i] [0]; // Check Columns for (i=0; i<3;i++) if (board [0][i] == board [1] [i] && board [0][i] == board [2] [i] && board [0] [i] != '*') key = board [0] [i]; // Check Diagonals if (board [0][0] == board [1] [1] && board [1][1] == board [2] [2] && board [1] [1] != '*') key = board [1] [1]; if (board [0][2] == board [1] [1] && board [1][1] == board [2] [0] && board [1] [1] != '*') key = board [1] [1]; //Declare Winner if any if (key == 'X') { printf ("You Win"); getch (); exit (); } if (key == 'O') { printf ("Computer Win"); getch (); exit (); } } void check2 () { int i; char key = '*'; // Check Rows for (i=0; i<3;i++) if (board [i][0] == board [i] [1] && board [i][0] == board [i] [2] && board [i] [0] != '*') key = board [i] [0]; // Check Columns for (i=0; i<3;i++) if (board [0][i] == board [1] [i] && board [0][i] == board [2] [i] && board [0] [i] != '*') key = board [0] [i]; // Check Diagonals if (board [0][0] == board [1] [1] && board [1][1] == board [2] [2] && board [1] [1] != '*') key = board [1] [1]; if (board [0][2] == board [1] [1] && board [1][1] == board [2] [0] && board [1] [1] != '*') key = board [1] [1]; //Declare Winner if any if (key == 'X') { printf ("player1 Win"); getch (); exit (); } if (key == 'O') { printf ("player2 Win"); getch (); exit (); } } void play ()
{ int i; for (i = 0; i<5;i++) { input (); computer (); mapboard (); check (); } printf ("nnGAME DRAW"); }
void play2 ()
{ int i,j; for (i = 0; i<5;i++) { input (); mapboard (); check2 (); input2 (); mapboard (); check2 (); } printf ("nnGAME DRAW"); } int main () { int ch; int gdriver = DETECT, gmode; initgraph (&gdriver, &gmode, "c:tcbgi"); printf("please enter your choicenn"); printf("1.play with computern 2.Two playersnn"); scanf("%d",&ch); switch(ch) { case 1:initiateboard (); play (); break; case 2:initiateboard (); play2(); break; }
getch (); closegraph (); return 0; }
|
| feel you
|
pdE Ba cOPy Yng prOgraM mU? heHe ProJEct nmin eHh
|
| can i copy your program
|
CAN I COPY YOUR PROGRAM FOR MY SPECIAL PROJECT?
|
|