-
Tic tac toe game
Hi this is my first post I just wondered if anyone could help this code is for a very simple tic tac toe (Os&Xs) game I have two problems with it one is that when it asks if you would like to play again it doesnt seem to matter what you enter it starts a new game. Two is that when you play another game instead of the grid showing 1 - 9 you get a load of random characters.
Can anyone help?
Thanks a lot
#include <stdio.h>
#include <stdlib.h>
void print_grid();
char player(int number);
int search4win(int *moves, int length);
void tictactoe();
void reset_board();
int wins[8][3]={{1,2,3},{4,5,6},{7,8,9},{1,4,7},{2,5,8},{3,6,9}, {1,5,9},{3,5,7}};
char board[9]={'1','2','3','4','5','6','7','8','9'};
/* X will be represented by 1
O will be represented by -1
*/
int main()
{
int play=1;
char again;
while (play >= 1)
{
tictactoe();
printf("would you like another go Y or N\n");
scanf("%c", &again);
getchar();
if ((again='y') || (again='Y'))
{
play++;
reset_board();
}
else if ((again='n') || (again='N'))
{
printf("Thank you for playing goodbye\n");
play=0;
}
else
printf("Invalid entry\n");
}
return 0;
}
void tictactoe()
{
int Xmoves[5], Omoves[4];
int go, goes=0, turn=1, row=0, Xgoes=0, Ogoes=0;
print_grid();
while ((goes < 9) && (row != 3))
{
printf("Would player %c please enter there move\n", (player(turn)));
scanf("%d", &go);
getchar();
printf("your go was %d \n", go);
if((go < 10) && (go > 0) && (board[go-1] != 'X') && (board[go-1] != 'O'))
{
board[go-1]=(player(turn));
print_grid();
if (turn > 0)
{
Xmoves[Xgoes]=go;
//printf("Xgoes is %d \n", Xgoes);
//printf("Xmoves[Xgoes] is %d \n", Xmoves[Xgoes]);
Xgoes++;
if (Xgoes >2)
{
row = search4win(Xmoves, Xgoes);
}
//printf("row is %d \n", row);
}
else
{
Omoves[Ogoes]=go;
Ogoes++;
if (Ogoes >2)
{
row=search4win(Omoves, Ogoes);
}
//printf("row is %d \n", row);
}
if(row==3) // if there is a line of 3 the winner is announced
{
printf("The winner is %c\n", (player(turn)));
}
goes++; //increments the number of goes had by both O and X
turn=turn*(-1); //this line changes whose turn it is
}
else
printf("invalid entry\n");
}
}
void reset_board()
{ int i=0, n=1;
for(i=0; i<=8; i++)
{
board[i]=n;
n++;
}
}
char player(int number)
{
return (number > 0) ? 'X' : 'O';
/*char temp;
if ( number > 0)
temp = 'X';
else
temp = 'O';
return temp;*/
}
void print_grid()
{
printf("\n %c|%c|%c\n -+-+-\n", board[6], board[7], board[8]);
printf(" %c|%c|%c\n -+-+-\n", board[3], board[4], board[5]);
printf(" %c|%c|%c\n\n", board[0], board[1], board[2]);
}
int search4win(int *moves, int length)
{
int i=0, j=0, k=0, n, line=0, ret;
while(line < 3 && j < 8)
{
for(i=0; i<3; i++)
{
n=wins[j][i];
//printf("n is %d\n", n);
for(k=0; k<length; k++)
{
if (n == moves[k])
line++;
//printf("line is %d \n", line);
}
}
if (line == 3)
return 3;
else
line=0;
j++;
}
return 0;
}
-
1 Attachment(s)
Sorry that last code was poorly posted I have attached the source code with this post for you to look at]
Seth
-
Better still, read about code tags then edit your original post to add them to your code. :)
[edit]
In your code, this is incorrect:
>>if ((again = 'y') || (again = 'Y'))
you need two equals sign for comparisons, one equals is for assignment. Make it
>>if ((again == 'y') || (again == 'Y'))
or better still, lookup the toupper() function.
-
Code:
if ((again='y') || (again='Y'))
{
//...
}
else if ((again='n') || (again='N'))
{
//...
}
Change the "=" to "=="
-
yeah...again='y' sets again to the value 'y'. The syntax is correct in the BASIC languages, but in C, = is the assignment operator and == is used for comparisons. If you're prone to making this mistake, write your if statements like this: if ('y'==again) because that will make the compiler spew error messages at you if you only use one =.
-
Code:
void reset_board()
{ int i=0, n=1;
for(i=0; i<=8; i++)
{
board[i]=n;
n++;
}
}
board[i]=n gives the ascii value of the character 1 and thats not the same as '1'.
Instead declare n as char , like char n = '1'
and then it should work.
Or typecast like board[i]=(char)n;
But i just read java in school so i dont remember
if it works in c. :-)
-
If you want to have the new game display 1 to 9 in the grid then
Code:
void reset_board()
{
int i=0, n=1;
for(i=0; i<=8; i++)
{
board[i]=n;
n++;
}
}
can be changed to
Code:
void reset_board()
{
int i;
for(i=0; i<=8; i++)
{
board[i]= i + '0'; // load the character value of the current index
}
}
-
Sorry, change the '0' to '1' because your loop starts at 0
-
Thanks everyone
Thanks everyone that posted I have now got my program working. I have posted the current code to try out the code tags.
Code:
#include <stdio.h>
#include <stdlib.h>
void print_grid();
char player(int number);
int search4win(int *moves, int length);
int tictactoe();
void reset_board();
int wins[8][3]={{1,2,3},{4,5,6},{7,8,9},{1,4,7},{2,5,8},{3,6,9},{1,5,9},{3,5,7}};
char board[9]={'1','2','3','4','5','6','7','8','9'};
/* X will be represented by 1
O will be represented by -1
*/
int main()
{
int play=1, winner, win[3]={0,0,0} /*Xwin=0, Owin=0, draw=0*/;
char again;
while (play >= 1)
{
winner=tictactoe();
switch (winner){
case 1:
//Xwin++;
win[0]++;
break;
case -1:
//Owin++;
win[1]++;
break;
case 0:
//draw++;
win[2]++;
break;
default:
printf("Unknown winner");
break;
}
printf("So far \n X has won: %d times\n O has won: %d times\n and there have been %d draws.\n", win[0], win[1], win[2]);
printf("would you like another go Y or N\n");
scanf("%c", &again);
getchar();
if ((again=='y') || (again=='Y'))
{
play++;
reset_board();
}
else if ((again=='n') || (again=='N'))
{
printf("Thank you for playing goodbye\n");
play=0;
}
else
printf("Invalid entry\n");
}
return 0;
}
int tictactoe()
{
int Xmoves[5], Omoves[4];
int go, goes=0, turn=1, row=0, Xgoes=0, Ogoes=0;
print_grid();
while ((goes < 9) && (row != 3))
{
printf("Would player %c please enter there move\n", (player(turn)));
scanf("%d", &go);
getchar();
//printf("your go was %d \n", go); //This is a test line not needed in finsished game
if((go < 10) && (go > 0) && (board[go-1] != 'X') && (board[go-1] != 'O'))
/*This line first checks if the number is between 1 and 9 and then checks that neither X or O has already been in that location*/
{
board[go-1]=(player(turn));
print_grid();
if (turn > 0)
{
Xmoves[Xgoes]=go;
//printf("Xgoes is %d \n", Xgoes); // Test lines
//printf("Xmoves[Xgoes] is %d \n", Xmoves[Xgoes]);
Xgoes++;
if (Xgoes >2)
{
row = search4win(Xmoves, Xgoes);
}
//printf("row is %d \n", row); //Test line
}
else
{
Omoves[Ogoes]=go;
Ogoes++;
if (Ogoes >2)
{
row=search4win(Omoves, Ogoes);
}
//printf("row is %d \n", row); //Test line
}
if(row==3) // if there is a line of 3 the winner is announced
{
printf("The winner is %c\n", (player(turn)));
return turn;
}
goes++; //increments the number of goes had by both O and X
turn=turn*(-1); //this line changes whose turn it is
}
else
printf("invalid entry\n");
}
return 0;
}
void reset_board()
{
int i;
for(i=0; i<=8; i++)
{
board[i]= i + '1'; // load the character value of the current index
}
}
/*void reset_board()
{ int i=0;
char new_board[9]={'1','2','3','4','5','6','7','8','9'};
for(i=0; i<=8; i++)
{
board[i]=new_board[i];
//printf("reset to %d \n", board[i]);
}
}*/
char player(int number)
{
return (number > 0) ? 'X' : 'O';
/*char temp;
if ( number > 0)
temp = 'X';
else
temp = 'O';
return temp;*/
}
void print_grid()
{
printf("\n %c|%c|%c\n -+-+-\n", board[6], board[7], board[8]);
printf(" %c|%c|%c\n -+-+-\n", board[3], board[4], board[5]);
printf(" %c|%c|%c\n\n", board[0], board[1], board[2]);
}
int search4win(int *moves, int length)
{
int i=0, j=0, k=0, n, line=0, ret;
while(line < 3 && j < 8)
{
for(i=0; i<3; i++)
{
n=wins[j][i];
//printf("n is %d\n", n);
for(k=0; k<length; k++)
{
if (n == moves[k])
line++;
//printf("line is %d \n", line);
}
}
if (line == 3)
return 3;
else
line=0;
j++;
}
return 0;
}
Thanks again everyone!! If you have any more suggestions on how I could improve my code then please keep posting
seth :D
-
I don't actually use the const==arg format, because I agree with you that it is hard to read. However, it was the only way of which I knew to make sure that popped up an error on compile.