/*------------------------------------------------------------------------------
Projekt: ICP - game Othello
Authors: Michal Schorm (xschor02)
Date: FIT VUTBR 2016
File content: class Board
-------------------------------------------------------------------------------*/
#include "./Field.cpp" // game Board contains fileds inside (playable) and fields around (border)
//! Class Board - represents game Board which consists form Fields
/*!
Board can have only several fixed sizes 6*6, 8*8, 10*10, 12*12
This class contains methods to analyze Disk on the board and check if somebody aleady won or if actual player has any possible move.
*/
#ifndef BOARD_CLASS_FULL
#define BOARD_CLASS_FULL
class Board
{
private:
//! Array of pointers to fields. Maximum size of game Board is 12*12, one line on each side is consists from border fields so it is 14*14.
Field * fields[14][14];
//! square root of number of playable fields. On 8*8 board it is 8 etc.
int size;
public:
//! Constructor create game Board. Make array of Fileds and set neigbours to each other (of on-border fields)
Board(int size)
{
this->size = size;
int row, col;
for(row = 0; row<=size+1; row++)
{
for(col = 0; col<=size+1; col++)
{
if(col == 0 || row == 0 || col == size+1 || row == size+1)
{
this->fields[row][col] = new Field(true);
}
else
{
this->fields[row][col] = new Field(false);
}
}
}
for(row = 1; row<=size; row++)
{
for(col = 1; col<=size; col++)
{
(*(this->fields[row][col])).setNeighbour(RR, fields[row][col+1]);
(*(this->fields[row][col])).setNeighbour(RD, fields[row+1][col+1]);
(*(this->fields[row][col])).setNeighbour(DD, fields[row+1][col]);
(*(this->fields[row][col])).setNeighbour(LD, fields[row+1][col-1]);
(*(this->fields[row][col])).setNeighbour(LL, fields[row][col-1]);
(*(this->fields[row][col])).setNeighbour(LU, fields[row-1][col-1]);
(*(this->fields[row][col])).setNeighbour(UU, fields[row-1][col]);
(*(this->fields[row][col])).setNeighbour(RU, fields[row-1][col+1]);
}
}
}
//! returns pointer to filed on coordinates given
Field * getField(int row, int col)
{
if(row<1 || row>this->size || col<1 || col>this->size) return NULL;
return this->fields[col][row];
}
//! returns size of the game Board
int getBoardSize()
{
return this->size;
}
//! put disk of givn color on coordinates given. Field::canPutDisk MUST always be checked before.
void putDisk(int row, int col, DiskColor color)
{
this->fields[row][col]->putDisk(new Disk(color));
}
//! draw game Board into the console.
void drawBoard()
{
int row, col;
for(col = 0; col<=(this->size)+1; col++, cout << endl)
{
for(row = 0; row<=(this->size)+1; row++)
{
if(col == 0 || col == (this->size)+1 ) cout << "-";
else if(row == 0 || row == (this->size)+1 ) cout << "|";
else if( (*(this->fields[row][col])).getDiskColor() == none) cout << ".";
else cout << (*(this->fields[row][col])).getDiskColor();
}
}
}
//! return amount of Disks of color given on this board
int amount(DiskColor color)
{
int row, col, amount;
for(row = 1, amount=0; row<=(this->size); row++)
{
for(col = 1; col<=(this->size); col++)
{
if( this->fields[row][col]->getDiskColor() == color) amount++;
}
}
return amount;
}
//! chceck who won (white/black/draw/none)
DiskColor checkWin()
{
int numWhite = this->amount(white);
int numBlack = this->amount(black);
if( numWhite == 0) return black;
else if( numBlack == 0 ) return white;
else if( numWhite+numBlack == (this->size)*(this->size) )
{
if( numWhite > numBlack ) return white;
else if( numBlack > numWhite ) return black;
else return draw;
}
else return none;
}
//! chceck if player of color given has any possible move (true/false)
bool checkCanPlay(DiskColor color)
{
int row, col;
for(row = 1; row<=(this->size); row++)
{
for(col = 1; col<=(this->size); col++)
{
if(this->fields[row][col]->canPutDisk(color)) return true;
}
}
return false;
}
};
#endif