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.

If you intended to correct an error in the post then please contact us.

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 this post


Link to post
Share on other sites
Guest Anonymous Poster
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 this post


Link to post
Share on other sites
Guest Anonymous Poster
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 this post


Link to post
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 <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 Move


void 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 Move


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;
}

}
}

//Checks to see if Player has won

int 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 won

int 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 this post


Link to post
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 this post


Link to post
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 this post


Link to post
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 this post


Link to post
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 this post


Link to post
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 this post


Link to post
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 this post


Link to post
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 this post


Link to post
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

Share this post


Link to post
Share on other sites