# Thread: Stumped on an infinite loop

1. ## Stumped on an infinite loop

Ok guys, be nice. First time posting
I'm a programming amateur. Only learned up to arrays so, nothing advanced yet please.

For a programming exercise, were asked to make a tic tac toe program. Here's the way I wrote it.

Code:
```#include <stdio.h>
#include <stdlib.h>
int checkDiag(int board[3][3])
{
if(board[1][1] == 0)
return 0;
if(board[1][1] == board[0][0] && board[1][1] == board[2][2])
return 1;
else if(board[1][1] == board[0][2] && board[1][1] == board[2][0])
return 1;
return 0;
}
int checkNondiag(int board[3][3])
{
int i, j, three = 1, check = 0;
for(i=0;i<3;i++)
if(board[i][i] == 0)
check++;
if(check == 3)
return 0;
for(i=0;i<3;i++)
{
three = 1;
for(j=1;j<3;j++)
{
if(board[i][0] == board[i][j])
three++;
}
if(three == 3)
return 1;
}
three = 1;
for(i=0;i<3;i++)
{
three = 1;
for(j=1;j<3;j++)
{
if(board[0][i] == board[i][j])
three++;
}
if(three == 3)
return 1;
}
return 0;
}
void gameboard(int board[3][3])
{
int i, j;
printf(" - - - \n|1|2|3|\n - - - \n|4|5|6|\n - - - \n|7|8|9|\n - - - \n\n");
printf(" - - - \n");
for(i=0;i<3;i++)
{
printf("|");
for(j=0;j<3;j++)
{
switch(board[i][j])
{
case 1: printf("X|");
break;
case 2: printf("O|");
break;
default: printf(" |");
}
}
printf("\n - - - \n");
}
}
int main(void)
{
int board[3][3] = {0, 0, 0, 0, 0, 0, 0, 0, 0};
int turn = 0, move = 0, win = 0, p1 = 0, p2 = 0;
int i, j;
do
{
do
{
if(checkDiag(board) == 1 || checkNondiag(board) == 1)
switch(turn)
{
case 0: p2++;
break;
case 1: p1++;
break;
}
system("cls");
printf("TIC TAC TOE IN C\n\n");
gameboard(board);
if(checkDiag(board) == 1 || checkNondiag(board) == 1)
switch(turn)
{
case 0: p2++;
break;
case 1: p1++;
break;
}
printf("\nPlayer 1(X): %d\nPlayer 2(O): %d\n\n", p1, p2);
if(checkDiag(board) == 1 || checkNondiag(board) == 1)
switch(turn)
{
case 0: printf("Player 2 won!\n");
win = 1;
for(i=0;i<3;i++)
for(j=0;j<3;j++)
board[i][j] = 0;
break;
case 1: printf("Player 1 won!\n");
win = 1;
for(i=0;i<3;i++)
for(j=0;j<3;j++)
board[i][j] = 0;
break;
}
printf("Player %d's turn!\n", turn + 1);
printf("What space would you like to use? ");
while(move < 1 || move > 9)
{
scanf("%d", &move);
if( move < 1 || move > 9)
printf("Invalid coordinates. Please enter another: ");
}
switch(move)
{
case 1: board[0][0] = turn + 1;
break;
case 2: board[0][1] = turn + 1;
break;
case 3: board[0][2] = turn + 1;
break;
case 4: board[1][0] = turn + 1;
break;
case 5: board[1][1] = turn + 1;
break;
case 6: board[1][2] = turn + 1;
break;
case 7: board[2][0] = turn + 1;
break;
case 8: board[2][1] = turn + 1;
break;
case 9: board[2][2] = turn + 1;
break;
}
switch(turn)
{
case 0: turn = 1;
break;
case 1: turn = 0;
break;
}
}while(win == 0);
}while(p1 < 5 && p2 < 5);
}```
Bear with me on the amateur-ish and inefficient coding.
May anyone tell me what's making it loop like that? and a solution?
And feel free to make suggestions to shorten my code. nothing to complicated, and only in C please. All the stuff I've used there is pretty much all that I've learned so far.

2. Why do you have to while-do loops? You can make one as
Code:
```do {
...
} while (win == 0 && p1 < 5 && p2 < 5);```
So if win = 1 it will exit. If p1 >=5 or p2>=5 it will exit.

Also, win doesn't seem to be necessary variable. You win, you empty the board, you start again. Isn't that true?
Then you break from the first do-while loop and continue on the outer do-while. Then win stays 1 for ever. You should skip win if you want this behavior.

So just keep the outer loop.

I know I am not answering the real question

Try adding at the end of the do-while
Code:
`printf("\n %d %d\n", p1, p2);`
to check those two values and see why they don't get incremented. Use printfs in general to get an output and check the flow of your program. It is better to use a debugger of course, but I am guessing you don't have one.

3. I forgot to state that the game only ends when one person has won 5 games Sorry.

Which do-while did you mean? Tried adding the one you said right after the inner do-while and now, it really was an infinite loop.

Concerning the debugger, I'm using Pelles C and I have the debugger thingies enabled(i think).
I never learned how to use it. We weren't taught how to use it(yet, hopefully) in class.

edit:
saw what you said about the win variable staying at 1, added a win = 0; right after the inner loop and it still doing that continuous thingy until it ends.

4. OK, leave the program as you posted it and replace
Code:
```printf("Player 2 won!\n");
printf("Player 1 won!\n");```
with
Code:
```printf("Player 2 games won!\nCurrent Score %d - %d\n", p1, p2);
printf("Player 1 games won!\nCurrent Score %d - %d\n", p1, p2);```
respectively and tell us the output. Do p1 and p2 increase as they should?

5. So I removed system("cls"); for a clearer look. The first output added to 2 to both p1 and p2 alternately until p1 won.

I found out that I had a duplicate code that added twice to the score so i removed that. Still the same behavior, adding 1 alternately to p1 and p2 until p1 won.

The question is, why does it not ask the 2nd player for a move? I saw that the move variable never resetted itself... You know what? I'll just post the code.

Code:
```int main(void)
{
int board[3][3] = {0, 0, 0, 0, 0, 0, 0, 0, 0};
int turn = 0, move = 0, win = 0, p1 = 0, p2 = 0;
int i, j;
do
{
do
{
system("cls");
printf("TIC TAC TOE IN C\n\n");
gameboard(board);
/* There was an extra if code here with a duplicate p1 and p2++, removed it*/
move = 0; /*added this so it stops that stupid loop.*/
if(checkDiag(board) == 1 || checkNondiag(board) == 1)
switch(turn)
{
case 0: p2++;
break;
case 1: p1++;
break;
}
printf("\nPlayer 1(X): %d\nPlayer 2(O): %d\n\n", p1, p2);
if(checkDiag(board) == 1 || checkNondiag(board) == 1)
switch(turn)
{
case 0: printf("Player 2 games won!\nCurrent Score %d - %d\n", p1, p2);;
win = 1;
for(i=0;i<3;i++)
for(j=0;j<3;j++)
board[i][j] = 0;
break;
case 1: printf("Player 1 games won!\nCurrent Score %d - %d\n", p1, p2);;
win = 1;
for(i=0;i<3;i++)
for(j=0;j<3;j++)
board[i][j] = 0;
break;
}
printf("Player %d's turn!\n", turn + 1);
printf("What space would you like to use? ");
while(move < 1 || move > 9)
{
scanf("%d", &move);
if( move < 1 || move > 9)
printf("Invalid coordinates. Please enter another: ");
}
switch(move)
{
case 1: board[0][0] = turn + 1;
break;
case 2: board[0][1] = turn + 1;
break;
case 3: board[0][2] = turn + 1;
break;
case 4: board[1][0] = turn + 1;
break;
case 5: board[1][1] = turn + 1;
break;
case 6: board[1][2] = turn + 1;
break;
case 7: board[2][0] = turn + 1;
break;
case 8: board[2][1] = turn + 1;
break;
case 9: board[2][2] = turn + 1;
break;
}
switch(turn)
{
case 0: turn = 1;
break;
case 1: turn = 0;
break;
}
}while(win == 0);
win = 0;
}while(p1 < 5 && p2 < 5);

}```
Now the game's screwed up Now that it's asking for turns, I played continously. At the first few moves, the board cleared. Then after a few more moves, player 1 won. i entered 1, 2, 3 , 4, 5 ,6 alternately to both players, so no one should've won. I guess the function i used to check who's won is also screwed up.

6. I don't see where you set win back to zero after a game.

Ninja'd!

7. Correct me if I am wrong, but you check for a winner
Code:
`if(checkDiag(board) == 1 || checkNondiag(board) == 1)`
then have one of them take a turn.
Code:
```while(move < 1 || move > 9)
{
scanf("%d", &move);
if( move < 1 || move > 9)
printf("Invalid coordinates. Please enter another: ");
}
switch(move)```
Wouldn't you want to do that the other way around?

Plus, what heppens in
Code:
```switch(turn)
{
case 0: turn = 1;
break;
case 1: turn = 0;
break;
}```
if turn ==2?

8. I don't see where you set win back to zero after a game.

Ninja'd!
It's right here:

Code:
```switch(turn)
{
case 0: turn = 1;
break;
case 1: turn = 0;
break;
}
}while(win == 0);
win = 0; <------------------------------|Right Here|
}while(p1 < 5 && p2 < 5);```
Wouldn't you want to do that the other way around?
Concerning the arrangement of the code, it's logical that the game board updates itself after every move.

So, let's assume that my program works and we're at the 5th turn(minimum amount of moves for someone to win).

After the player takes his/her turn, the first switch records the move into the game board then the second switch switches the players' turns.

The loop restarts, game board shows the 5th move, then it checks to see if anyone has won. If anyone won, it shows Player %d won! then ends the inner loop immediately.

Then the board array gets all its values back to 0 and start the game again.

edit:
if turn ==2?
turn is a pseudo-boolean variable. only switches from 0 and 1. Notice that there is no other code that changes turn's value aside from that switch code

9. Originally Posted by nirvana619

Concerning the arrangement of the code, it's logical that the game board updates itself after every move.

So, let's assume that my program works and we're at the 5th turn(minimum amount of moves for someone to win).

After the player takes his/her turn, the first switch records the move into the game board then the second switch switches the players' turns.

The loop restarts, game board shows the 5th move, then it checks to see if anyone has won. If anyone won, it shows Player %d won! then ends the inner loop immediately.

Then the board array gets all its values back to 0 and start the game again.

edit:

turn is a pseudo-boolean variable. only switches from 0 and 1. Notice that there is no other code that changes turn's value aside from that switch code
I ran it and player 1 won on the first move every time by selecting position 1, so I think there is an error on how you determine the winner.

As for the logic, it is fine, but if I win 5 rounds, the game should end. The way it is written, it starts another game even after I win 5 rounds and then ends. It isn't "wrong" per se, but I would do it a bit different.

For the "turn" variable, I just read it wrong and thought you were incrementing it, but you are not.

10. The way it is written, it starts another game even after I win 5 rounds and then ends. It isn't "wrong" per se, but I would do it a bit different.
Yes you're right. :| A friend helped me and now the game's up and running except for that error you have specified. After someone reaches 5 wins, it still asks the other player for a move, then ends the game.

May anyone help me with that?
Credits to Ken Russell for the revision of my Non diag functions as well as the fixing the part it went wrong when checking the winner.
Code:
```#include <stdio.h>
#include <stdlib.h>
int checkDiag(int board[3][3])
{
if(board[1][1] == board[0][0] && board[1][1] == board[2][2])
return 1;
else if(board[1][1] == board[0][2] && board[1][1] == board[2][0])
return 1;
return 0;
}
int checkNondiag(int board[3][3])
{
int k;
for (k=0; k<3; k++)
{
if (board[k][1]==board[k][0] && board[k][1]==board[k][2])
return 1;
}
for (k=0; k<3; k++)
{
if (board[1][k]==board[0][k] && board[1][k]==board[2][k])
return 1;
}
}
void gameboard(int board[3][3], int p1, int p2)
{
int i, j;
printf("TIC TAC TOE IN C\n\n");
printf("\nPlayer 1(X): %d\nPlayer 2(O): %d\n\n", p1, p2);
printf(" - - - \n|1|2|3|\n - - - \n|4|5|6|\n - - - \n|7|8|9|\n - - - \n\n");
printf(" - - - \n");
for(i=0;i<3;i++)
{
printf("|");
for(j=0;j<3;j++)
{
switch(board[i][j])
{
case 1: printf("X|");
break;
case 2: printf("O|");
break;
default: printf(" |");
}
}
printf("\n - - - \n");
}
}
int main(void)
{
int board[3][3] = {10, 20, 30, 40, 50, 60, 70, 80, 90};
int turn = 0, move = 0, win = 0, p1 = 0, p2 = 0;
int i, j;
do
{
do
{
system("cls");
gameboard(board, p1, p2);
move = 0;
if(checkDiag(board) == 1 || checkNondiag(board) == 1)
switch(turn)
{
case 0: p2++;
break;
case 1: p1++;
break;
}
if(checkDiag(board) == 1 || checkNondiag(board) == 1)
{	system("cls");
win = 1;
gameboard(board,p1,p2);
switch(turn)
{
case 0: printf("Player 2 won this round!\n", p1, p2);
system("Pause");
break;
case 1: printf("Player 1 won this round!\n", p1, p2);
system("Pause");
break;
}
system("cls");
for(i=0;i<3;i++)
for(j=0;j<3;j++)
board[i][j] = (i*10)+(j*20);
gameboard(board,p1,p2);
}
printf("Player %d's turn!\n", turn + 1);
printf("What space would you like to use? ");
while(move < 1 || move > 9)
{
scanf("%d", &move);
if( move < 1 || move > 9)
printf("Invalid coordinates. Please enter another: ");
}
switch(move)
{
case 1: board[0][0] = turn + 1;
break;
case 2: board[0][1] = turn + 1;
break;
case 3: board[0][2] = turn + 1;
break;
case 4: board[1][0] = turn + 1;
break;
case 5: board[1][1] = turn + 1;
break;
case 6: board[1][2] = turn + 1;
break;
case 7: board[2][0] = turn + 1;
break;
case 8: board[2][1] = turn + 1;
break;
case 9: board[2][2] = turn + 1;
break;
}
switch(turn)
{
case 0: turn = 1;
break;
case 1: turn = 0;
break;
}
}while(win == 0);
win = 0;
}while(p1 < 5 && p2 < 5);
if(p1==5)
printf("\nPlayer 1 has won the game!\nThank you for playing!\n");
else
printf("\nPlayer 2 has won the game!\nThank you for playing!\n");
}```