I made a Tic Tac Toe game using C. Here two players, player1 and player2, can participate and play. Please rate my code and suggest improvements.
#include<stdio.h>
#include<conio.h>
void board(char t[]);
int cheak(char T[]);
void main()
{
int i=0,n,r=100,p=1;
char TOT[9]={'1','2','3','4','5','6','7','8','9'};
char a='X';
for(;i<9;i++)
{
clrscr();
board(TOT);
printf("\n\n\n Player1=X\nPlayer2=O");
printf(" \n player %d tern:-",p);
printf("\nEnter number");
scanf("%d",&n);
TOT[n-1]=a;
if(a=='X')
{
a='O';
}
else
{
a='X';
}
r=cheak(TOT);
if(r==1)
{
clrscr();
board(TOT);
printf("\nPlayer 1 win");
break;
}
if(r==2)
{
clrscr();
board(TOT);
printf("\nPlayer 2 win");
break;
}
if(p==1)
{
p=2;
}
else
{
p=1;
}
if(i==8)
{
clrscr();
board(TOT);
printf("\n\nMatch Draw");
break;
}
}
getch();
}
void board(char t[])
{
printf("_________________");
printf("\n|| %c || %c || %c ||",t[0],t[1],t[2]);
printf("\n|---------------|");
printf("\n|| %c || %c || %c ||",t[3],t[4],t[5]);
printf("\n|---------------|");
printf("\n|| %c || %c || %c ||",t[6],t[7],t[8]);
printf("\n|---------------|");
}
int cheak(char T[])
{
int i=0,n=0;
for(;n<3;n++)
{
if(T[i]=='X'&&T[i+1]=='X'&&T[i+2]=='X')
{
return 1;
}
i=i+3;
}
i=0;
for(n=0;n<3;n++)
{
if(T[i]=='X'&&T[i+3]=='X'&&T[i+6]=='X')
{
return 1;
}
i++;
}
if(T[0]=='X'&&T[4]=='X'&&T[8]=='X')
{
return 1;
}
if(T[2]=='X'&&T[4]=='X'&&T[6]=='X')
{
return 1;
}
i=0;
for(n=0;n<3;n++)
{
if(T[i]=='O'&&T[i+1]=='O'&&T[i+2]=='O')
{
return 2;
}
i=i+3;
}
i=0;
n=0;
for(;n<3;n++)
{
if(T[i]=='O'&&T[i+3]=='O'&&T[i+6]=='O')
{
return 2;
}
i++;
}
if(T[0]=='O'&&T[4]=='0'&&T[8]=='O')
{
return 2;
}
if(T[2]=='O'&&T[4]=='O'&&T[6]=='O')
{
return 2;
}
return 0;
}
1 Answer 1
void main()
is not portable
Although it "works" in a lot of cases, the only two portable definitions of main
are:
int main(void)
and
int main(int argc, char **argv)
Error checking
You don't check the return value of scanf
.
This would be better:
if(scanf("%d", &n) != 1)
{
fputs("Error; enter a number.", stderr);
return EXIT_FAILURE; /* entering a letter will cause infinite loop so error out here */
}
Note that EXIT_FAILURE
requires stdlib.h
to be included.
Out-of-bounds write
If a user enters a 0
or a number greater than 9
in the scanf
mentioned above, this line will write outside of the array bounds:
TOT[n-1]=a;
This can cause a segmentation fault.
Spelling
There are a couple spelling errors in this code:
cheak -> check
tern -> turn
Formatting
There are a few issues with formatting here; first of all, each line in a function should be indented by at least 4 spaces. In addition, you should put spaces after commas in function calls, and around most (if not all) operators.
Portability
Although clrscr
and getch
work with Windows and DOS, I would suggest simply removing clrscr
and replacing getch
with getchar
. This makes your code portable to the point where it can run on most other systems.
Non-descriptive variable names
At first glance, I don't know what t
, T
, TOT
, a
, i
, n
, r
, or p
are for. The variable names should describe what they contain.
Spacing
Although the board is nice, the prompt to the user isn't. I would suggest something like this:
printf("\n\n\nPlayer 1 = X\nPlayer 2 = O");
printf("\nPlayer %d's turn.",p);
printf("\n\nEnter a number: ");
...
if(r == 1 || r == 2)
{
board(TOT);
printf("\nPlayer %d wins!", r);
break;
}
Misc.
p
is already 1 here. You don't need to set it again:
else
{
p=1;
}