Thread: Simple TicTacToe game - feedback please!

  1. #1
    Registered User
    Join Date
    Nov 2009
    Posts
    8

    Simple TicTacToe game - feedback please!

    Hi, wasn't sure if this post should go in the games section, but seemed more relevant here. Made this game - have only got to the arrays tutorial on this site btw. Have read around a bit and seems classes are useful for more advanced stuff (for this game)!

    There's two parts I'm sure can be improved to start with. First one is the winnercheck function - seems a bit too brute force method. I can't think of a better way to check for a winner though. Second bit is my move function. Quite a bit of repitition here - would like to make it more compact.

    Anyway here's my code, I hope it's understandable:

    Code:
    #include <iostream>
    
    using namespace std;
    
    //Prototype funcitons
    char printarray(char board[3][3]); //Function to print the board
    int winnercheck(char board[3][3], char letter, int *won); //Checks if someone has won the game
    int move(char board[3][3], char letter, int *won); //Collects coordinates, validates input and uses above functions
    
    
    int main()
    {
        char board[3][3]={'-','-','-','-','-','-','-','-','-'}; //Initial board
        char board_start[4][4]={'-','1','2','3','1','-','-','-','2','-','-','-','3','-','-','-'}; //Showing input method (coordinates)
        char X,O; //Player 'pieces'
        int i,j; //For printing board_start array
        int x,y; //For placing X's and O's
        int won=0; //This will be set to 0 if no one has won and 1 is there is a winner. Changed by the winnercheck function.
        int turn=1; //Turn is set to 1 as Player 1 goes 1st
    
        //Introduction
        cout<<"Welcome to Tic-Tac-Toe\n";
        for(i=0;i<4;i++) //Show game board coordinates
        {
            for(j=0;j<4;j++)
            {
                cout<<board_start[i][j]<<"\t";
            }
            cout<<"\n";
        }
        cout<<"Instructions: when asked, input the coordinates of where you want to go\n";
        cout<<"in the form of x y, where x is the row number(1-3) and y is the column\n";
        cout<<"number(1-3)\n";
        cout<<"e.g. to go in the middle square would be 2 2, or top right corner would be 1 3\n";
        cout<<"Player 1=X, Player 2=O" <<endl<<endl;
        //End of introduction
    
        //Game
        while(won==0)
        {
            switch (turn)
            {
                case 1:
                    cout<<"Player 1, enter where you want to go: ";
                    move(board,'X', &won);
                    if(won==1) cout<<"Player 1 wins\n";
                    turn=2;
                    break;
                case 2:
                    cout<<"Player 2, enter where you want to go: ";
                    move(board,'O', &won);
                    if(won==1) cout<<"Player 2 wins\n";
                    turn=1;
                    break;
            }
        }
    }
    
    char printarray(char board[3][3])
    {
        int i,j;
    
        cout<<"\n";
    
        for(i=0;i<3;i++)
        {
            for(j=0;j<3;j++)
            {
                cout<<board[i][j]<<"\t";
            }
            cout<<"\n";
        }
    }
    
    int move(char board[3][3], char letter, int *won)
    {
        int x,y,range,check;
    
        cin>> x>>y;
        x-=1; y-=1;
        range = x<0 || x>2 || y<0 || y>2;
        check = board[x][y] == 'X' || board[x][y] == 'O';
    
        while(range || check)
        {
            if (range) cout<<"Coordinates out of range. Try again: ";
            if (check) cout<<"Position already taken. Try again: ";
            cin>> x >>y;
            x-=1; y-=1;
            range = x<0 || x>2 || y<0 || y>2;
            check = board[x][y] == 'X' || board[x][y] == 'O';
        }
        board[x][y] = letter;
        printarray(board);
        winnercheck(board, letter, won);
    }
    
    int winnercheck(char board[3][3], char letter, int *won)
    {
        if(board[0][0] == letter && board[1][0] == letter && board[2][0] == letter) *won=1;
        if(board[0][1] == letter && board[1][1] == letter && board[2][1] == letter) *won=1;
        if(board[0][2] == letter && board[1][2] == letter && board[2][2] == letter) *won=1;
        if(board[0][0] == letter && board[0][1] == letter && board[0][2] == letter) *won=1;
        if(board[1][0] == letter && board[1][1] == letter && board[1][2] == letter) *won=1;
        if(board[2][0] == letter && board[2][1] == letter && board[2][2] == letter) *won=1;
        if(board[0][0] == letter && board[1][1] == letter && board[2][2] == letter) *won=1;
        if(board[0][2] == letter && board[1][1] == letter && board[2][0] == letter) *won=1;
    }
    Any feedback appreciated! Thanks

  2. #2
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    There are some glaring problems. Incorrect initialization. Did you compile this code? And it gave you no warnings?
    Unused variables. The X, O variables are unused.
    Pointers instead of references.
    Code duplication (why are you repeating the same thing twice?).
    Use of an int (turn) instead of an enum.
    All in all, not that bad for a beginner. Sure, some of could be better, but you can't get everything right in the very first time around, can you?
    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.

  3. #3
    Registered User
    Join Date
    Nov 2009
    Posts
    8
    Thanks for reply.
    Incorrect initialization. Did you compile this code? And it gave you no warnings?
    What do you mean by "incorrect initialization". Program works fine - complied in the CodeBlocks package if that's any help.

    Unused variables. The X, O variables are unused.
    For some reason, at the time I thought I would have to 'define' these.

    Pointers instead of references.
    References are later in the tutorials so I didn't know about them. I'll try and get them in!

    Code duplication (why are you repeating the same thing twice?).
    I'm assuming you're talking about the move function. I have the range and check bit before the while loop to check that the input is in the correct format. If it isn't it goes to the while loop. If they input the wrong thing again, it keeps on asking the person to put in the right input. Without the copied bit, the program will go ahead with the wrong inputs and mess up. The code is pretty inefficient I admit!

    Use of an int (turn) instead of an enum.
    What does the brackets around "turn" do? Where can I read up on it?

    Cheers for help!

  4. #4
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by scott452 View Post
    What do you mean by "incorrect initialization". Program works fine - complied in the CodeBlocks package if that's any help.
    Well, perhaps it works. Though I am thinking of:
    Code:
    char board[3][3]={ {'-','-','-'}, {'-','-','-'}, {'-','-','-'} };
    You're aren't initializing a 1D array here.

    I'm assuming you're talking about the move function. I have the range and check bit before the while loop to check that the input is in the correct format. If it isn't it goes to the while loop. If they input the wrong thing again, it keeps on asking the person to put in the right input. Without the copied bit, the program will go ahead with the wrong inputs and mess up. The code is pretty inefficient I admit!
    Of course, but essentially you are doing:

    Ask for input.
    If wrong:
    Ask for input
    Loop while wrong input

    Wouldn't it be better if you just put all of inside one loop? Loop as long as the answer is wrong instead of doing the check twice?

    What does the brackets around "turn" do? Where can I read up on it?
    Not sure what you mean. I was thinking of enums. Eg:

    Code:
    enum ETurn
    {
        PLAYER1,
        PLAYER2
    };
    
    switch (turn)
    {
        case PLAYER1:
    //etc
    Btw, here's a special treat for you:
    http://filebeam.com/ee0b5eb5727b1ba7bc2e6c98625a6e93
    I once made a similar project. I call it "X in a row".
    It was originally made in disgusting Java (now converted to C++), and I had to adhere to rules which said I cannot use too many advanced features, so the code isn't optimal, but at least it's something. Here you can have a look at how I've made it and maybe you can get some ideas.
    I call it "X in a row" because it doesn't have to be 3 in a row (in fact, it cannot). It's X in a row, where X is between 5 and 99. In fact, you can create any board size you want, from 5x5 to 99x99 and it doesn't have to be square. The program... "scales".

    It depends on boost, but all necessary files to compile the code should be included (thanks to my gather source files utility).
    Last edited by Elysia; 07-08-2010 at 10:18 AM.
    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
    Registered User
    Join Date
    Nov 2009
    Posts
    8
    Thanks for feedback It's been helpful! I'll try and understand your program - looks pretty crazy though!
    Scott

  6. #6
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Yeah, there are some bugs in it, too, and it could be better. But it's just a learning resource. Feel free to ask questions. You might learn something.
    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.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Creating a simple Windows game
    By ejohns85 in forum C Programming
    Replies: 1
    Last Post: 05-22-2009, 12:46 PM
  2. i have to write simple car racing game?
    By iskelet in forum Game Programming
    Replies: 1
    Last Post: 04-01-2009, 04:34 PM
  3. creating an AI engine for a simple game
    By cyb3r in forum Game Programming
    Replies: 1
    Last Post: 01-26-2009, 01:19 PM
  4. Simple Guessing Game
    By Elk in forum C Programming
    Replies: 13
    Last Post: 09-03-2006, 08:39 AM
  5. My Memory Game
    By jazy921 in forum C Programming
    Replies: 0
    Last Post: 05-05-2003, 05:13 PM