#### Archived

This topic is now archived and is closed to further replies.

# Tic Tac Toe Disaster =(

This topic is 5899 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

Hey, I''m new to programming and I''m trying to program my first console dos game, tic tac toe, and I''ve pretty much finished it except for one problem. Every time the computer wins, the program freezes for some reason. I have looked and looked and attempted to debug(not sure how to do this yet) and I''m still lost on the problem. Could someone check out my code and see if they can come to a conclusion. I have the .cpp on my page because it is like 350 lines long and I didn''t want to post that long a program on the forum, so hopefully one of you will download it and help me figure out the solution. Click here to download/load it in your browser. Thanks alot Note: I know my method for almost everything in the program is not in the least the most optimal way to perform the functions, but I''m not very good at programming anywho so look past the newbieness

##### Share on other sites
The link doesnt seem to work

##### Share on other sites
Are you using Visual C++? If so, use the debugger. Put a breakpoint at the very start of the main() loop by selecting the first line of code and hitting F9. Then debug into the program using F5. By pressing F10, you can step through the entire program and see where it dies.

##### Share on other sites
Are you using Visual C++? If so, use the debugger. Put a breakpoint at the very start of the main() loop by selecting the first line of code and hitting F9. Then debug into the program using F5. By pressing F10, you can step through the entire program and see where it dies.

##### Share on other sites
Hmmm, well apparently tripod has some gay ''remote loading'' policy. Guess I''ll just go ahead and post the code here since 350 lines isn''t really that much. Hope no one minds...

  #include #include #include int b[3][3] = { {0,0,0} , {0,0,0} , {0,0,0} };int ScreenHeight = 25;int ScreenWidth = 80;void ClearScreen(){ for(int i=0; i> rowNum; cout << "Pick a Column: "; cin >> colNum; if(rowNum>3) { cout << "Row Number too big!\n"; return; } if(colNum>3) { cout << "Column Number too big!\n"; return; } if(b[rowNum-1][colNum-1]==0) b[rowNum-1][colNum-1]=1; else cout << "Already Marked! Try Again!\n";}//Computer''s Movevoid cTurn(int& rRow, int& rCol){ bool fQuitt = false; while(!fQuitt) { srand( (unsigned)time( NULL ) ); int cRow = (rand()%2-0) + 0; int cCol = (rand()%2-0) + 0; if(b[cRow][cCol]==0) { b[cRow][cCol]=2; fQuitt = true; break; } }}//Checks to see if Player has wonint pWin(){ //Check for Row 1 Complete if(b[0][0]==1 && b[0][1]==1 && b[0][2]==1) { cout << "\n\nYOU WIN!!!\n"; return 1; } //Check for Row 2 Complete if(b[1][0]==1 && b[1][1]==1 && b[1][2]==1) { cout << "\n\nYOU WIN!!!\n"; return 1; } //Check for Row 3 Complete if(b[2][0]==1 && b[2][1]==1 && b[2][2]==1) { cout << "\n\nYOU WIN!!!\n"; return 1; } //Check for Column 1 Complete if(b[0][0]==1 && b[1][0]==1 && b[2][0]==1) { cout << "\n\nYOU WIN!!!\n"; return 1; } //Check for Column 2 Complete if(b[0][1]==1 && b[1][1]==1 && b[2][1]==1) { cout << "\n\nYOU WIN!!!\n"; return 1; } //Check for Column 3 Complete if(b[0][2]==1 && b[1][2]==1 && b[2][2]==1) { cout << "\n\nYOU WIN!!!\n"; return 1; } //Check for TL to BR Complete if(b[0][0]==1 && b[1][1]==1 && b[2][2]==1) { cout << "\n\nYOU WIN!!!\n"; return 1; } //Check for BL to TR Complete if(b[2][0]==1 && b[1][1]==1 && b[0][2]==1) { cout << "\n\nYOU WIN!!!\n"; return 1; } return 0;}//Checks to see if Computer has wonint cWin(){ //Check for Row 1 Complete if(b[0][0]==2 && b[0][1]==2 && b[0][2]==2) { cout << "\n\nYOU LOSE!!!\n"; return 1; } //Check for Row 2 Complete if(b[1][0]==2 && b[1][1]==2 && b[1][2]==2) { cout << "\n\nYOU LOSE!!!\n"; return 1; } //Check for Row 3 Complete if(b[2][0]==2 && b[2][1]==2 && b[2][2]==2) { cout << "\n\nYOU LOSE!!!\n"; return 1; } //Check for Column 1 Complete if(b[0][0]==2 && b[1][0]==2 && b[2][0]==2) { cout << "\n\nYOU LOSE!!!\n"; return 1; } //Check for Column 2 Complete if(b[0][1]==2 && b[1][1]==2 && b[2][1]==2) { cout << "\n\nYOU LOSE!!!\n"; return 1; } //Check for Column 3 Complete if(b[0][2]==2 && b[1][2]==2 && b[2][2]==2) { cout << "\n\nYOU LOSE!!!\n"; return 1; } //Check for TL to BR Complete if(b[0][0]==2 && b[1][1]==2 && b[2][2]==2) { cout << "\n\nYOU LOSE!!!\n"; return 1; } //Check for BL to TR Complete if(b[2][0]==2 && b[1][1]==2 && b[0][2]==2) { cout << "\n\nYOU LOSE!!!\n"; return 1; } return 0;}int main(){ int colNum = 0; int rowNum = 0; int &rRow = rowNum; int &rCol = colNum; bool fQuit = false; ClearScreen(); while(!fQuit) { //Player''s Turn pTurn(rRow,rCol); //Check to see if Player has won if(pWin()) { cout << endl; cout << endl; DrawGame(b); cout << endl; cout << endl; fQuit = true; break; } //Computer''s Turn cTurn(rRow,rCol); //Check to see if Computer has won if(cWin()) { cout << endl; cout << endl; DrawGame(b); cout << endl; cout << endl; fQuit = true; break; } ClearScreen(); cout << endl; cout << endl; DrawGame(b); cout << endl; cout << endl; } system("pause"); return 0;}

##### Share on other sites
I don''t know why it would be crashing but I know you can think of a better tic tac toe algorithm than srand :-)

Try to see if the computer can win in any position, then try to see if you can block in a position (just check if the player wins then go there), then see if you can grab the middle spot, then see if you can grab a corner. Worst case, take a random endge spot.

##### Share on other sites
Of course, there are ways to beat an AI like that

I wrote one of these a couple years back but it was a little more complex. Fully object oriented and a learning AI that I made up myself. After about 1 million times (couple seconds) of playing itself, it now never loses. I''d suggest using a method like this for a good AI if you ever do that.

About your problem, I don''t seem to see what is the matter. If it does not crash when the player wins, it shouldn''t when the computer does since the code is practically identical. I''m sorry but I''d suggest stepping through your code (as they described above)... that should help you find the exact line causing the error.

##### Share on other sites
One thing I would suggest though now that I've looked at it more closely is to eliminate all of your reference stuff. None of it is really needed unless the function needs to change the variable and have its value be changed outside of the function (after it returns). Even then, you don't need to create reference variables to pass to the function. The compiler will automatically convert from "int" to "int &" for example. Just do something like:

  void func (int &var){ var = 10;}...int variable = 5;cout << variable; // Prints "5"func (variable);cout << variable; // Prints "10"

Got that? Hope that helps.

Edited by - AndyTX on October 22, 2001 8:14:03 PM

##### Share on other sites
Ok apparently my algorithm for cTurn was causing it to freeze when the computer had won. After removing the srand and all that, I made the computer a little bit smarter in that he checks for open corners or the middle as his moves. However, I''m having trouble trying to get him to move in ''win spot'' or block a player who has a potential ''win spot''. I believe I could have it check for the individual 16 or so possible variations of a "2 filled row", but that seems like a slow/bad way at going at it. I can''t just say If(cWin()) then move to this spot because cWin checks for a complete row. Is there like a way to search the whole matrix for a certain value or a row of values. Anyways, I hope I''m making some sense. Anyone have any suggestions on a good way to make the computer move to win and block a potential win from the opposing player?

##### Share on other sites
I''ve written a flawless ai for this game. It''s not really that hard.

The ai needs to look for, in this order:

1) Can the computer win in one move?
2) Can the player win in one move?

(There are only 8 ways that someone can win, so you can pretty much just check each one explicitly.)

3) Fall back onto a list of what move to take for every possible remaining board position. There''s not as many as you might think. You can find every possibility with some paper, and a system.

And before you ask for my code, the only copy is a prolog file sitting on a 25 mhz 486 in a locked, empty house 200 km away. No chance

##### Share on other sites
This reminds me the movie "WAR GAMES" performed by Mathew Broderick...those were movies..

##### Share on other sites
Tic-Tac-Toe doesn''t require AI.

Is the computer O, just place in the center :p Immediatly stops the game, noone will win :p

##### Share on other sites
If you actually look into it, you''ll find that the best square to take on the first move is a corner. If the opponent takes any square other than the center, you can beat them. If they do take the center, then you take the opposite corner. At this point, most people think they''re screwed, and will take another corner, allowing you to beat them. But if they take a side, they can force a draw.

##### Share on other sites
Well in an finite game (aka only 9 freaking moves max) you don''t need any learning on part of the computer. SO writing an AI that "learns" in couple of secs is kinda bullshit to me.

Only in games with infinite possiblities (ala chess, movement in a free world) would you need a learning ai that could delevop paterns..

Once in a state science fair I wrote the game othello. (8x8 board) with finite moves and all I did was map out every possible move in a tree and then just selected moves based off that. And the stupid judge couldn''t understand the fact that the computer doesn''t learn anything in this type of game....anyways that''s my little story

Pactuul

##### Share on other sites
This may be your problem. I only looked at your program for a second.

  void cTurn(int& rRow, int& rCol){ bool fQuitt = false; while(!fQuitt) { srand( (unsigned)time( NULL ) ); int cRow = (rand()%2-0) + 0; int cCol = (rand()%2-0) + 0; if(b[cRow][cCol]==0) { b[cRow][cCol]=2; fQuitt = true; break; } }}

Every time CTurn is called, you set fQuitt to false.

I'm pretty sure fQuitt needs to be TRUE for it to win, right? (I wish I had more time to look at the source)

--Lowell N. Manners
lowell@makevideogames.com
MakeVideoGames.com

Edited by - Lowell Manners on October 24, 2001 12:49:57 PM