Thread: tic tac toe check winner

  1. #1
    Registered User
    Join Date
    Dec 2009
    Posts
    30

    Question tic tac toe check winner

    i'm creating a tic tac toe game (no functions unfortunately.....sorry!) and was trying to check for a winner at the end of each turn. Is there any way of doing this without using a hefty amount of "if" statements? I have already searched the forum but the only examples I could find included these statements in mass.

    I was thinking to using a nested "for" loop but the problem came that I would only be searching row wins and column wins...i'm stumped. If you would like to see my code, see below. Like I said, there is no check yet, but I added a comment line so you can see where it would start.

    Code:
    //Tic Tac Toe
    //Dustin Hardin 12-12-08
    
    //Play the classic game of tic tac toe
    
    #include <iostream>
    #include <string>
    #include <cstdlib>
    #include <ctime>
    
    using namespace std;
    
    int main()
    {
        const short NUM_ROWS = 3, NUM_COLUMNS = 3;
        const short unsigned MAX_PLAYERS = 2;
        short unsigned numPlayers, numComputer, rowSelect, columnSelect, xCheck = 0, oCheck = 0;
        bool playerMove, gameBoardFull = true;
        short unsigned int whoFirst, whoWin = 0, move, playerCheck, opponentCheck;
        srand(time(0));
        
        string players[MAX_PLAYERS];
        
        string board[NUM_ROWS][NUM_COLUMNS] = 
        {
            {"|#|","|#|","|#|"},
            {"|#|","|#|","|#|"},
            {"|#|","|#|","|#|"}
        };
        
        
        while (true)  //Game Loop
        {   
            
            
            //get number of players
            do{
            system("cls");
            cout << "\t\tWelcome to Tic-Tac-Toe!\n\n";
            
            cout << "How many players will be joining us today? (1-2): ";
            cin >> numPlayers;
            cin.ignore();
            
            }while (numPlayers != 1 && numPlayers != 2);
            
            numComputer = 2 - numPlayers;
            
            //inform player of who is playing
            if (numPlayers == 1)
            {
               cout << "\nGreat! So there will be " << numPlayers << " Human Vs. " << numComputer << " Computer!\n\n";
               players[0] = "Player";
               players[1] = "Computer";
            }
            else
            {
                cout << "Great! So it will be Human Vs. Human!\n\n";
                players[0] = "Player 1";
                players[1] = "Player 2";
            }
            
            cin.get();
            
            
            //RULES!
            system("cls");
            cout << "\t\tRULES: \n\n";
            cout << "1.  You must pick a position to start in. (1-9)\n"
                 << "the top row is 1-3, second 4-6, third 7-9" << endl;
            cout << "\n2.  Who goes 'first' is random....so no complaining!\n\n";
            cin.get();
            system("cls");
                
                
            //Display who is first    
            cout << "DECIDING WHO GOES FIRST...PLEASE WAIT.....";
            whoFirst = rand() % 2 + 1; //pick either one of the players to go first
            cin.get();
            
            if(whoFirst == 1)
            {
                playerMove = true;
                cout << "\n\n" << players[0] << " goes first";
                cin.get();
            }
            else
            {
                playerMove = false;
                cout << "\n\n" << players[1] << " goes first";
                cin.get();
            }
    
           system("cls"); 
            
            
            //now enter the game of tic-tac-toe
            do
            {   
                gameBoardFull = true;
                system("cls");
                
                //check to see if full board (draw)
                 for(int j = 0; j < 3; j++)
                 {
                         for(int k = 0; k < 3; k++)
                         {
                                 if (board[j][k] == "|#|")
                                 {
                                     gameBoardFull = false;
                                 }
                         }
                 }
                
                if(gameBoardFull == false)
                {
                    //display board                              
                    for(int i = 0; i < 3; i++)
                    {
                            for(int j = 0; j < 3; j++)
                            {
                                    cout << board[i][j];
                            }
                            cout << endl;
                    }
                    
                    
                    //check who's move it is and get input
                    do
                    {
                        if( playerMove == true)
                        {
                            cout << players[0] << ": ";
                            cin >> move;
                            cin.ignore();
                        }
                        else if(playerMove == false && numPlayers == 2)
                        {
                             cout << players[1] << ": ";
                             cin >> move;
                             cin.ignore();
                         }
                         else if(playerMove == false && numPlayers == 1)
                         {
                             move = rand() % 9 + 1;
                         }
                         
                     } while(move < 1 && move > 9);
                     
                     //adjust move to the corresponding row and columns
                     if (move > 0 && move < 4)
                     {
                          rowSelect = 0;
                          columnSelect = move - 1;
                     }
                     else if (move > 3 && move < 7)
                     {
                          rowSelect = 1;
                          columnSelect = move - 4;
                     }
                     else if (move > 6 && move < 10)
                     {
                          rowSelect = 2;
                          columnSelect = move - 7;
                     }
         
                     if(board[rowSelect][columnSelect] == "|#|")
                     {
                     //place the marker on board
                         if (playerMove == true)
                         {
                            board[rowSelect][columnSelect] = "|X|";
                            playerMove = false;
                         }
                         else if (playerMove == false && numPlayers == 2)
                         {
                            board[rowSelect][columnSelect] = "|O|";
                            playerMove = true;
                            cin.get();
                         }
                         else
                         {
                             board[rowSelect][columnSelect] = "|O|";
                             playerMove = true;
                             cout << players[1] << ": " << move;   
                             cin.get();                       
                         }
                      }
                  }
                  
                  //check for winner
                  for(int i = 0; i < 3; i++)
                  {
                                for(int j = 0; j < 3; j++)
                                {
                                }
                  }
    
            }while(gameBoardFull == false);//add whoWin == 0 so that it will check for winner before end loop
            
            system("cls");
            
            if(gameBoardFull == true)
                cout << "\t\tGame Ended in Draw!";
            cin.get();
            break;
            
        }
        cin.get();
        
    }
    Once again, I'm very sorry about the lack of functions, I am trying to go step by step in my book and every chapter I try to make a game out of what I've learned so far (and very limited, yes).


    Thanks again!

  2. #2
    Registered User
    Join Date
    Dec 2009
    Posts
    30
    well, I did more searching...and it looks like everyone I looked at (which I gave up quickly) used a series of if statements. Not that I do not like using them, its just that I was hoping for a different way of checking for a winner. I will still be looking for answers, but in the mean time, I will code the if statements in and finish the game.

    thanks again!

  3. #3
    Algorithm Dissector iMalc's Avatar
    Join Date
    Dec 2005
    Location
    New Zealand
    Posts
    6,318
    It would be simpler if you just used a one-dimensional array.

    Lookup tables are your friend.
    My homepage
    Advice: Take only as directed - If symptoms persist, please see your debugger

    Linus Torvalds: "But it clearly is the only right way. The fact that everybody else does it some other way only means that they are wrong"

  4. #4
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    1D arrays are a hassle when working with two dimensions IMHO.
    Anyway, you don't need a lot of if statements.
    You just search each row separately, then all columns, then the two diagonals. If your board is 3x3, and requires an entire row to be filled, it becomes very easy.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  5. #5
    Algorithm Dissector iMalc's Avatar
    Join Date
    Dec 2005
    Location
    New Zealand
    Posts
    6,318
    dhardin is already asking for the users move as a number between 1 and 9, and is similarly generating a random number from 1-9 for the computer move. It's no more work to use a 1D array than it is to convert the above into x & y coordinates, but it then makes other things easier.
    Note that the code below this comment suggests that dhardin is not familar with using divide and mod to convert back to x & y coordinates anyway, so you may be somewhat right here:
    Code:
    //adjust move to the corresponding row and columns
    My homepage
    Advice: Take only as directed - If symptoms persist, please see your debugger

    Linus Torvalds: "But it clearly is the only right way. The fact that everybody else does it some other way only means that they are wrong"

  6. #6
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    I would treat it as a coordinate system instead and ask for x and y.
    It's easier for the brain to visualize, as well, when inputting which square to use.
    But then again, there is no easy function for splitting strings in std::string or the standard library, is there?
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  7. #7
    Grey Wizard C_Sparky's Avatar
    Join Date
    Sep 2009
    Posts
    50
    It's quite easy to do with a 1D array, just use 0 for the first button, 1 for the second and so on.

    Here is how I did it:

    Code:
    /* Check X Victory */
    /*
    X is defined as 1
    O is defined as 2
    */
            //Check Rows
            if(bStatus[0] == X && bStatus[1] == X && bStatus[2] == X)
            {
                    ShowWinner("x");
            }
    
            if(bStatus[3] == X && bStatus[4] == X && bStatus[5] == X)
            {
                    ShowWinner("x");
            }
    
            if(bStatus[6] == X && bStatus[7] == X && bStatus[8] == X)
            {
                    ShowWinner("x");
            }
    
            //Check Collums
            if(bStatus[0] == X && bStatus[3] == X && bStatus[6] == X)
            {
                    ShowWinner("x");
            }
    
            if(bStatus[1] == X && bStatus[4] == X && bStatus[7] == X)
            {
                    ShowWinner("x");
            }
    
            if(bStatus[2] == X && bStatus[5] == X && bStatus[8] == X)
            {
                    ShowWinner("x");
            }
    
            //Check Diagonals
            if(bStatus[0] == X && bStatus[4] == X && bStatus[8] == X)
            {
                    ShowWinner("x");
            }
    
            if(bStatus[2] == X && bStatus[4] == X && bStatus[6] == X)
            {
                    ShowWinner("x");
            }
    
    
            //-------------------------------------------------------
    
    
            /* Check O Victory */
            //Check Rows
            if(bStatus[0] == O && bStatus[1] == O && bStatus[2] == O)
            {
                    ShowWinner("o");
            }
    
            if(bStatus[3] == O && bStatus[4] == O && bStatus[5] == O)
            {
                    ShowWinner("o");
            }
    
            if(bStatus[6] == O && bStatus[7] == O && bStatus[8] == O)
            {
                    ShowWinner("o");
            }
    
            //Check Collums
            if(bStatus[0] == O && bStatus[3] == O && bStatus[6] == O)
            {
                    ShowWinner("o");
            }
    
            if(bStatus[1] == O && bStatus[4] == O && bStatus[7] == O)
            {
                    ShowWinner("o");
            }
    
            if(bStatus[2] == O && bStatus[5] == O && bStatus[8] == O)
            {
                    ShowWinner("o");
            }
    
            //Check Diagonals
            if(bStatus[0] == O && bStatus[4] == O && bStatus[8] == O)
            {
                    ShowWinner("o");
            }
    
            if(bStatus[2] == O && bStatus[4] == O && bStatus[6] == O)
            {
                    ShowWinner("o");
            }
    
    
            else if(counter >= 9 && over == false)
            {
                    ShowWinner("draw");
            }
    Last edited by C_Sparky; 12-18-2009 at 03:25 PM.

  8. #8
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    And it's quite easy with a 2D array, but the questions was if it was possible to do without a lot if statements.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  9. #9
    Malum in se abachler's Avatar
    Join Date
    Apr 2007
    Posts
    3,195
    You can roll it into a single if statement that checks all 6 cases.

    Or you can use a bit mask in a for loop.
    or you can enumerate all winning boards into an array that contains the winner.

    or ...
    Code:
    char Board[9]; // X = 1, O = 2, blank = 0
    
    int winner = 
    Board[0] * (Board[0] == Board[1] && Board[0] == Board[2]) +
    Board[0] * (Board[0] == Board[3] && Board[0] == Board[6]) +
    Board[0] * (Board[0] == Board[4] && Board[0] == Board[8]) +
    Board[1] * (Board[1] == Board[4] && Board[1] == Board[7]) +
    Board[2] * (Board[2] == Board[5] && Board[2] == Board[8]) +
    Board[2] * (Board[2] == Board[4] && Board[2] == Board[6]) +
    Board[3] * (Board[3] == Board[4] && Board[3] == Board[5]) +
    Board[6] * (Board[6] == Board[7] && Board[6] == Board[8]);
    enjoy

  10. #10
    Registered User QuestionKing's Avatar
    Join Date
    Jan 2009
    Posts
    68
    I started out testing for a winner by 3 key points in the grid. First the center square. If this mark does not match the current player's token (x or o), you immediately cut 4 possible wins. Then you can test any two diagonally opposite corners. If those 3 fail there was no win. If one passes you can test further. But since most moves do not result in a win, I chose to eliminate as many as I could per step rather than cycling every possible win every move. Just another thought. gl
    Asking a question you already know the answer to might teach you something you did not know...

  11. #11
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  12. #12
    Registered User QuestionKing's Avatar
    Join Date
    Jan 2009
    Posts
    68
    Quote Originally Posted by Elysia View Post
    Actually, main can be declared in any of the three following ways:

    int main()
    int main(int argc, char *argv[])
    lol @ wiki
    Asking a question you already know the answer to might teach you something you did not know...

  13. #13
    Malum in se abachler's Avatar
    Join Date
    Apr 2007
    Posts
    3,195
    Quote Originally Posted by Elysia View Post
    void main() is not improper, stop saying that it is. It may be improper for PC based applications, but PC's are hardly the only, or even the biggest, place C/C++ are used.

  14. #14
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Did I say it was improper? I did not.
    I linked to an article, and if you be bothered to read it, it actually covers your point, too.

    Quote Originally Posted by QuestionKing View Post
    lol @ wiki
    Did you check the wiki? I can see no such thing
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  15. #15
    Registered User
    Join Date
    Dec 2009
    Posts
    30
    okay, thanks a lot for all who replied! I will be taking a look at my code and try to add in your advice (stuff that I understand more of course). Will post my code when i'm done.

    thanks again!

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Bizarre Tic Tac Toe!
    By Lynux-Penguin in forum C Programming
    Replies: 5
    Last Post: 05-14-2002, 05:10 PM
  2. Check my Tic Tac Toe game for bugs please
    By aresashura in forum Game Programming
    Replies: 5
    Last Post: 12-19-2001, 08:47 AM
  3. Replies: 22
    Last Post: 11-08-2001, 11:01 PM
  4. My tic tac toe game, please check this out.
    By Leeman_s in forum C++ Programming
    Replies: 1
    Last Post: 11-05-2001, 11:14 PM
  5. Tic tac toe (how do i check for winnner?)
    By Leeman_s in forum C++ Programming
    Replies: 3
    Last Post: 10-20-2001, 03:38 PM