Allegro.cc - Online Community

Allegro.cc Forums » Game Design & Concepts » tic tac toe game

This thread is locked; no one can reply to it. rss feed Print
 1   2 
tic tac toe game
senthil kumar
Member #8,490
April 2007

hi,

Im developing tic tac toe game in which i had tried most algorithms. Still i like to have a complex algo to make the player defeated. Anyone could give me any idea about it

Also I try to zoom out the squares of tictactoe when it loads but i failed to do so.

LennyLen
Member #5,313
December 2004
avatar

Quote:

Also I try to zoom out the squares of tictactoe when it loads but i failed to do so.

Can you explain better? Posting some code would also help.

raja peter
Member #7,835
October 2006

i think you want to stretch the image loaded.

use stretch_sprite()
8-)

luv,

raja

senthil kumar
Member #8,490
April 2007

raja, I thought you are on leave and will be in church today (rajesh) ....:-/

raja peter
Member #7,835
October 2006

::)

luv,

raja

Tobias Dammers
Member #2,604
August 2002
avatar

Tic tac toe isn't hard, and there is an optimal strategy. Due to the limited number of possible moves, it shouldn't be hard to find, and it should be even easier to program it.
Hint: If you move first, the take the center square, after that one of the corners. If your opponent moves first, take the center square if you can, otherwise you're screwed anyway.

---
Me make music: Triofobie
---
"We need Tobias and his awesome trombone, too." - Johan Halmén

gnolam
Member #2,030
March 2002
avatar

Just make sure the computer can play itself. That could save the world some day.

--
Move to the Democratic People's Republic of Vivendi Universal (formerly known as Sweden) - officially democracy- and privacy-free since 2008-06-18!

kentl
Member #2,905
November 2002

There are only 9! number of ways to play Tic Tac Toe (362880). So you could create a recursive algorithm which plays perfect.

ImLeftFooted
Member #3,935
October 2003
avatar

Let me see if I can do this from memory...

If you go first, do:

  1. Go center

  2. If they take a non-corner

  3. Take a corner next to their move

  4. You have 100% odds of winning

  5. Goto "General"

  6. If they take a corner

  7. Take opposite corner

  8. You have 66% odds of winning

  9. Goto "General"

If you go second, use these rules for deciding moves:

  • If center is open

  • Go center

  • If they are about to win
    • Block them

  • If their 2nd move gave them opposing corners
    • Move to a random non-corner.

  • If there is an open corner
    • Take a corner touching one of their pieces. (you may touch diagonally)

  • Else
    • Goto "General"

    [/list]

    "General"

    • If they are about to win

    • Block them

  • If there is a move that 'forks' you (gives you two open chains of 2)
    • Move there

  • If there is an open corner
    • Move in that corner

  • Else
    • Move randomly.

    [/list]

    Quote:

    There are only 9! number of ways to play Tic Tac Toe

    If you make a logical algorithm (instead of recursive), the steps are quite a few less. Pretend for example you are player 2 and player 1 just made his first move to the center square. It appears you have 8 moves, but in reality you only have 2.

    piccolo
    Member #3,163
    January 2003
    avatar

    the algorithm your looking for is called the MIn Max algorithm.
    i made this game for a class project

    1 
    2 
    3#include < iostream.h>
    4bool min2(int num,int turn);
    5bool max2(int num,int turn);
    6 
    7 
    8 
    9int maxPath [25];
    10int minPath [25];
    11 
    12void draw(int n)
    13{
    14 cout << endl;
    15 
    16while (n>0)
    17{
    18 
    19cout <<"@ ";
    20n--;
    21}
    22cout << " <-- ";
    23 
    24 
    25 
    26}
    27bool min2(int num,int turn)
    28{
    29 if(num== 1)
    30 {
    31//cout << num <<" min picks last 1 and loses "<<endl<<endl;
    32 return false;
    33 }
    34 
    35
    36 if(max2(num-1,turn+1)==false)
    37 {
    38minPath[turn]=1;
    39//cout << num <<" min picks 1 "<<endl;
    40 
    41 
    42 return true;
    43 }
    44 
    45 if(max2(num-2,turn+1)==false)
    46 {
    47minPath[turn]=2;
    48//cout << num <<" min picks 2 "<<endl;
    49 
    50 return true;
    51 }
    52 
    53 if(max2(num-3,turn)==false)
    54 {
    55minPath[turn]=3;
    56//cout << num <<" min picks 3 "<<endl;
    57 
    58 return true;
    59 }
    60 //cout << num <<" nnnnnnnnnnnnnnnnnnnn2 "<<endl;
    61 
    62minPath[turn]=1;
    63//cout << num <<" min picks 1 "<<endl;
    64return false;
    65}
    66 
    67 
    68 
    69 
    70 
    71bool max2(int num, int turn)
    72{
    73 if(num==1)
    74 {
    75//cout << num <<" max picks last 1 and loses "<<endl<<endl;
    76 return false;
    77 }
    78 
    79
    80
    81 if(min2(num-1,turn+1)==false)
    82 {
    83maxPath[turn]=1;
    84//cout << num <<" max picks 1 "<<endl;
    85 return true;
    86 }
    87 
    88 if(min2(num-2,turn+1)==false)
    89 {
    90maxPath[turn]=2;
    91//cout << num <<" max picks 2 "<<endl;
    92 return true;
    93 }
    94 
    95 if(min2(num-3,turn+1)==false)
    96 {
    97maxPath[turn]=3;
    98//cout << num <<" max picks 3 "<<endl;
    99 return true;
    100 }
    101 //cout << num <<" nnnnnnnnnnnnnnnnnnnn "<<endl;
    102 
    103maxPath[turn]=1;
    104//cout << num <<" max picks 1 "<<endl;
    105 
    106return false;
    107}
    108 
    109 
    110 
    111int main()
    112{
    113int items=0;
    114int player=0;
    115char ans;
    116bool gameon= true;
    117while (gameon==true)
    118{
    119
    120 cout << " enter the number of items in the game" <<endl;
    121 cin >> items;
    122 cout << " Ok lets play " <<endl;
    123draw(items);
    124 
    125 while (1)
    126 {
    127 cout << "Items ="<<items <<" pick num 1-3 " <<endl;
    128 cin >>player;
    129while(player != 1&&player!=2&&player!=3)
    130{
    131 cout << "Items ="<<items <<" pick num 1-3 " <<endl;
    132draw(items);
    133 cin >>player;
    134}
    135 if(items-player>0)
    136 {
    137 items-=player;
    138player=0;
    139 max2(items,0);
    140if(items==1)
    141 {
    142draw(items);
    143 cout << " you win because the computer must pick this one" << endl;
    144break;
    145 }
    146 cout << "Items now ="<<items <<" the computer picks "<< maxPath[0] <<endl;
    147 items-=maxPath[0];
    148draw(items);
    149 if(items==1)
    150 {
    151 
    152 cout << " you lose because you must pick this one" << endl;
    153break;
    154 }
    155 }
    156 else
    157 {
    158 
    159 cout << " you lose because you must pick this one" << endl;
    160 
    161break;
    162 }
    163 
    164 
    165 
    166 
    167 
    168 }
    169cout << " do you want to try again y or n " <<endl;
    170cin >>ans;
    171if(ans=='n')
    172{
    173cout << " game over " <<endl;
    174gameon=false;
    175}
    176else
    177{
    178cout << " restarting game " <<endl;
    179}
    180 
    181}
    182/*
    183if(max2(11,0) == true)
    184{
    185cout << " max wins "<<endl;
    186}
    187else
    188{
    189 cout << " min wins "<<endl;
    190}
    191
    192for(int i = 0;i<25;i++)
    193{
    194 if(i%2!=1)
    195 {
    196cout <<" max picked "<<maxPath<i> <<""<<endl;
    197 }
    198 else
    199 {
    200cout <<" min picked "<<minPath<i> <<""<<endl;
    201 }
    202}
    203*/
    204 
    205return 0;
    206}

    wow
    -------------------------------
    i am who you are not am i

    kentl
    Member #2,905
    November 2002

    Dustin Dettmer said:

    If you make a logical algorithm (instead of recursive), the steps are quite a few less. Pretend for example you are player 2 and player 1 just made his first move to the center square. It appears you have 8 moves, but in reality you only have 2.

    Sure there are lots of ways to solve the problem. But as the worst case is to search through 9! combinations we're dealing with a trivial problem.

    I think we can all agree that if you go first taking the center is the way to go. This because that position interfer (for the enemy) or enables (for you) a solution from each of the 8 remaining positions.

    That way we have reduced the problem to a 8! search which is only 40320 combinations to look through at the second move. Piece of cake for a modern computer! After that we're dealing with a 7! search, which is 5040 game states. And so on.

    I would say that this is a typical case where brute force search is a nice solution.

    Picollos suggestion to use Min-Max is what I would suggest as well. There is a nice tutorial here: http://ai-depot.com/articles/minimax-explained/

    piccolo
    Member #3,163
    January 2003
    avatar

    in tic tac toe and the game i post above the min max algorithm is the best. its a no brainier that for a game like chest the min max algorith will have to be moded so it dose not take all day. but:-X he is not coding chess is he;)

    edit: i should have read all of it :-X

    wow
    -------------------------------
    i am who you are not am i

    kentl
    Member #2,905
    November 2002

    Quote:

    edit: i should have read all of it :-X

    Yes I do agree with you. ;D

    Still Dustins algorithm and other "hand crafted" algorithms are nice and fun to think about.

    [Edit] The more I think about it the more I like a hand crafted algorithm specifically for Tic Tac Toe. I still feel that a search is a clean and nice solution to the problem and that it's easier to not mess up and introduce a human error. But if we can do it without a search that's pretty appealing too.

    Matthew Leverton
    Supreme Loser
    January 1999
    avatar

    Quote:

    That way we have reduced the problem to a 8! search which is only 40320 combinations to look through at the second move. Piece of cake for a modern computer! After that we're dealing with a 7! search, which is 5040 game states. And so on.

    First, there's not even 9! solutions because most winning solutions don't even go 9 moves. Plus, if you consider that many of the games are just mirror images of each other, that number drops drastically.

    There's only three possible opening moves (corner, side, middle), not nine. The rest of the board can be played relative to the first middle+corner piece. But figuring all that out is more difficult than just going through 9!.

    Quote:

    I think we can all agree that if you go first taking the center is the way to go. This because that position interfer (for the enemy) or enables (for you) a solution from each of the 8 remaining positions.

    Starting on the corner isn't bad either. For instance:

    X - -     X - -     X - -     X - -     X - X     X - X     X X X
    - - -     - 0 -     - 0 -     - 0 -     - 0 -     - 0 0     - 0 0
    - - -     - - -     - - X     0 - X     0 - X     0 - X     0 - X
    

    I find that above game is the easiest way to beat stupid people.

    After the first couple of moves, the rest of the moves are obvious. So I agree with Dustin; writing a brute force is actually more difficult than an impossible-to-beat AI.

    kentl
    Member #2,905
    November 2002

    Quote:

    First, there's not even 9! solutions because most winning solutions don't even go 9 moves. Plus, if you consider that many of the games are just mirror images of each other, that number drops drastically.

    Yeah sure. It gives a rough estimation though and it's enough to conclude that the problem isn't very hard and that search algorithm could be used, like Min-Max (without Alfa-Beta pruning as it's not necessary).

    Quote:

    So I agree with Dustin; writing a brute force is actually more difficult than an impossible-to-beat AI.

    I'm leaning more towards this as well now that I've thought more about it (as I wrote above). But if you've got the Min-Max algorithm implemented in a generic and robust way already, then that's what I'd use.

    Quote:

    Starting on the corner isn't bad either. For instance:

    X - - X - - X - - X - - X - X X - X X X X
    - - - - 0 - - 0 - - 0 - - 0 - - 0 0 - 0 0
    - - - - - - - - X 0 - X 0 - X 0 - X 0 - X

    I find that above game is the easiest way to beat stupid people.

    I can see that's a sneaky way to fool people who aren't used to the game, I don't necessarily think they're stupid though.

    It would be interesting to see all paths to a certain victory. That is, if there are more paths than one. If there's only one it feels logical that it should start in the center position. If there are multiple they're center and one of the corners.

    piccolo
    Member #3,163
    January 2003
    avatar

    when programing the AI for tic tac toe you want to maximize the lanes for ubtaing a win wining. That is why you alway play in the middle first. in

    1|2|3
    -----
    4|5|6
    -----
    7|8|9
    

    when you play at 5 you can win at: 1,5,9 : 3,5,7 : 4,5,6 : 2,3,8. its greater then all other first moves.

    edit:
    2nd play should never win only tie.

    wow
    -------------------------------
    i am who you are not am i

    Matthew Leverton
    Supreme Loser
    January 1999
    avatar

    Quote:

    when programing the AI for tic tac toe you want to maximize the lanes for ubtaing a win wining. That is why you alway play in the middle first.

    In theory, yes. But not all victories are equal. You want to pick the route that produces the most wins. That might not be equivalent to picking the first move that produces the most number of winning possibilities. Starting in a corner might fool people more often. (I don't know.) If it does, then starting in the corner could possibly be better, despite it leading to fewer winning paths.

    Regardless of which approach has a higher probability of winning, letting the AI use multiple starting locations will feel more natural and will probably end up stumping the player more often (if he can be stumped at all).

    Paul whoknows
    Member #5,081
    September 2004
    avatar

    Hahaha! I have easily won most online tic tac toe games using Matthew's strategy, only a few tied games tough.

    ____

    "The unlimited potential has been replaced by the concrete reality of what I programmed today." - Jordan Mechner.

    piccolo
    Member #3,163
    January 2003
    avatar

    My teacher says then when programing Game AI you must all way assume the player play well and make the best moves all the time. you will lose playing the first move in the corner when playing an AI. But if you want to give the 2nd player a chance you can random the first move then apply the AI algorithm to the rest of the game.

    wow
    -------------------------------
    i am who you are not am i

    Matthew Leverton
    Supreme Loser
    January 1999
    avatar

    Show me how starting in the corner guarantees a loss.

    And your teacher is incorrect. Humans aren't computers. They can be tricked. Sometimes a gamble pays off. The best AI is not one that always picks the "best" (in your sense of the word) route.

    For example, let's say Move A gives you 4 paths of winning and 2 paths of losing; Move B gives you 5 paths of winning and 1 path of losing. Move B is better, right? No, you cannot answer that. More information is needed.

    Maybe one of those paths in Move A is very clever and tricks most players. The probability of winning by Move A goes up. And that is what you should care about. The total number of winning paths is irrelevant if they are all so obvious, a blind man would see them.

    piccolo
    Member #3,163
    January 2003
    avatar

    well ill say that if the you play in the corner you can not win playing someone who is good you can say the same for the middle as well. if both players play well the game will always end up in a tie.
    edit fixed

    wow
    -------------------------------
    i am who you are not am i

    LennyLen
    Member #5,313
    December 2004
    avatar

    Quote:

    well ill say that if the you play in the corner you can not win play some who is good you can say the same for the middle as well.

    Is that supposed to be "If you play in the corner you can't win. Play some one who's good, and you can say the same for the middle as well" or "If you play in the corner, you can't win playing someone who is good. You can say the same for the middle as well."

    The first seems to be what you mean, as it's closer to what you wrote, but it's also wrong.

    Now please try to use grammar in the future to avoid such ambiguities. It's what it's for.

    anonymous
    Member #8025
    November 2006

    Sorry to break the fun, but doesn't 3*3 tic-tac-toe always end in draw if both players make the best moves?
    The best the computer can do is avoid losing moves and choose the winning move if you make a mistake, and that's it.

    LennyLen
    Member #5,313
    December 2004
    avatar

    Quote:

    Sorry to break the fun, but doesn't 3*3 tic-tac-toe always end in draw if both players make the best moves?

    Yes.

    However, not everyone will always make the best moves, especially if they are used to the first player always starting at a particular position. So, stirring things up a little can throw people off, and cause them to make mistakes.

    Arthur Kalliokoski
    Second in Command
    February 2005
    avatar

    Couldn't you represent the chosen squares as bits in a 32 bit int? Each side would use 16 bits, high & low halves.

       |   |
       |X  |
    -----------
       |   |
       |O  |X
    -----------
      O|   |
       |   |
    
              (unused X bits)     (valid X bits)  (unused O bits) (valid O bits)
    would be  0000 0000 00         010 001 000    0000 0000 00     000 010 100
    

    so that the top 3 squares would be the most significant "valid" bits, next row etc.

    Then you could store these in a two int struct that would have the sought pattern (sorted for binary search) with an optimal bit pattern for the next move (one more bit set than the sought int). You could have several optimal moves if possible for variety, set the most significant unused bits for "not possible" flags, e.g. if X started in a corner there'd be only 3 possible (1 optimal) move.

    They all watch too much MSNBC... they get ideas.

     1   2 


    Go to: