Reputation: 59
I am working on a tic tac toe program and I need to create a 2D array of variable size in a class. This is how I have it written now:
class ticTacToe
{
public:
ticTacToe();
void display();
bool moveIsValid();
private:
int rows;
int cols;
int board[rows][col];
}
I have the board being read in from a file in the constructor but I am not sure how to make it of variable size so that I can read in a board of any size and then access it outside of the class.
Upvotes: 4
Views: 4848
Reputation: 11
I suggest you to use pointer to pointer.
#include <iostream>
#include <cstdlib>
using namespace std;
class ticTacToe{
private:
int rows;
int cols;
int **board; // POINTER TO POINTER
public:
ticTacToe(int a,int b){
rows=a;
cols=b;
board=new int*[rows];
for (int k = 0; k < rows; ++k) {
board[k]=new int[cols];
}
/*LET'S INITIALIZE CELL VALUES TO= 0*/
for (int i = 0; i < rows; ++i) {
for (int j = 0; j < cols; ++j) {
board[i][j]=0;
}
}
}
void display();
bool moveIsValid();
};
Upvotes: 0
Reputation: 1
"I have the board being read in from a file in the constructor but I am not sure how to make it of variable size so that I can read in a board of any size"
In c++ you use a std::vector
instead a raw array like follows
class ticTacToe {
public:
ticTacToe();
void display();
bool moveIsValid();
private:
int rows;
int cols;
std::vector<std::vector<int>> board; // <<<<
};
The dynamic allocation can be applied as follows in a constructor:
ticTacToe(int rows_, int cols_) : rows(rows_), cols(cols_) {
board.resize(rows,std::vector<int>(cols));
}
and then access it outside of the class
Well, I'm not sure that this is really a good idea, but you can simply add an accessor function for that member variable
std::vector<std::vector<int>>& accBoard() { return board; }
The better design approach would be IMHO, to provide something like a separate function to read from a std::istream
:
void ticTacToe::readFromStream(std::istream& is) {
// supposed the first two numbers in the file contain rows and cols
is >> rows >> cols;
board.resize(rows,std::vector<int>(cols));
for(int r = 0; r < rows; ++r) {
for(int c = 0; c < cols; ++c) {
cin >> board[r][c];
}
}
}
For real code you would check for input errors of course like
if(!(is >> rows >> cols)) {
// handle errors from input
}
Upvotes: 5
Reputation: 6642
In case this is homework and you cannot use the standard library:
// Declaration
int rows;
int columns;
int **board;
// Construction
board = new int*[rows];
for (int i = 0; i < rows; i++) {
board[i] = new int[columns];
}
// Destruction
for (int i = 0; i < rows; i++) {
delete[] board[i];
}
delete[] board;
Update: You could perform a single allocation but it will be easier for you to work it this way.
Upvotes: 4
Reputation: 117876
You either need to have a dynamically sized array
int* board;
Then your constructor would be
ticTacToe::ticTacToe(int _rows, int _cols)
: rows{_rows}, cols{_cols}
{
board = new int[rows * cols];
}
And your destructor
ticTacToe::~ticTacToe()
{
delete[] board;
}
Or better yet use a std::vector
std::vector<int> board;
Then your constructor would be
ticTacToe::ticTacToe(int _rows, int _cols)
: rows{_rows}, cols{_cols}
{
board.resize(_rows * _cols);
}
Upvotes: 1