Question

Having problems getting my game to work... Any thoughts on what I might do? I have gone through most of the code and initialized it, but for some reason it is saying for most of the function that I don't have the proper points. Also that the drawBoard doesn't have the void type. Please help

Thanks

#include <iostream>

using namespace std;

// initialize a 2d board (3,3) with asterisk 
void drawBoard(char board[][]);
char check_Winner(char [][]);

int main(){
    char board[3][3]={{'*','*','*'},{'*','*','*'},{'*','*','*'}};
    bool win = false;
    bool in_row = false;
    bool in_col = false;
    int row;
    int column;




// run a loop:
    while (!win) {
    // Display the content of the board
        drawBoard(char board[][]));
        cout << "Player 1's turn:";
    // Ask player one to chose a location (row, column)
        cout << "What is the row:?\n";
        cin >> row;
        cout << "What is the column?\n";
        cin >> column;
    // check if move is valid

        //check if location has astericks and its between 0 thru 2
        bool valid = false;
        while (!valid) 
        {
            //check if the move is within range.
            if(!(row <= 3 && row >= 1 && column <= 3 && column >= 1)){
                cout << "Error: Either the row or column is not within range of the board.\n";
                // ask again (error: row in column not within range)
                cout << "What is the row:?\n";
                cin >> row;
                cout << "What is the column?\n";
                cin >> column;
            }
            else if(board[row-1][column-1] != '*')
            {
                cout << "Error: The (row,column) is already occupied.\n";
                cout << "What is the row:?\n";
                cin >> row;
                cout << "What is the column?\n";
                cin >> column;
            }else {
                valid = true;
            }


        }
        board[row-1][column-1] = 'X';
        drawBoard(char board[][]);
    // Check if someone won or  if there is a tie
        check_Winner(char board[][]);
    // Ask player two to chose a location (row, column)
    cout << "Player 2's turn:";

    cout << "What is the row:?\n";
                cin >> row;
                cout << "What is the column?\n";
                cin >> column;
                // check if move is valid

                //check if location has astericks and its between 0 thru 2
                bool valid = false;
                while (!valid) 
                {
                    //check if the move is within range.
                    if(!(row <= 3 && row >= 1 && column <= 3 && column >= 1)){
                        cout << "Error: Either the row or column is not within range of the board.\n";
                        // ask again (error: row in column not within range)
                        cout << "What is the row:?\n";
                        cin >> row;
                        cout << "What is the column?\n";
                        cin >> column;
                    }
                    else if(board[row-1][column-1] != '*')
                    {
                        cout << "Error: The (row,column) is already occupied.\n";
                        cout << "What is the row:?\n";
                        cin >> row;
                        cout << "What is the column?\n";
                        cin >> column;
                    }else 
                    {
                        valid = true;
                    }
                    board[row-1][column-1] = 'O';
                }
        drawBoard(char board[][])
    // Check if someone won or  if there is a tie
        check_Winner(char board[][]);

    }

    system("pause");

    return 0;
}
char check_Winner(char board[][]){
    char winner = 'T';

    // Checks for horizontal:
    for (int i = 0; i < 3; i++)
        if (board[i][0] == board[i][1] && board[i][1] == board[i][2])
            winner = board[i][0];

    // Checks for vertical:
    for (int i = 0; i < 3; i++)
        if (board[0][i] == board[1][i] && board[1][i] == board[2][i])
            winner = board[0][1];

    // Checks for diagnol:
    if ((board[0][0] == board[1][1] && board[1][1] == board[2][2]) || 
        (board[0][2] == board[1][1] && board[1][1] == board[2][0]))
        winner = board[1][1];

    // checking the result:
    switch (winner) {
        case 'T': cout << "IT'S A TIE";/* tie */ break;
        case 'X': cout << "PLAYER 1 WON!";/* X won */ break;
        case 'O': cout << "PLAYER 2 WON!";/* O won */ break;
        default : cout << "NEXT PLAYER'S TURN...>"; continue;
    }

}
void drawBoard(char board[][])
{

    cout << "     1   2   3" << endl;
    cout << "   +---+---+---+" << endl;

    cout << " 1" << " | " << board[0][0] << " | " << board[0][1] << " | " << board[0][2] << " | " << endl;
    cout << "   +---+---+---+" << endl;

    cout << " 2" << " | " << board[1][0] << " | " << board[1][1] << " | " << board[1][2] << " | " << endl;
    cout << "   +---+---+---+" << endl;

    cout << " 3" << " | " << board[2][0] << " | " << board[2][1] << " | " << board[2][2] << " | " << endl;
    cout << "   +---+---+---+" << endl;

}
Was it helpful?

Solution

I pasted your code into codepad.org and compiled it. The first error message is:

Line 6: error: declaration of 'board' as multidimensional array must have bounds for all dimensions except the first

In other words - if you don't tell the compiler something about the dimensions of your 2-D array, it won't know how to find an element. Why is that? Well, when you access a 2D array of m x n elements, a[i][j], you are really computing

*(a + n * i + j)

because for each time you increment the row i, you skip another n elements.

Another way to think of this - the "2D" elements are really one big block. If you had

0  1  2  3
4  5  6  7
8  9 10 11

They are really stored as

0 1 2 3 4 5 6 7 8 9 10 11

And you find element [1][1], say, by computing the offset (1D index, if you like) 1 * 4 + 1 = 5. And sure enough, element 5 in the linear array has the value 5, which is what you would have found by going one down and one across.

We fix this first compiler error by replacing

void drawBoard(char board[][]);
char check_Winner(char [][]);

with

void drawBoard(char board[][3]);
char check_Winner(char [][3]);

(as an aside, I'm not sure why check_Winner is defined as returning a char (you don't have a return Winner; statement in your function...) , and why you use the strange combination of underscores and caps in your function name. We'll get back to that later)

Next, the compiler complains about the way you call these functions. You need to call them (in line 23 and elsewhere) not as

drawBoard(char board[][]);

but simply as

drawBoard(board);

Since you already have defined that you are passing a char, and you don't need the [][] to remind the compiler of the type of board (you defined it earlier).

Next error (after these are fixed) that the compiler throws is

In function 'int main()':

Line 72: error: redeclaration of 'bool valid'

Indeed, you defined

bool valid = false;

in line 33. After that, when referring to the same variable, you MUST NOT put bool in front of the variable name - it looks like you are (re)declaring the variable. Just put

valid = true

in line 72. (Aside - you clearly did a copy-paste of a big block of code, which is how this error crept in. You want to think hard about finding a way to make "make a move" a single function that can be called for either player 1 or player 2 - then you don't need to repeat all this code, and things will look cleaner. And less prone to mistakes.).

With that fixed, the compiler complains about line 99:

In function 'int main()':

Line 99: error: expected ';' before 'check_Winner'

As is often the case with errors like this, the problem is in the line before. Line 97:

drawBoard(board)

is missing a semicolon at the end, and should be

drawBoard(board);

With that fixed, the compiler complains about line 130:

default : cout << "NEXT PLAYER'S TURN...>"; continue;

In function 'char check_Winner(char (*)[3])':

Line 130: error: continue statement not within a loop

The continue statement is used to say "go straight to the next iteration of the loop you are in" (while, for...). But you are using it inside a switch statement, and there is no loop (within the scope of the function you are in) that the code can jump to. If you just leave the continue; off, the code will continue just fine.

In fact (although this is not really what you are asking about), the break' will not cause the program to stop; it will just take you to the end of the function, and the code will keep going. This is why you really need a return value in your check_Winner function - and you need to check it after you have called it, so you can take appropriate action (print message, and quit the game).

Taking out the continue on line 130, we now hit a warning on line 133:

In function 'char check_Winner(char (*)[3])':

Line 133: warning: control reaches end of non-void function

This is saying "you declared this function to return a char, but you forgot to put in a return statement!". Add

return winner;

before the end of the function, and the complaint goes away.

The result of all these edits is the following code. I'm not saying it is "good" code, but at least the compiler errors have been removed. I hope that the process that I described will be helpful for you as you learn. Most compilers have flags to enable warnings and error messages; I strongly recommend that you always enable every warning you can, and pay attention to what the compiler is complaining about. You will learn to write better code..

disclaimer - I was writing this whilst "on the road" so I could only use codepad.org for basic debugging. It doesn't allow interactive programming so I could not test whether the final code 'works' - I can only tell you that it stopped complaining about the errors in the code... I am 99% sure that your check_Winner code has some logic errors in it - for one, you start out with

winner = 'T';

Which means you will call a tie unless one of the other conditions is met; I think you should only call a tie if you have no asterisks left (if you want to be really clever you can call a tie when there is no possible solution but that's a much harder problem to code).

Anyway - here is the code that compiles. There is more to do before you have a working game, I think...

#include <iostream>

using namespace std;

// initialize a 2d board (3,3) with asterisk 
void drawBoard(char board[][3]);
char check_Winner(char board[][3]);

int main(){
    char board[3][3]={{'*','*','*'},{'*','*','*'},{'*','*','*'}};
    bool win = false;
    bool in_row = false;
    bool in_col = false;
    int row;
    int column;




// run a loop:
    while (!win) {
    // Display the content of the board
        drawBoard(board);
        cout << "Player 1's turn:";
    // Ask player one to chose a location (row, column)
        cout << "What is the row:?\n";
        cin >> row;
        cout << "What is the column?\n";
        cin >> column;
    // check if move is valid

        //check if location has astericks and its between 0 thru 2
        bool valid = false;
        while (!valid) 
        {
            //check if the move is within range.
            if(!(row <= 3 && row >= 1 && column <= 3 && column >= 1)){
                cout << "Error: Either the row or column is not within range of the board.\n";
                // ask again (error: row in column not within range)
                cout << "What is the row:?\n";
                cin >> row;
                cout << "What is the column?\n";
                cin >> column;
            }
            else if(board[row-1][column-1] != '*')
            {
                cout << "Error: The (row,column) is already occupied.\n";
                cout << "What is the row:?\n";
                cin >> row;
                cout << "What is the column?\n";
                cin >> column;
            }else {
                valid = true;
            }


        }
        board[row-1][column-1] = 'X';
        drawBoard(board);
    // Check if someone won or  if there is a tie
        check_Winner(board);
    // Ask player two to chose a location (row, column)
    cout << "Player 2's turn:";

    cout << "What is the row:?\n";
                cin >> row;
                cout << "What is the column?\n";
                cin >> column;
                // check if move is valid

                //check if location has astericks and its between 0 thru 2
                valid = false;
                while (!valid) 
                {
                    //check if the move is within range.
                    if(!(row <= 3 && row >= 1 && column <= 3 && column >= 1)){
                        cout << "Error: Either the row or column is not within range of the board.\n";
                        // ask again (error: row in column not within range)
                        cout << "What is the row:?\n";
                        cin >> row;
                        cout << "What is the column?\n";
                        cin >> column;
                    }
                    else if(board[row-1][column-1] != '*')
                    {
                        cout << "Error: The (row,column) is already occupied.\n";
                        cout << "What is the row:?\n";
                        cin >> row;
                        cout << "What is the column?\n";
                        cin >> column;
                    }else 
                    {
                        valid = true;
                    }
                    board[row-1][column-1] = 'O';
                }
        drawBoard(board);
    // Check if someone won or  if there is a tie
        check_Winner(board);

    }

    system("pause");

    return 0;
}
char check_Winner(char board[][3]){
    char winner = 'T';

    // Checks for horizontal:
    for (int i = 0; i < 3; i++)
        if (board[i][0] == board[i][1] && board[i][1] == board[i][2])
            winner = board[i][0];

    // Checks for vertical:
    for (int i = 0; i < 3; i++)
        if (board[0][i] == board[1][i] && board[1][i] == board[2][i])
            winner = board[0][1];

    // Checks for diagnol:
    if ((board[0][0] == board[1][1] && board[1][1] == board[2][2]) || 
        (board[0][2] == board[1][1] && board[1][1] == board[2][0]))
        winner = board[1][1];

    // checking the result:
    switch (winner) {
        case 'T': cout << "IT'S A TIE";/* tie */ break;
        case 'X': cout << "PLAYER 1 WON!";/* X won */ break;
        case 'O': cout << "PLAYER 2 WON!";/* O won */ break;
        default : cout << "NEXT PLAYER'S TURN...>";
    }
    return winner;
}
void drawBoard(char board[][3])
{

    cout << "     1   2   3" << endl;
    cout << "   +---+---+---+" << endl;

    cout << " 1" << " | " << board[0][0] << " | " << board[0][1] << " | " << board[0][2] << " | " << endl;
    cout << "   +---+---+---+" << endl;

    cout << " 2" << " | " << board[1][0] << " | " << board[1][1] << " | " << board[1][2] << " | " << endl;
    cout << "   +---+---+---+" << endl;

    cout << " 3" << " | " << board[2][0] << " | " << board[2][1] << " | " << board[2][2] << " | " << endl;
    cout << "   +---+---+---+" << endl;

}

Postscript.

I am not a C++ expert by any stretch of the imagination. But people who are tend to insist not to use using namespace std;, and instead to write

std::cout << "hello world" << std::endl;

etc. As your code gets more complicated, being explicit about what function/constant belongs to what class gets more important. So I have been told... See Why is "using namespace std" considered bad practice? . Both the question and the answer got a LOT of upvotes... suggesting this is an important thing that people think about. Do read beyond the accepted answer... there are some gems further down that page.

OTHER TIPS

May I suggest you to try to use a typedef for your board?

typedef char tttboard[3][3];

your board declaration:

tttboard board={{'*','*','*'},{'*','*','*'},{'*','*','*'}};

your functions will look like: (by reference!)

 void drawBoard(tttboard& board);
 char check_Winner(tttboard& board);

And as you been told in the comment you call it without the char and [][] like this:

drawBoard(board);
check_Winner(board);
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top