Sign in to follow this  
Nitin TPs

Tic Tac Toe app problem with AI

Recommended Posts

Hello. I just started programming a Tic Tac Toe game on the GNU GCC C++ code::blocks IDE. There is a slight problem with the AI, however. The computer makes a move and repeats it all game long (i think). Can you have a look at the code and tell me about what i did wrong? Thanks in advance! Oh and you'll need two headers dpl.h and max.h which are in the rar. Apart from this you need the conio.h (old one). I've used funcs like gotoxy() and clrscr():) The headers are required IF you'll compile the project. code: http://rapidshare.com/files/93570852/Tic_Tac_Toe.rar.html

Share this post


Link to post
Share on other sites
Usually posts like this ("here's my source code, fix it please!") don't get very many responses. You'll probably have better luck if you can ask specific questions. For example, instead of uploading your entire source code, you could have just posted the "CalculateMove" function if your problem is the AI.
(Also, if you post source code, you can use [ source ] tags to format it)


First, some comments on your style:

You should never use absolute paths in include directives!
#include "D:\d\codes\dev_open_free\Tic Tac Toe\header\TicTacToeEngine.h"

It should be:
#include "header\TicTacToeEngine.h"


Also, TicTacToeEngine.h is full of function definitions. That is a bad thing.
You should only have the function prototypes in the header, e.g.:
void DrawBoard(const string cMovesDone);

And then put the function implementation in a cpp file:
void DrawBoard(const string cMovesDone)
{
...
}

If you try to include that header in more than one cpp file you will find out why it is a bad thing (you will get linker errors).



As to what is actually wrong with CalculateMove; the first problem I can see is that it is possible for all of your if's and else-if's to be false, in which case you're going to return an un-initialised value!

Share this post


Link to post
Share on other sites
Thanks. Sorry for the rather assuming post. erm... I dont exactly see what's wrong with CalculateMove... The logic seems, with no attempts at modesty, impeccable. How is it errant? Please help me out!

Share this post


Link to post
Share on other sites
Quote:
Original post by Nitin TPs
I dont exactly see what's wrong with CalculateMove... The logic seems, with no attempts at modesty, impeccable. How is it errant? Please help me out!

CalculateMove only seems to be checking for a line of two symbols, and if it finds one, it tells the AI to choose to move into the third position in that line.
CalculateMove doesn't contain any code at all to handle the situation when it can't find a line of two symbols (such as at the start of the game)!

int CalculateMove(const string cMovesDone)
{
k:
int nCompMove;

if(cMovesDone.at(0) == cMovesDone.at(4)) nCompMove = 8;
else if(cMovesDone.at(4) == cMovesDone.at(8)) nCompMove = 0;
else if(cMovesDone.at(0) == cMovesDone.at(8)) nCompMove = 4;

else if(cMovesDone.at(0) == cMovesDone.at(3)) nCompMove = 6;
else if(cMovesDone.at(0) == cMovesDone.at(6)) nCompMove = 3;
else if(cMovesDone.at(3) == cMovesDone.at(6)) nCompMove = 0;

else if(cMovesDone.at(0) == cMovesDone.at(1)) nCompMove = 2;
else if(cMovesDone.at(0) == cMovesDone.at(2)) nCompMove = 1;
else if(cMovesDone.at(2) == cMovesDone.at(1)) nCompMove = 0;

else if(cMovesDone.at(1) == cMovesDone.at(4)) nCompMove = 7;
else if(cMovesDone.at(4) == cMovesDone.at(7)) nCompMove = 1;
else if(cMovesDone.at(1) == cMovesDone.at(7)) nCompMove = 4;

else if(cMovesDone.at(2) == cMovesDone.at(5)) nCompMove = 8;
else if(cMovesDone.at(5) == cMovesDone.at(8)) nCompMove = 2;
else if(cMovesDone.at(2) == cMovesDone.at(8)) nCompMove = 5;

else if(cMovesDone.at(3) == cMovesDone.at(4)) nCompMove = 5;
else if(cMovesDone.at(3) == cMovesDone.at(5)) nCompMove = 4;
else if(cMovesDone.at(4) == cMovesDone.at(5)) nCompMove = 3;

else if(cMovesDone.at(6) == cMovesDone.at(7)) nCompMove = 8;
else if(cMovesDone.at(7) == cMovesDone.at(8)) nCompMove = 6;
else if(cMovesDone.at(6) == cMovesDone.at(8)) nCompMove = 7;

else if(cMovesDone.at(2) == cMovesDone.at(4)) nCompMove = 6;
else if(cMovesDone.at(4) == cMovesDone.at(6)) nCompMove = 2;
else if(cMovesDone.at(2) == cMovesDone.at(6)) nCompMove = 4;

return nCompMove;
}






^^^
What happens when none of the 'if' conditions are true?


When the game first starts none of your 'if' conditions are going to be true!
cMovesDone starts off as "123456789".

Which means you end up doing:

int CalculateMove(const string cMovesDone)
{
int nCompMove;//no initial/default value specified here

if('1' == '5') nCompMove = 8;//nope, not true
else if('5' == '9') nCompMove = 0;//not true either
else if('1' == '9') nCompMove = 4;//still not true
else if('1' == '4') nCompMove = 6;//this one aint true either
else if('1' == '7') nCompMove = 3;//still not true...
else if('4' == '7') nCompMove = 0;//false
else if('1' == '2') nCompMove = 2;//false
else if('1' == '3') nCompMove = 1;//false
else if('3' == '2') nCompMove = 0;//false
else if('2' == '5') nCompMove = 7;//false
else if('5' == '8') nCompMove = 1;//false
else if('2' == '8') nCompMove = 4;//false
//etc...
//None of the if's were true, which means nCompMove was never assigned a value!

return nCompMove;//returning uninitialized value is undefined behaviour! There's no telling what's going to happen after this point!
}





In pseudo-code your logic is currently doing this:

Search each possible line
if line contains two of the same symbol and one empty space, then
move into that empty space
else
continue searching
If search failed to find a move, then
move into <undefined>


I'd recommend changing it to:


//try to win
Search each possible line
if line contains two of the AI-player's symbols and one empty space, then
move into that empty space
else
continue searching
If search failed to find a move, then
//try to block the human player from winning
Search each possible line
if line contains two of the Human-player's symbols and one empty space, then
move into that empty space
else
continue searching
If search failed to find a move, then
//just move randomly
repeat
position = random number from 0 to 8
until position is an empty space
move into position


[Edited by - Hodgman on February 21, 2008 9:47:58 PM]

Share this post


Link to post
Share on other sites
Thank ye, hodgman! That seems ju-ust fine and dandy. I'll make it that way.
Until now, i was just testing the defense of the computer... There's a slight problem, however. I tried testing it's defense with the above code. Not working.
Looks like either my if(check-whole-line-for-same-opp-symbols) is not working or my wiring up of the entire program isn't. Dunno what, though. Hope it'll work after i attach the offense part...

Share this post


Link to post
Share on other sites
Hang on! is the defensive play all right? That

if(cMovesd...at(something) == cMovesd...at(something_else)) nCompMove = blah;

Is it alright? If it is, i'll have to burrow into the circuitry of the program.
Else i'll just about bin it and start from scratch.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this