Jump to content
  • Advertisement
Sign in to follow this  
RedKMan

Struggling with 2D std::vector in c++

This topic is 3171 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I'm having problems trying to "get" 2d vectors. I'm trying to swap over from using arrays to use vectors in my tic tac toe game. Below is what I can do,
int boardSize;
std::vector< std::vector<char> > board;		// 2D Game board.
	
std::cout << "Please enter the board size you desire: " << std::endl;
std::cin >> boardSize;

board.resize(boardSize);

So for example if boardSize is 3 then the 2d vector board will be 3*3 with 9 elements. Problem I can't work out now is how to iterate through the thing. I need to:- 1. initialise every element to '\0'. 2. assign O or X to a specific element, ie board[row][column] = 'X' Any tips much appreciated as after a week of googling I'm still not getting it.

Share this post


Link to post
Share on other sites
Advertisement

int boardSize = ###;
std::vector< std::vector<char> > board;
board.resize(boardSize);
for ( size_t row = 0; row < boardSize; row ++ )
{
board[row].resize(boardSize);
}




This will create a "square" vector of vectors. I personally think of the "outer" vector as the rows and the inner vector as the "columns." You can access elements by specifying board[row][col];

The first index relates to the size you specified when you did this:
board.resize(number of rows);

The second index relates to the size of each index you specifically resized:
board[row].resize(number of columns in this row);

Share this post


Link to post
Share on other sites
The easiest way would be:
board.resize(boardSize, std::vector<char>(boardSize, '\0'));


I would however make a class that represents a board.

class Board
{
public:
Board(unsigned size) : fields_(size * size, '\0') { }

char get(unsigned x, unsigned y) const
{
assert(x < size_ && y < size_);
return fields_[x + y * size_];
}

void set(unsigned x, unsigned y, char c)
{
assert(x < size_ && y < size_);
assert(c == 'O' || c == 'X');
fields_[x + y * size_] = c;
}

private:
unsigned size_;
std::vector<char> fields_;
};

unsigned boardSize;

std::cout << "Please enter the board size you desire: " << std::endl;
std::cin >> boardSize;

Board board(boardSize);

board.set(2, 2, 'X');

Share this post


Link to post
Share on other sites
Don't use vectors of vectors it's generally a bad idea. Either use a 1D vector indexing it as Black Knight suggsests (possibly with a nice wrapper), or look into boost if you want a clean solution with good stl compatibility: http://www.boost.org/doc/libs/1_41_0/libs/multi_array/doc/user.html

Share this post


Link to post
Share on other sites
In the particular case of tic-tac-toe, an array of 9 elements is probably the best solution.

For other cases where you want to represent something like a matrix, the STL also has a specialized container called `valarray' which might be appropriate.

Share this post


Link to post
Share on other sites
I'm still struggling with iteration. The example below returns a Debug Assertation failed. Expression: Vector subscript out of range.


class GameBoard
{
public:

GameBoard(unsigned size);

~GameBoard();

// Get the board size.
unsigned getBoardSize();

// Set the board size.
void setBoardSize(unsigned size);

// Initialise the board
void initBoard();

private:

unsigned boardSize;
std::vector<char> board;

};




#include "GameBoard.h"


//---------------------------------------------------------------
// Name: Constructor()
// Desc: Takes an unsigned value which is used to set the size of
// the board.
//---------------------------------------------------------------
GameBoard::GameBoard(unsigned size)
: boardSize(size * size), board(size * size, '\0')
{

}



//---------------------------------------------------------------
// Name: Destructor()
// Desc: GameBoard Class Destructor
//---------------------------------------------------------------
GameBoard::~GameBoard()
{
}


//---------------------------------------------------------------
// Name: getBoardSize()
// Desc: Returns the size of the board.
//---------------------------------------------------------------
unsigned GameBoard::getBoardSize()
{
return boardSize;
}


//---------------------------------------------------------------
// Name: setBoardSize()
// Desc: Set the size of the board
//---------------------------------------------------------------
void GameBoard::setBoardSize(unsigned size)
{
boardSize = size * size;
}


//---------------------------------------------------------------
// Name: initBoard()
// Desc: Initialise / clear the game board
//---------------------------------------------------------------
void GameBoard::initBoard()
{
for(unsigned row = 0; row < getBoardSize(); row++)
{
for(unsigned col = 0; col < getBoardSize(); col++)
{
board[row + col * getBoardSize()] = '\0';
}
}
}


#include "GameBoard.h"

int main()
{
unsigned boardSize;

std::cout << " please enter the board size : ";
std::cin >> boardSize;

// Instantiate game objects.
GameBoard TicTacToe(boardSize);

std::cout << "The board size is " << TicTacToe.getBoardSize();

TicTacToe.initBoard();

return 0;
}



The problem is initBoard() I think I've got lost somewhere. Can anyone help?

Share this post


Link to post
Share on other sites
Quote:
Original post by RedKMan
I'm still struggling with iteration. The example below returns a Debug Assertation failed. Expression: Vector subscript out of range.

*** Source Snippet Removed ***

*** Source Snippet Removed ***

The problem is initBoard() I think I've got lost somewhere. Can anyone help?

It's because you're iterating over each dimension using boardSize, which is the size of the whole board, instead of the length of each dimension (which is the square-root of boardSize, or the size parameter you pass into the constructor). However you shouldn't clear the board like that anyway - just use existing vector functionality:

board.assign(boardSize, '\0');

Share this post


Link to post
Share on other sites
I'm still getting a Debug Assertation failed. Expression: Vector subscript out of range.

The vector is declared as,


std::vector<char> board;

GameBoard::GameBoard(unsigned size)
: boardSize(size * size), board(size * size, '\0')
{

}



So for example upon creation if size is 3 then board becomes 3 * 3 = 9.

Following some of the tips above my function for putting either an X or an O in the right coordinate on the grid is.


//---------------------------------------------------------------
// Name: setBoard()
// Desc: Checks to make sure the choice is empty and valid,
// e.g. within the range of 0 and 2 for both row and column
// and does not allready contain a O or X.
// Sets the location row, column to either X or O
// depending on the argument marker.
//---------------------------------------------------------------
bool GameBoard::setBoard(unsigned row, unsigned column, char playerMarker)
{
// Check to see if either row or column is greater than
// the actual board size.
if((row > getBoardSize()) && (column > getBoardSize()))
{
return false;
}

// Check to see if the players choice is an empty position.
if(board[row + column * getBoardSize()] != '\0')
{
return false;
}

// The user choice is valid and the location is empty so update
// the game board with the players relevant marker either X or O.
board[row + column * getBoardSize()] = playerMarker;

return true;
}



The board[row + column * getBoardSize()] = playerMarker solution for assigning a marker to the correct coordinate in the vector isn't working. What will work, bearing in mind I only want to use a row, column coordinate system.

Help appreciated.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!