topical media & game development
professional-program-15-GameBoard-GameBoard.c
? /
professional-program-15-GameBoard-GameBoard.c
// GameBoard.cpp
include <GameBoard.h>
using namespace std;
// Microsoft Visual Studio requires you to omit the following two lines.
// However, some compilers require them.
//const int GameBoard::kDefaultWidth;
//const int GameBoard::kDefaultHeight;
GameBoard::GameBoard(int inWidth, int inHeight) throw(bad_alloc) :
mWidth(inWidth), mHeight(inHeight)
{
int i, j;
mCells = new GamePiece* [mWidth];
try {
for (i = 0; i < mWidth; i++) {
mCells[i] = new GamePiece[mHeight];
}
} catch (...) {
//
// Cleanup any memory we already allocated, because the destructor
// will never get called. The upper bound of the for loop is the index
// of the last element in the mCells array that we tried to allocate
// (the one that failed). All indices before that one store pointers to
// allocated memory that must be freed.
//
for (j = 0; j < i; j++) {
delete [] mCells[j];
}
delete [] mCells;
// translate any exception to bad_alloc
throw bad_alloc();
}
}
GameBoard::GameBoard(const GameBoard& src) throw (bad_alloc)
{
copyFrom(src);
}
GameBoard::~GameBoard() throw()
{
// free the old memory
for (int i = 0; i < mWidth; i++) {
delete [] mCells[i];
}
delete [] mCells;
}
GameBoard& GameBoard::operator=(const GameBoard& rhs) throw (bad_alloc)
{
// check for self-assignment
if (this == &rhs) {
return (*this);
}
// free the old memory
for (int i = 0; i < mWidth; i++) {
delete [] mCells[i];
}
delete [] mCells;
// copy the new memory
copyFrom(rhs);
return (*this);
}
void GameBoard::copyFrom(const GameBoard& src) throw(bad_alloc)
{
int i, j;
mWidth = src.mWidth;
mHeight = src.mHeight;
mCells = new GamePiece *[mWidth];
try {
for (i = 0; i < mWidth; i++) {
mCells[i] = new GamePiece[mHeight];
}
} catch (...) {
// Cleanup any memory we already allocated.
// If this function is called from the copy constructor,
// the destructor will never get called.
// Use the same upper bound on the loop as described in the constructor.
for (j = 0; j < i; j++) {
delete [] mCells[j];
}
delete [] mCells;
// Set mCells and mWidth to values that will allow the
// destructor to run without harming anything.
// This function is called from operator=, in which case the
// object was already constructed, so the destructor will get
// called.
mCells = NULL;
mWidth = 0;
throw bad_alloc();
}
for (i = 0; i < mWidth; i++) {
for (j = 0; j < mHeight; j++) {
mCells[i][j] = src.mCells[i][j];
}
}
}
void GameBoard::setPieceAt(int x, int y, const GamePiece& inElem)
throw(out_of_range)
{
// Check for out of range arguments
if (x < 0 || x >= mWidth || y < 0 || y >= mHeight) {
throw out_of_range("Invalid width or height");
}
mCells[x][y] = inElem;
}
GamePiece& GameBoard::getPieceAt(int x, int y) throw(out_of_range)
{
// Check for out of range arguments
if (x < 0 || x >= mWidth || y < 0 || y >= mHeight) {
throw out_of_range("Invlalid width or height");
}
return (mCells[x][y]);
}
const GamePiece& GameBoard::getPieceAt(int x, int y) const throw(out_of_range)
{
// Check for out of range arguments
if (x < 0 || x >= mWidth || y < 0 || y >= mHeight) {
throw out_of_range("Invlalid width or height");
}
return (mCells[x][y]);
}
(C) Æliens
20/2/2008
You may not copy or print any of this material without explicit permission of the author or the publisher.
In case of other copyright issues, contact the author.