Noughts and Crosses (Tic Tac Toe) Logic
I'm sorry for asking what seems to be a pretty noobish question, but I'm really not too good at applying maths logically.
Basically, I'm wondering if there's a logcal way of usings maths to calculate AI and winning conditions for a game of noughts and crosses (tic tac toe as it seems to be more popularly known) instead of writing out 37+ if statements.
1|2|3
4|5|6
7|8|9
is what I've got so far. With an array of boolean values for X and O for whether each is checked.
so for example..
for(i=0;i<=9;i++)
if xArray[i] == false
if oArray[i] == false.. etc
and such
but I was contemplating changing this to one array of integers with 0 for none, 1 for X, 2 for O, or something..
But either way, would anyone be able to enlighten me to any logical ways of designing the AI?
ynori7 wrote: How is it programmed? Like if you put x at place 1, is array[1]=='x'? Seems more efficient than keeping two separate arrays. And you can do it in two if statements. If(array[0]=='x' AND array[1]=='x' AND array[2]=='x' OR …. OR … OR … etc) then x wins. And then have a similar if statement for 'o'. At the minute it uses two seperate arrays and then checks them individually when drawing the sprites, to know whether or not to draw them. But you're right.. I'll do what I said at the end of my post and put them all in one array.. but still, even if I used the if(blah or blah or or or) etc.. there'd be 37+ conditions, wouldn't there? or am I just being stupid here? :S
Here is the code I had used in a very old tic tac toe game I had created, only uses four if statements total. It could be further optimized by only preforming checks based off the last move, for example a corner move only needs 3 checks(horizontal, vertical, diagonal).
The code below was done using Qt framework, so you will need to tweak it depending on what you are using. Change it as you need, but remember even though you look at code and say that makes sense doesn't mean you understand it, write it yourself applying the following logic: loop vertical loop horizontal check D1 check D2
The below code should only be used as reference, but that is all up to you.
bool check_win(char player)
{
for(int i = 0; i<9; i+=3)
if(b[i]->text().toAscii() == player && b[i+1]->text().toAscii() == player && b[i+2]->text().toAscii() == player)
return true;
for(int i = 0; i<3; i++)
if(b[i]->text().toAscii() == player && b[i+3]->text().toAscii() == player && b[i+6]->text().toAscii() == player)
return true;
if(b[0]->text().toAscii() == player && b[4]->text().toAscii() == player && b[8]->text().toAscii() == player)
return true;
if(b[2]->text().toAscii() == player && b[4]->text().toAscii() == player && b[6]->text().toAscii() == player)
return true;
return false;
}
p4plus2 wrote: Very helpful stuff Thanks very much :] and I agree, about the writing it yourself stuff.
After looking into this further I found I could use..
8|1|6
3|5|7
4|9|2
in which, all possible victory conditions would sum as 15.
but I still can't see a way around having lots of if statements for the AI of where the computer plays it's move. :(
8456987 wrote: but I still can't see a way around having lots of if statements for the AI of where the computer plays it's move. :( That's how AI works. You're going to have a lot of if's. The best strategy for tic-tac-toe is to go for the center first, then one of the middle spaces on the edge, and if you opponent blocks you, go for one of the corners right beside that middle space you took. Guaranteed win.
1|2|3
4|5|6
7|8|9
So take 5. Your opponent takes 8. You take 6. Your opponent blocks you by taking 4. You take 9. Your opponent can block you by either taking 3 or 1, but he can't block both so you win.
I believe this only works if your opponent's first move is not a corner spot. So if you move second and your opponent took 5, always take a corner spot first.