Tic Tac Toe app problem with AI
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
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!
(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!
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!
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 searchingIf search failed to find a move, then move into <undefined>
I'd recommend changing it to:
//try to winSearch 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 searchingIf 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]
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...
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...
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement