Tic Tac Toe Disaster =(

Started by
13 comments, last by Elwren 22 years, 5 months ago
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
Advertisement
The link doesnt seem to work
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.
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.
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 <iostream.h>#include <stdlib.h>#include <time.h>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<ScreenHeight; i++)		cout << "\n";}void DrawPos(int val){	if (val==0)		cout << " ";	if (val==1)		cout << "X";	if (val==2)		cout << "O";}void DrawRow(int row[3]){	cout << "    ";	DrawPos(row[0]);	cout << "   ||   ";	DrawPos(row[1]);	cout << "    ||   ";	DrawPos(row[2]);	cout << endl;	cout << "\t\t\t";	cout << "     ";	cout << "   ||   ";	cout << " ";		cout << "    ||   ";	cout << endl;}void DrawGame(int board[3][3]){	cout << "\t\t\t";	DrawRow(board[0]);	cout << "\t\t\t";	cout << "--------||--------||--------" << endl;	cout << "\t\t\t";	DrawRow(board[1]);	cout << "\t\t\t";	cout << "--------||--------||--------" << endl;	cout << "\t\t\t";	DrawRow(board[2]);}//Player''s Movevoid pTurn(int& rowNum, int& colNum){	cout << "Pick a Row:  ";	cin >> 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;}  
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.
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.
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
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?
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

This topic is closed to new replies.

Advertisement