vectors and arrays - connect 3 game

Pages: 123
Looking for help on this assignment..New to c++ and looking to see if what I have is "good" code or if should take a different route as well as how to do that

These are the instructions for my assignment
The game board should be a class. Use a two-dimensional array (or vector) to store the state of the game board as private data within the "Board" class. Use methods on the class: setters and getters, to make moves on the board inside the class. The constructor of class Board should create an empty game, ready to play.

Start out by displaying an empty game board, and ask for the move of player one. Redraw the board after every move. Alternate moves between player one and player two. Stop the game when no legal moves are available. Do not allow invalid moves: invalid column, or a move onto a full column. Allow the player to stop the game immediately. (I will use '0' to quit)

To determine if a game is won, check if there are enough tokens in a line. Check rows, columns, and diagonals.
There are 8 ways to win with 3 in a line: top row, middle row, bottom row; left column, middle column, right column, or top-left to bottom-right diagonal or top-right to bottom-left diagonal.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
1 .         1   .       1     .
2 .         2   .       2     .
3 .         3   .       3     .
0 1 2 3     0 1 2 3     0 1 2 3

1 .         1     .
2   .       2   .       
3     .     3 .
0 1 2 3     0 1 2 3

1 . . .     1           3
2           2 . . .     2
3           3           1 . . .
0 1 2 3     0 1 2 3     0 1 2 3


1
2
3
4
5

[i-1] [j-1]  	[i-1][j]	[i-1][j+1]
[i][j-1]	[i][j]		[i][j+1]
[i+1][j-1]	[i+1][j]	[i+1][j+1]


Play as many games as the user desires. Keep score of how many games each player won. If a player quits the game early, the game is forfeit, and that player loses that game. After the game, ask the user if he/she wants to continue. Provide percentage of win/loss/draws.

Provide a menu where the user can chose to play another player, as described above, OR play the computer. The computer can use a random number generator to generate legal moves.
potentially this:
enum menu { player = 'p', computer = 'c', quit = 'q' };


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
#include <iostream>
using namespace std;
// sets a name and 'ID' to each player
struct playerInfo
{
    char playerName[81];
    char playerID;
};


int main() {
    
    playerInfo playerOne, playerTwo;
// intro to game
    cout << "Let's Play Connect 3. Below is the initial game board.\n"
    <<"Select column number 1, 2, 3; along the top; to indicate your move.\n"
    << endl;
    
// initialized array
 char array2D[5][3]
 {
     {'1', '2', '3'},
     {'-', '-', '-'},
     {'*', '*', '*'},
     {'*', '*', '*' },
     {'*', '*', '*'}
 };
 for (int row{}; row<5; ++row)
 {
   for (int col{}; col<3; ++col)
   {
     cout<<array2D[row][col];
   }
   cout<<endl;
 }
// menu choice
    enum menu {otherPlayer = 'o', computer = 'c', quit = 'q'};
       char i;
    cout << "\nChoose who you would like to play with: o)ther player, c)omputer, q)uit: ";
       cin >> i;
    menu userChoice {};
    userChoice = static_cast<menu>(i);
       switch(userChoice)
       {
           case otherPlayer:
               cout << "\nyou picked to play with another player\n"
               << "Player One please enter your name: ";
                   cin  >> playerOne.playerName;
                   playerOne.playerID = 'X';
                   cout << "Player Two please enter your name: ";
                   cin  >> playerTwo.playerName;
                   playerTwo.playerID = 'O';
              cout <<"The two player tokens are X and O. Player 1 (X) begins.\n";
               
               break;

           case computer:
               cout << "You picked to play against the computer\n"; break;

           case quit:
               cout << "You have forfeited the match! Would you like to play again?"; break;

           default:
               cout << "\nThat is not an option! Try again...\n"; break;
       }
    return 0;
 }

    
/* output after every game ends:
Congratulations! Player 1(X) has won the game!!!

Do you want to play again? (y/n): n

Player 1 won: 1 times. 100.00%  Player 2 won: 0 times. 0.00%
This ends the Connect game. Goodbye.
*/
Last edited on
1. This looks like standard Tic-Tac-Toe game play, not Connect 3/4. With a Connect game there is very little possibility a player can snag the bottom row since the two players alternate dropping tokens down a chosen column. The 2nd player has to want to lose by dropping their token in the same column as the 1st player with each round of play.

3. Don't hardcode the look of the game board in your 2D array, it should only contain the played elements.

3. Don't hardcode the dimensions of your game board array with magic numbers (i.e. 3). Use constants.
1
2
3
const rows { 3 };
const cols { 3 };
char arr[rows][cols];

4. A 2D container can be simulated using a 1D container:
char arr[rows * cols];

5. Your title mentions vectors. Well, 2D vectors are possible, but declaring one is a bit tricky. Using the declared consts for rows and columns earlier:
1
2
// create a 2 dimensional vector with known dimensions
std::vector<std::vector<char>> vec(rows, std::vector<char>(cols));

One side effect with using a 2D vector is it can be run-time resized. A row can be inserted or deleted, individual elements can be inserted or deleted. With a game board that might be undesirable.

A simulated 2D vector in 1D looks easy, but still suffers from being volatile (elements added/deleted).

Using C++11's std::array is a possibility, declaring a 2D std::array is less verbiage than a 2D std::vector:
std::array<std::array<int, rows>, cols> arr;

With all that said the code so far is decent start. Not how I would do it, but still a solid beginning.
can anyone help me out with figuring this out?
how can I print an initialized array inside a switch statement?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
class Board
{
//access specifier
public:
    //Global constants for the game pieces
   // const char empty = '-'; // do i need this for the line that separates numbers and game board?
    const char empty = '*'; // empty/available places
    const char P1 = 'X'; // player 1
    const char P2 = 'O'; // player 2
    //global variables/constants for the game board
    const int col = 3;
    const int row = 5;
/*
const rows { 3 };
const cols { 3 };
char arr[rows][cols];
*/
    //Initialize the board to be empty
    void initializeBoard();
    //Display the board
    void displayBoard();
    //Get column for current move
    int getColumn(bool isPlayer1);
    //Add one piece to the Board
    bool addPiece(int c, bool isPlayer1);
    //Check if a given player has won
    bool isWinner(bool isPlayer1, int lastCol);
// how do I check for a tie in the game?



private:
    // the private is the 2d array and you can set elements on the 2darray
    // should only be able to set elements on 3 bottom rows
    char array2D[5][3]
    {
        {'1', '2', '3'},
        {'-', '-', '-'},
        {'*', '*', '*'},
        {'*', '*', '*' },
        {'*', '*', '*'}
    };
};
int main() {
    
    playerInfo playerOne, playerTwo;
    
    // intro to game
        cout << "Let's Play Connect 3. Below is the initial game board.\n"
        <<"Select column number 1, 2, 3; along the top; to indicate your move.\n"
        << endl;
    
     // this prints the array but what is a more efficient way i can print the empty board game
//here as well as an updated array every time a player makes a move?

    char array2D[5][3]
     {
         {'1', '2', '3'},
         {'-', '-', '-'},
         {'*', '*', '*'},
         {'*', '*', '*' },
         {'*', '*', '*'}
     };
     for (int row{}; row<5; ++row)
     {
       for (int col{}; col<3; ++col)
       {
         cout<<array2D[row][col];
       }
       cout<<endl;
     }
    
    // menu choice
        enum menu {otherPlayer = 'o', computer = 'c', quit = 'q'};
           char i;
        cout << "\nChoose who you would like to play with: o)ther player, c)omputer, q)uit: ";
           cin >> i;
        menu userChoice {};
        userChoice = static_cast<menu>(i);
           switch(userChoice)
           {
               case otherPlayer:
                   cout << "You picked to play with another player\n"
                        << "Player One please enter your name: ";
                       cin  >> playerOne.playerName;
                       playerOne.playerID = 'X';
                    cout << "Player Two please enter your name: ";
                       cin  >> playerTwo.playerName;
                       playerTwo.playerID = 'O';
                   cout <<"The two player tokens are X and O. Player 1 (X) begins.\n";
                   

//This is the part I am stuck on....
                   // here I will print the array/modified array based on plays

                   
/*after a game is finished print: 
Congratulations! Player 1(X) has won the game!!!

Do you want to play again? (y/n): n

Player 1 won: 1 times. 100.00%  Player 2 won: 0 times. 0.00%
This ends the Connect game. Goodbye. 
                   break;
*/
               case computer:
                   cout << "You picked to play against the computer\n";
                   break;

               case quit:
                   cout << "You have forfeited the match! Would you like to play again?\n";
                   break;

               default:
                   cout << "That is not an option! Try again...\n";
                   
                   break;
           }
        return 0;
     }

Last edited on
I have 2 days to complete this so I decided to get rid of the option to play against the computer.
I am still need to modify this to fit the instructions

The game board should be a class. Use a two-dimensional array (or vector) to store the state of the game board as private data within the "Board" class.


Here is my source code and I have added comments where I need help

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
//Create a Connect 3 Game
#include <iostream>
#include <string>

using namespace std;

//Global constants for the game pieces
const char EMP = '*';
const char P1 = 'X';
const char P2 = 'O';

//constants for the game board
const int COLS = 4;
const int ROWS = 3;
char board[COLS][ROWS]; //2D array of 7x6 connect 4 board

//Initialize the board to be empty
void initializeBoard();

//Displays the board
void displayBoard();

//Get column for current move
int getColumn(bool isPlayer1);

//Add one piece to the Board
bool addPiece(int c, bool isPlayer1);

//Check if a given player has won
bool isWinner(bool isPlayer1, int lastCol);

int main() {

  int totalMoves = 0; //number of moves by both players
  const int MAX_MOVES = COLS * ROWS; //total cells on the board
  bool playerOne = true; //boolean to keep track of current player
  bool gameWon = false; //boolean to keep track if game won
  int column = -1;

  initializeBoard();
  displayBoard();

  //loop until game is won or the board is full
    // how do i loop until user quits?
  while ((!gameWon) && (totalMoves < MAX_MOVES)) {
    bool validMove = false;

    while (!validMove) {
      column = getColumn(playerOne);
      validMove = addPiece(column, playerOne);
      if (!validMove) {
        cout << "Invalid move. Try again." << endl;
      }
    }

    totalMoves++;
    displayBoard();

    //Check if game is won
// it is not counting diagonal wins
    gameWon = isWinner(playerOne, column);
    if (gameWon) {
      cout << "Congratulations Player " << (playerOne ? "1" : "2")
           << ". has won the game!" << endl;
    } else if (totalMoves == MAX_MOVES) {
      cout << "Game over! No moves remaining." << endl;
    } else {
      playerOne = !playerOne; //switch player
    }
  }
  return 0;
}

void initializeBoard() {
  //Loops through each column
  for (int c = 0; c < COLS; c++) {
    //Loop through each row in a given column
    for (int r = 0; r < ROWS; r++){
      board[c][r] = EMP; //initialize all cells to empty
    }
  }
}

/* intro to the program:
 Welcome to connect 3. Below is the initial game board.
 Select column number 1, 2, 3; along the top; to indicate your move.
 The two player tokens are X and O. X begins.
 */


void displayBoard() {
  cout << endl << "Connect 4 Board:" << endl;
  //Display the board one row at a time
  for (int r = 0; r < ROWS; r++) {
    //For each row display all of the columns
    for (int c = 1; c < COLS; c++) {
      cout << board[c][r] << " ";
    }
    cout << endl;
  }
    
  //displays the column numbers below the board
  for (int c = 1; c < COLS; c++) {
      
    cout << c << " ";
  }
  cout << endl << endl;
}

int getColumn(bool isPlayer1) {
  int col = 0;


  cout << "Player " << (isPlayer1 ? "1" : "2")
       << " - Select a column (0," << (COLS-1) <<  ") to play: ";
  cin >> col;
  return col;
}

bool addPiece(int c, bool isPlayer1) {
  if ((c < 0) || (c >= COLS)) {
    return false;
  }

  if (board[c][0] == EMP) {
    
    for (int r = (ROWS-1); r >= 0; r--) {
      if (board[c][r] == EMP) {
        
        if (isPlayer1) {
          board[c][r] = P1;
        } else {
          board[c][r] = P2;
        }
        return true;
      }
    }
  }
  return false;
}

bool isWinner(bool isPlayer1, int lastCol) {
  int counter;

  char currTile;
  if (isPlayer1) {
    currTile = P1;
  } else {
    currTile = P2;
  }

  counter = 0;
  for (int r = ROWS-1; r >= 0; r--) {
    if (board[lastCol][r] == currTile) {
      counter++;
      if (counter == 3) {
        return true;
      }
    } else if (board[lastCol][r] == EMP) {
      break;
    }
    else {
      counter = 0;
    }
  }

  /*
   Need this printed after every game or is a user forefeits
   Congratulations! Player 1(X) has won the game!!!

   Do you want to play again? (y/n): n

   Player 1 won: 1 times. 100.00%  Player 2 won: 0 times. 0.00%
   This ends the Connect game. Goodbye.
   */

  //otherwise no winner
  return false;

}
Last edited on
The game board should be a class.

Creating the definition of that class would be a good first step.
I'm having a hard time figuring out how to set up my class. I know the private has to hold the array which is below.( not sure if that is correct) but from there I'm not sure how to print it based on player moves

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#include <iostream>
#include <string>

using namespace std;

// class
class Board
{
//access specifier
public:

private: int boardArray(){
    char array2D[4][3]
     {
         {'*', '*', '*'},
         {'*', '*', '*' },
         {'*', '*', '*'},
         {'1', '2', '3'}
     };
     for (int row{}; row<5; ++row)
     {
       for (int col{}; col<3; ++col)
       {
         cout<<array2D[row][col];
       }
       cout<<endl;
     }}
};
Last edited on
How would you display a 2D array as a 2D if it wasn't in a class? Just wrap the code for that in a class method member function.

Maybe call the method Display()?

You seem to be seriously struggling with classes and class design. A refresher on basic object-oriented programming can be perused at Learn C++, lesson 12: https://www.learncpp.com/cpp-tutorial/welcome-to-object-oriented-programming/

Why is your board 2D array including display elements? Your working board array should be 3 x 3, not 4 x 3. Separate the data from how the data is displayed.

Also, don't use hard-coded "magic" numbers. Use constants for the number of rows and columns. That makes it easier to change the layout if you want a bigger or smaller game board.

Something like this (very crude and hacked-up and NOT OOPed):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <iostream>

int main()
{
   constexpr size_t rows { 3 };
   constexpr size_t cols { 3 };

   char arr[3][3] { {'*', '*', '*'},
                    {'*', '*', '*' },
                    {'*', '*', '*'} };

   for (size_t i { }; i < rows; ++i)
   {
      std::cout << i + 1 << "| ";

      for (size_t j { }; j < cols; ++j)
      {
         std::cout << arr[i][j] << ' ';
      }
      std::cout << '\n';
   }
   std::cout << "  ------\n";
   std::cout << "x  1 2 3\n";
}

trying to understand and set up my class has really slowed me down I'm starting with the array which is below.
can anyone help me understand how to set elements based on user input. my notes have an example of how to set an element on an array but not based on user input
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
using namespace std;
class Board{
private:
    
public:
public:
static const int ROWS = 3;
static const int COLUMNS = 3;
static const int WINNING_ROWS = 3;
static const char X = 'X';
static const char O = 'O';
static const char EMPTY = '*';

};
int main() {
  
  // this is my 3x3 2Darray
  char board[3][3]
  {
    // initialized array
// off 0   1   2
    {'*', '*', '*'}, // row 1  offset 0
    {'*', '*', '*'}, // row 2  offset 1
    {'*', '*', '*'}  // row 3  offset 2
  };
  // row starts at 0; < 3 because 3 is outer dimension; ++ on row
  for (int row{}; row<3; ++row) // for each row
  {
      //row starts at 0; < 3 because 3 is outer dimension; ++ on row
    for (int col{}; col<3; ++col) // for each column
    {
        // print out contents
      cout<<' '<< board[row][col];
    }
    cout<<endl;
  }
    cout << " -----"<< endl;
    cout << " 1 2 3"<< endl;
    
    
    cout <<"\n===================\n"<< endl;

// setting elements on array
  board[2][2] = 'X'; // off my one

for (int row{}; row<3; ++row) // for each row
{
    //row starts at 0; < 3 because 3 is outer dimension; ++ on row
  for (int col{}; col<3; ++col) // for each column
  {
      // print out contents
    cout<<' '<< board[row][col];
  }
  cout<<endl;
}
  cout << " -----"<< endl;
  cout << " 1 2 3"<< endl;

  return 0;

  
}
Last edited on
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
#include <iostream>

class Board
{
private:
    static const int NO_ROWS{3};
    static const int NO_COLS{3};
    
    char symbol[3]{'-', 'O', 'X'};
    char game[NO_ROWS][NO_COLS];
    
public:
    Board()
    {
        for(int row = 0; row < NO_ROWS; row++)
        {
            for(int col = 0; col < NO_COLS; col++)
            {
                game[row][col] = symbol[0];
            }
        }
    };
    
    ~Board(){};
    
    void display()
    {
        for(int row = 0; row < NO_ROWS; row++)
        {
            for(int col = 0; col < NO_COLS; col++)
            {
                std::cout << game[row][col] << ' ';
            }
            std::cout << '\n';
        }
        std::cout << '\n';
    }
    
    void set(int player, int row, int col)
    {
        game[row][col] = symbol[player];
        display();
    }
};

int main() {
    
    Board bored;
    bored.display();
    
    bored.set(1, 2, 1);
    bored.set(2, 1, 2);
    
    return 0;
}


- - - 
- - - 
- - - 

- - - 
- - - 
- O - 

- - - 
- - X 
- O - 

Program ended with exit code: 0
I keep getting this error message "Use of undeclared identifier" for ROWS and COLS. What am I doing wrong? I have them declared inside the main..

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
#include <iostream>
#include <string>
#include <vector>
#include <random>
#include <string>
using namespace std;

class Board
{
private:
    static const int NO_ROWS{3};
    static const int NO_COLS{3};
    
    char symbol[3]{'*', 'O', 'X'};
    char board[NO_ROWS][NO_COLS]; //2D array of 3x3 connect 3 board
    
public:
    Board()
    {
        for(int row = 0; row < NO_ROWS; row++)
        {
            for(int col = 0; col < NO_COLS; col++)
            {
                board[row][col] = symbol[0];
            }
        }
    };
    
    ~Board(){};
    
    void display()
    {
        for(int row = 0; row < NO_ROWS; row++)
        {
            for(int col = 0; col < NO_COLS; col++)
            {
                std::cout << board[row][col] << ' ';
            }
            std::cout << '\n';
        }
        std::cout << '\n';
    }
    // display the board
    void set(int player, int row, int col)
    {
        board[row][col] = symbol[player];
        display();
    }
    

    
    // display game board: playingBoard.display();
    
};

int main() {

    // intro to game
    cout << "Let's Play Connect 3. Below is the initial game board.\n"
            <<"Select column number 1, 2, 3; along the top; to indicate your move.\n"
    << endl;
    // display #'s on game board
    cout<<"1 2 3\n";
    cout <<"-----\n";
    // displays board
    Board playingBoard;
    playingBoard.display();
    
  // doesnt dislpay board  void displayBoard(); you need playingBoard.display();

    //global variables/constants for the game board
    const int COLS = 3;
    const int ROW = 3;

    
    int totalMoves = 0; //number of moves by both players
    const int MAX_MOVES = COLS * ROWS; //total cells on the board
    bool playerOne = true; //boolean to keep track of current player
    bool gameWon = false; //boolean to keep track if game won
    int column = -1;
    
    //Get column for current move
    int getColumn(bool isPlayer1);

    //Add one piece to the Board
    bool addPiece(int c, bool isPlayer1);

    //Check if a given player has won
    bool isWinner(bool isPlayer1, int lastCol);
    
    
    //Game play loop
      //loop until game is won or the board is full
      while ((!gameWon) && (totalMoves < MAX_MOVES)) {
        bool validMove = false;

        while (!validMove) {
          column = getColumn(playerOne);
          validMove = addPiece(column, playerOne);
          if (!validMove) {
            cout << "Invalid move! Try again..." << endl;
          }
        }

        totalMoves++;
          playingBoard.display();

        //Check if game is won
        gameWon = isWinner(playerOne, column);
        if (gameWon) {
          cout << "CONGRATULATIONS Player " << (playerOne ? "1" : "2")
               << ". You've won Connect 3!!!!" << endl;
        } else if (totalMoves == MAX_MOVES) {
          cout << "Game over! No moves remaining." << endl;
        } else {
          playerOne = !playerOne; //switch player
        }
      }



      return 0;
    }

    void initializeBoard() {
      //Loops through each column
      for (int c = 0; c < COLS; c++) {
        //Loop through each row in a given column
        for (int r = 0; r < ROWS; r++){
          board[c][r] = EMP; //initialize all cells to empty
        }
      }
    }

    void displayBoard() {
      cout << endl << "Connect 4 Board:" << endl;
      //Display the board one row at a time
      for (int r = 0; r < ROWS; r++) {
        //For each row display all of the columns
        for (int c = 0; c < COLS; c++) {
          cout << board[c][r] << " ";
        }
        cout << endl; //After each row output a newline character
      }
      //Now display the column numbers below the board
      for (int c = 0; c < COLS; c++) {
        cout << c << " ";
      }
      cout << endl << endl;
    }

    int getColumn(bool isPlayer1) {
      int col = 0;

      /*cout << "Player ";
      if (isPlayer1) {
        cout << "1";
      } else {
        cout << "2";
      }
      cout << " - Select a column [0," << (COLS-1) <<  "] to play: ";*/
      //The below is a short form of above output
      cout << "Player " << (isPlayer1 ? "1" : "2")
           << " - Select a column [0," << (COLS-1) <<  "] to play: ";
      cin >> col;
      return col;
    }

    bool addPiece(int c, bool isPlayer1) {
      if ((c < 0) || (c >= COLS)) { //check if column is valid for board
        return false;
      }
      //check if column c has space
      if (board[c][0] == EMP) {
        //add a piece to the lowest unoccupied row in column c
        for (int r = (ROWS-1); r >= 0; r--) {
          if (board[c][r] == EMP) {
            //add piece
            if (isPlayer1) {
              board[c][r] = P1;
            } else {
              board[c][r] = P2;
            }
            return true;
          }
        }
      }
      //if column is full return false
      return false;
    }

    bool isWinner(bool isPlayer1, int lastCol) {
      int counter;

      //Identify which tile is used by current player
      char currTile;
      if (isPlayer1) {
        currTile = P1;
      } else {
        currTile = P2;
      }

      //Check if current player has 4 vertical tiles in a row in the current column
      counter = 0;
      for (int r = ROWS-1; r >= 0; r--) {
        if (board[lastCol][r] == currTile) {
          counter++;
          if (counter == 3) {
            return true;
          }
        } else if (board[lastCol][r] == EMP) { //an optimization to stop searching
          break;                               //if no more tiles in columns
        }
        else {
          counter = 0;
        }
      }

      /*TO DO: created this output after every game:
Congratulations! Player 1(X) has won the game!!!

Do you want to play again? (y/n): n

Player 1 won: 1 times. 100.00%  Player 2 won: 0 times. 0.00%
This ends the Connect game. Goodbye.*/
      return false;

    }
Last edited on
You declared 'ROW' not 'ROWS'.

Also, those variables are local to main. If you want to use them in other functions, pass them as parameters or make them global constants.
Last edited on
thanks that worked. that's what was confusing me so much about the class but a lot of the code is outside the main. I will post my updated code once I get it working
can someone let me know if I've set up the class and global constants correctly?
I also got my code to run but its still not taking user input, I just keep getting the error message I set.

I think the error is somewhere after L160

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
#include <iostream>
#include <string>
#include <vector>
#include <random>
#include <string>
using namespace std;

class Board
{
private:
    static const int NO_ROWS{3};
    static const int NO_COLS{3};
    
    char symbol[3]{'*', 'O', 'X'};
    char board[NO_ROWS][NO_COLS]; //2D array of 3x3 connect 3 board
    
public:
    Board()
    {
        for(int row = 0; row < NO_ROWS; row++)
        {
            for(int col = 0; col < NO_COLS; col++)
            {
                board[row][col] = symbol[0];
            }
        }
    };
    
    ~Board(){};
    
    void display()
    {
        for(int row = 0; row < NO_ROWS; row++)
        {
            for(int col = 0; col < NO_COLS; col++)
            {
                std::cout << board[row][col] << ' ';
            }
            std::cout << '\n';
        }
        std::cout << '\n';
    }
    // display the board
    void set(int player, int row, int col)
    {
        board[row][col] = symbol[player];
        display();
    }
};
//Global constants for the game pieces
const char EMP = '*';
const char P1 = 'X';
const char P2 = 'O';
//global variables/constants for the game board
const int COLS = 3;
const int ROWS = 3;
char board[COLS][ROWS]; //2D array of 3x3 connect 3 board
//Initialize the board to be empty
void initializeBoard();
//Display the board
void displayBoard();
//Get column for current move
int getColumn(bool isPlayer1);
//Adds piece to the Board
bool addPiece(int c, bool isPlayer1);
//Check if a given player has won
bool isWinner(bool isPlayer1, int lastCol);
int main() {
    
    //Initialize game
      int totalMoves = 0; //number of moves by both players
      const int MAX_MOVES = COLS * ROWS; //total cells on the board
      bool playerOne = true; //boolean to keep track of current player
      bool gameWon = false; //boolean to keep track if game won
      int column = -1;
    // intro to game
    cout << "Let's Play Connect 3. Below is the initial game board.\n"
            <<"Select column number 1, 2, 3; along the top; to indicate your move.\n"
    << endl;
    // display #'s on game board
    cout<<"1 2 3\n";
    cout <<"-----\n";
    // displays board
    Board playingBoard;
    playingBoard.display();
    

    
    //Game play loop
      //loop until game is won or the board is full
      while ((!gameWon) && (totalMoves < MAX_MOVES)) {
        bool validMove = false;

        while (!validMove) {
          column = getColumn(playerOne);
          validMove = addPiece(column, playerOne);
          if (!validMove) {
            cout << "Invalid move! Please try again..." << endl;
          }
        }

        totalMoves++;
          playingBoard.display();

        //Check if game is won
        gameWon = isWinner(playerOne, column);
        if (gameWon) {
          cout << "Congratulations Player " << (playerOne ? "1" : "2")
               << "! You won Connect 3!" << endl;
        } else if (totalMoves == MAX_MOVES) {
          cout << "Game over! No moves remaining." << endl;
        } else {
          playerOne = !playerOne; //switch player
        }
      }
      return 0;
    }

    void initializeBoard() {
      //Loops through each column
      for (int c = 0; c < COLS; c++) {
        //Loop through each row in a given column
        for (int r = 0; r < ROWS; r++){
          board[c][r] = EMP; //initialize all cells to empty
        }
      }
    }
    void displayBoard() {
        cout<<"1 2 3\n";
        cout <<"-----\n";
      //Display the board one row at a time
      for (int r = 0; r < ROWS; r++) {
        //For each row display all of the columns
        for (int c = 0; c < COLS; c++) {
          cout << board[c][r] << " ";
        }
        cout << endl; //After each row output a newline character
      }
      //Now display the column numbers below the board
      for (int c = 0; c < COLS; c++) {
        cout << c << " ";
      }
      cout << endl << endl;
    }

    int getColumn(bool isPlayer1) {
      int col = 0;

      /*cout << "Player ";
      if (isPlayer1) {
        cout << "1";
      } else {
        cout << "2";
      }
      cout << " - Select a column [0," << (COLS-1) <<  "] to play: ";*/
      //The below is a short form of above output

// should cols-1 remain like that or should I change it to just cols. I know this has to do with the offset
      cout << "Player " << (isPlayer1 ? "1" : "2")
           << " - Select a column [1 - " << (COLS-1) <<  "] to play: ";
      cin >> col;
      return col;
    }

    bool addPiece(int c, bool isPlayer1) {
      if ((c < 0) || (c >= COLS)) { //check if column is valid for board
        return false;
      }
      //check if column c has space
      if (board[c][0] == EMP) {
        //add a piece to the lowest unoccupied row in column c
        for (int r = (ROWS-1); r >= 0; r--) {
          if (board[c][r] == EMP) {
            //add piece
            if (isPlayer1) {
              board[c][r] = P1;
            } else {
              board[c][r] = P2;
            }
            return true;
          }
        }
      }
      //if column is full return false
      return false;
    }

    bool isWinner(bool isPlayer1, int lastCol) {
      int counter;

      //Identify which tile is used by current player
      char currTile;
      if (isPlayer1) {
        currTile = P1;
      } else {
        currTile = P2;
      }

      //Check if current player has 4 vertical tiles in a row in the current column
      counter = 0;
      for (int r = ROWS-1; r >= 0; r--) {
        if (board[lastCol][r] == currTile) {
          counter++;
          if (counter == 4) {
            return true;
          }
        } else if (board[lastCol][r] == EMP) { //an optimization to stop searching
          break;                               //if no more tiles in columns
        }
        else {
          counter = 0;
        }
      }

      /*TO DO: created this output after every game:
Congratulations! Player 1(X) has won the game!!!

Do you want to play again? (y/n): n

Player 1 won: 1 times. 100.00%  Player 2 won: 0 times. 0.00%
This ends the Connect game. Goodbye.*/
      return false;

    }
Last edited on
It's great to see you have adopted the idea of using a class. However you need to reconsider your code because it's getting far too complicated. It's always a good move, whether you use a class or not, functions are best if they only cover one or two operations only.

This is not complete obviously ...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
#include <iostream>

class Board
{
private:
    static const int NO_ROWS{3};
    static const int NO_COLS{3};
    
    char symbol[3]{'*', 'O', 'X'};
    char board[NO_ROWS][NO_COLS];
    
    int NO_MOVES{0};
    int MAX_NO_MOVES;
    
public:
    Board()
    {
        for(int row = 0; row < NO_ROWS; row++)
        {
            for(int col = 0; col < NO_COLS; col++)
            {
                board[row][col] = symbol[0];
            }
        }
    };
    
    ~Board(){};
    
    void display()
    {
        for(int row = 0; row < NO_ROWS; row++)
        {
            for(int col = 0; col < NO_COLS; col++)
            {
                std::cout << board[row][col] << ' ';
            }
            std::cout << '\n';
        }
        std::cout << "No. of moves: " << NO_MOVES << "\n\n";
    }
    
    bool move(int player, int row, int col)
    {
        if( isValidMove(row,col) )
        {
            board[row][col] = symbol[player];
            NO_MOVES++;
            display();
            
            return true;
        }
        else
        {
            std::cout
            << row << '-' << col << " is not a valid move ... try again\n\n";
            return false;
        }
    }
    
    bool isValidMove(int row, int col)
    {
        if( board[row][col] == symbol[0])
            return true;
        else
            return false;
    }
    
    int getMoveCount()
    {
        return NO_MOVES;
    }
    
};


int main()
{
    
    Board bored;
    bored.display();
    
    const int player_O{1};
    const int player_X{2};
    
    bored.move(player_O, 1, 2);
    
    bored.move(player_X, 1, 2);
    bored.move(player_X, 1, 1);
    
    bored.move(player_O, 0, 0);
    
    return 0;
}



* * * 
* * * 
* * * 
No. of moves: 0

* * * 
* * O 
* * * 
No. of moves: 1

1-2 is not a valid move ... try again

* * * 
* X O 
* * * 
No. of moves: 2

O * * 
* X O 
* * * 
No. of moves: 3

Program ended with exit code: 0
Last edited on
what would be the best thing to do to implement user input? I understand how to change elements on the array but for this program it has to be based on user input and it should work like a connect 4 board

I also don't think I need "No. of moves: " could I change that to "No. of games: " to then calculate the percentage of games won by each player
Last edited on
User input goes in main via a while loop. (You need to toggle between players.)

You can have a 4 board by hard coding the size in the class. Or if you use pointers or <vectors> you can generalize the size of the board - square or rectangular.

And by adjusting the parameters for a check winning move method the sequence length can be set.

The class also needs to incorporate maximum allowed moves.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
#include <iostream>
#include <vector>

class Board
{
private:
    int NO_ROWS{3};
    int NO_COLS{3};
    
    char symbol[3]{'*', 'O', 'X'};
    std::vector<std::vector<char>> board;
    
    int NO_MOVES{0};
    int MAX_NO_MOVES{0};
    
public:
    Board(int rows = 3, int cols = 5)
    {
        NO_ROWS = rows;
        NO_COLS = cols;
        initialize();
    };
    
    ~Board(){};
    
    void initialize()
    {
        board.resize(NO_ROWS, std::vector<char>(NO_COLS, symbol[0]));
        
        for(int row = 0; row < NO_ROWS; row++)
        {
            for(int col = 0; col < NO_COLS; col++)
            {
                board[row][col] = symbol[0];
            }
        }
    }
    
    void display()
    {
        for(int row = 0; row < NO_ROWS; row++)
        {
            std::cout << row << ' ' ;
            for(int col = 0; col < NO_COLS; col++)
            {
                std::cout << board[row][col] << ' ';
            }
            std::cout << '\n';
        }
        std::cout << "  ";
        for(int col = 0; col < NO_COLS; col++)
        {
            std::cout << col << ' ';
        }
        std::cout
        << '\n'
        << "No. of moves: " << NO_MOVES << "\n\n";
    }
    
    void set(int player, int row, int col)
    {
        board[row][col] = symbol[player];
    }
    
    bool move(int player, int row, int col)
    {
        if( isValidMove(row,col) )
        {
            set(player, row, col);
            NO_MOVES++;
            display();
           
            return true;
        }
        else
        {
            std::cout
            << row << '-' << col << " is not a valid move ... try again\n\n";
            return false;
        }
    }
    
    bool isValidMove(int row, int col)
    {
        if( board[row][col] == symbol[0])
            return true;
        else
            return false;
    }
    
    int getMoveCount()
    {
        return NO_MOVES;
    }
};


int main()
{
    Board bored(7,4);
    bored.display();
    
    const int player_O{1};
    const int player_X{2};
    
    bored.move(player_O, 1, 2);
    
    bored.move(player_X, 1, 2);
    bored.move(player_X, 1, 1);
    
    bored.move(player_O, 0, 0);
    
    return 0;
}

0 * * * * 
1 * * * * 
2 * * * * 
3 * * * * 
4 * * * * 
5 * * * * 
6 * * * * 
  0 1 2 3 
No. of moves: 0

0 * * * * 
1 * * O * 
2 * * * * 
3 * * * * 
4 * * * * 
5 * * * * 
6 * * * * 
  0 1 2 3 
No. of moves: 1

1-2 is not a valid move ... try again

0 * * * * 
1 * X O * 
2 * * * * 
3 * * * * 
4 * * * * 
5 * * * * 
6 * * * * 
  0 1 2 3 
No. of moves: 2

0 O * * * 
1 * X O * 
2 * * * * 
3 * * * * 
4 * * * * 
5 * * * * 
6 * * * * 
  0 1 2 3 
No. of moves: 3

Program ended with exit code: 0


Last edited on
I found this code online which checks for a player win. wondering if its useful for my code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
i-1] [j-1]  	[i-1][j]	[i-1][j+1]
[i][j-1]	[i][j]		[i][j+1]
[i+1][j-1]	[i+1][j]	[i+1][j+1]

// horizontalCheck
for (int j = 0; j<getHeight()-1 ; j++ ){
    for (int i = 0; i<getWidth(); i++){
        if (this.board[i][j] == player && this.board[i][j+1] == player && this.board[i][j+1] == player && this.board[i][j+1] == player){
            return true;
        }
    }
}
// verticalCheck
for (int i = 0; i<getWidth()-1 ; i++ ){
    for (int j = 0; j<this.getHeight(); j++){
        if (this.board[i][j] == player && this.board[i+1][j] == player && this.board[i+1][j] == player && this.board[i+1][j] == player){
            return true;
        }
    }
}
// ascendingDiagonalCheck
for (int i=1; i<getWidth(); i++){
    for (int j=0; j<getHeight()-3; j++){
        if (this.board[i][j] == player && this.board[i-1][j+1] == player && this.board[i-1][j+1] == player && this.board[i-1][j+1] == player)
            return true;
    }
}
// descendingDiagonalCheck
for (int i=1; i<getWidth(); i++){
    for (int j=3; j<getHeight(); j++){
        if (this.board[i][j] == player && this.board[i-1][j-1] == player && this.board[i-1][j-1] == player && this.board[i-1][j-1] == player)
            return true;
    }
}
return false;
}

Last edited on
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
 #include <iostream>
 class Board
 {
 private:
     static const int NO_ROWS{3};
     static const int NO_COLS{3};
     char symbol[3]{'*', 'O', 'X'};
     char board[NO_ROWS][NO_COLS];
     int NO_MOVES{0};
     int MAX_NO_MOVES;
     const int MAX_MOVES = NO_COLS * NO_ROWS; //total cells on the board
     
 public:
     Board()
     {
         for(int row = 0; row < NO_ROWS; row++)
         {
             for(int col = 0; col < NO_COLS; col++)
             {
                 board[row][col] = symbol[0];
             }
         }
     };
     
     ~Board(){};
 // displays board
     void display()
     {
         for(int row = 0; row < NO_ROWS; row++)
         {
             for(int col = 0; col < NO_COLS; col++)
             {
                 std::cout << board[row][col] << ' ';
             }
             std::cout << '\n';
         }
     }
 // checks if the move is valid
     bool move(int player, int row, int col)
     {
         if( isValidMove(row,col) )
         {
             board[row][col] = symbol[player];
             NO_MOVES++;
             display();
             
             return true;
         }
         else
         {
             std::cout
             << row << '-' << col << " is not a valid move ... try again\n\n";
             return false;
         }
     }
     bool isValidMove(int row, int col)
     {
         if( board[row][col] == symbol[0])
             return true;
         else
             return false;
     }
 // switches players after every move
     void SwapPlayer(int player)
             {
                 if (player == 1)
                 {
                     player = 2;
                 }

                 else if (player == 2)
                 {
                     player = 1;
                 }
             }
     
 // User's choice to drop piece
     int dropChoice(int b, char player){
         if(b >=0 && b<= 3)
         {
             if(board[0][b] == ' '){
                 int i;
                 for(i = 0;board[i][b] == ' ';i++)
                     if(i == 2
                        ){board[i][b] = player;
                 return i;}
                 i--;
                 board[i][b] =player;
                 return i;

             }
             else{
                 return -1;
             }

         }
         else{
             return -1;
         }

     }
     
 };
 using namespace std;
 int main()
 {
     int dropChoice, win, full, again;
     cout << "Let's Play Connect 3. Below is the initial game board.\n"
         <<"Select column number 1, 2, 3; along the top; to indicate your move.\n"
         <<"Enter 0 to quit.\n"
         << endl;
         // display #'s on game board
         cout<<"1 2 3\n";
         cout <<"-----\n";
         // displays board
         Board playingBoard;
         playingBoard.display();
         cout<<endl;
     
         cout << "The two player tokens are X and O. X begins."<< endl;
     // receive user input
     cout<<"1 2 3\n";
     cout <<"-----\n";
     // display board with user input
   //  dropChoice = ?
     
     win = CheckFour;
             if ( win == 1 )
             {
                 PlayerWin(playerOne);
                 again = restart(board);
                 if (again == 2)
                 {
                     break;
                 }
             }
     
return 0;
}

int CheckFour ( char board[][10])
{
    char XO;
    int win;
    // how do i set up the 'active player'
    XO = activePlayer;
    win = 0;

    for( int i = 3; i >= 1; --i )
    {
        
        for( int j = 3; j >= 1; --j )
        {
            // diagonal
            if( board[i][j] == XO     &&
                board[i-1][j-1] == XO &&
                board[i+1][j+1] == XO )
            {
                win = 1;
            }
            
// top horizontal
            if( board[i-1][j-1] == XO   &&
                board[i-1][j] == XO &&
                board[i-1][j+1] == XO)
            {
                win = 1;
            }
 // middle horizontal
            if( board[i][j] == XO   &&
                board[i][j-1] == XO &&
                board[i][j+1] == XO )
            {
                win = 1;
            }
// bottom horizontal
            if( board[i+1][j-1] == XO     &&
                board[i+1][j] == XO &&
                board[i+1][j+1] == XO)
            {
                win = 1;
            }
//left vertical
            if ( board[i-1][j-1] == XO   &&
                 board[i][j-1] == XO &&
                 board[i+1][j-1] == XO )
            {
                win = 1;
            }
//middle vertical
            if ( board[i-1][j] == XO   &&
                board[i][j] == XO &&
                board[i+1][j] == XO )
            {
                  win = 1;
            }
// right vertival
            if ( board[i-1][j+1] == XO   &&
                board[i][j+1] == XO &&
                board[i+1][j+1] == XO )
            {
                win = 1;
            }
        }
        
    }
    return win;
    }
Last edited on
Your CheckFour function is well suited to be incorporated in the Board class. The point of view is 'the Board checks itself each time for a winning streak and reports/sends a message back to the game controller in main after each move'.

Also, why are you cluttering up main() with board coordinate display junk when a Board 'knows' how to display itself fully?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
#include <iostream>
#include <vector>

class Board
{
private:
    int NO_ROWS{3};
    int NO_COLS{3};
    
    char symbol[3]{'*', 'O', 'X'};
    std::vector<std::vector<char>> board;
    
    int NO_MOVES{0};
    int MAX_NO_MOVES{10};
    
public:
    Board(int rows = 3, int cols = 5)
    {
        NO_ROWS = rows;
        NO_COLS = cols;
        initialize();
    };
    
    ~Board(){};
    
    void initialize()
    {
        board.resize(NO_ROWS, std::vector<char>(NO_COLS, symbol[0]));
        
        for(int row = 0; row < NO_ROWS; row++)
        {
            for(int col = 0; col < NO_COLS; col++)
            {
                board[row][col] = symbol[0];
            }
        }
    }
    
    bool isWin(int aPlayer, int r, int c)
    {
        char sym = getSymbol(aPlayer);
        
        // VERTICAL (UP)
        if( r >= 2 && board[r - 1][c] == sym && board[r - 2][c] == sym )
            return true;
        
        // HORIZONTAL (LEFT)
        if( c >= 2 && board[r][c - 1] == sym && board[r][c - 2] == sym )
            return true;
        
        // DIAGONAL (LEFT UP)
        if
            ( r >= 2 && c >= 2 && board[r - 1][c - 1] == sym &&
             board[r - 2][c - 2] == sym
             )
            return true;
        
        // DIAGONAL (LEFT DOWN)
        if
            ( r < NO_ROWS && c >= 2 &&  board[r + 1][c - 1] == sym &&
             board[r + 2][c - 2] == sym
             )
            return true;
        
        // TODO: OTHER's

        return false;
    }
    
    void display()
    {
        for(int row = 0; row < NO_ROWS; row++)
        {
            std::cout << row << ' ' ;
            for(int col = 0; col < NO_COLS; col++)
            {
                std::cout << board[row][col] << ' ';
            }
            std::cout << '\n';
        }
        std::cout << "  ";
        for(int col = 0; col < NO_COLS; col++)
        {
            std::cout << col << ' ';
        }
        std::cout
        << '\n'
        << "No. of moves: " << NO_MOVES << "\n\n";
    }
    
    void set(int player, int row, int col)
    {
        board[row][col] = symbol[player];
    }
    
    bool move(int player, int row, int col)
    {
        if( isValidMove(row,col) )
        {
            set(player, row, col);
            NO_MOVES++;
            return true;
        }
        else
        {
            return false;
        }
    }
    
    bool isValidMove(int row, int col)
    {
        if(row < 0 or row >= NO_ROWS)
            return false;
        
        if(col < 0 or col >= NO_COLS)
            return false;
        
        if( board[row][col] == symbol[0])
            return true;
        else
            return false;
    }
    
    int getMoveCount()
    {
        return NO_MOVES;
    }
    
    int getMoveCountLimit()
    {
        return MAX_NO_MOVES;
    }
    
    char getSymbol(int aPlayer)
    {
        return symbol[aPlayer];
    }
};


int main()
{
    Board bored(3,3);
    
    bool turn{true};
    
    const int player_O{1};
    const int player_X{2};
    
    int current_player{player_O}; // 'O' always starts play
    int row{-99}, col{-99};
    
    bored.display();
    std::cout << "->  O to move\n";
    while(
          // TODO: CHECK WIN
          bored.getMoveCount() < bored.getMoveCountLimit() &&
          std::cout << "Enter row col " &&
          std::cin >> row >> col
          )
    {
        if( bored.isValidMove(row, col))
        {
            bored.move(current_player, row, col);
            bored.display();
            
            if (bored.isWin(current_player, row, col) == true)
            {
                std::cout << "Player: " << current_player << " has won\n";
            }
            
            turn = !turn;
        }
        else
        {
            std::cout << "Invalid move - TRY AGAIN!\n";
        }
        
        if(turn)
        {
            current_player = player_O;
        }
        else
        {
            current_player = player_X;
        }
        
        std::cout
        << "->  Player " << bored.getSymbol(current_player) << " to move\n";
    }
    
    return 0;
}


0 * * * 
1 * * * 
2 * * * 
  0 1 2 
No. of moves: 0

->  O to move
Enter row col 0 0
0 O * * 
1 * * * 
2 * * * 
  0 1 2 
No. of moves: 1

->  Player X to move
Enter row col 1 2
0 O * * 
1 * * X 
2 * * * 
  0 1 2 
No. of moves: 2

->  Player O to move
Enter row col 1 1
0 O * * 
1 * O X 
2 * * * 
  0 1 2 
No. of moves: 3

->  Player X to move
Enter row col 2 1
0 O * * 
1 * O X 
2 * X * 
  0 1 2 
No. of moves: 4

->  Player O to move
Enter row col 2 2
0 O * * 
1 * O X 
2 * X O 
  0 1 2 
No. of moves: 5

Player: 1 has won
->  Player X to move
Enter row col 
Last edited on
what can I do so this works more like a connect 4 board, where the piece goes to the last available spot on a column from top to bottom?

Your example is working more like a tic tac toe board
Pages: 123