Tic Tac Toe app problem with AI

Started by
4 comments, last by Nitin TPs 16 years, 2 months ago
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
- dF repping The Pill studios
Advertisement
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!
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!
- dF repping The Pill studios
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...
- dF repping The Pill studios
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.
- dF repping The Pill studios

This topic is closed to new replies.

Advertisement