139 lines
3.4 KiB
C++
139 lines
3.4 KiB
C++
#include <string>
|
|
|
|
struct BoundaryCondition
|
|
{
|
|
virtual bool boundary(Board& board, int i, int j) = 0;
|
|
};
|
|
|
|
class Board {
|
|
public :
|
|
// Konstruktor, erzeuge bool* _fields
|
|
Board(int width, int height, BoundaryCondition cond);
|
|
|
|
// Desktruktor, raeume bool* _fields auf
|
|
~Board();
|
|
|
|
// copy constructor, intializes by copying from 'other'
|
|
Board(Board& other);
|
|
|
|
// assignment operator
|
|
Board& operator=(Board& other);
|
|
|
|
// gibt die Breite des Bretts zurueck
|
|
double width();
|
|
|
|
// gibt die Hoehe des Bretts zurueck
|
|
double height();
|
|
|
|
// schreibe value an den Pixel (i,j)
|
|
// Ueberlegen Sie wie aus (i,j) den flachen Index bei row-major bekommen
|
|
void updateField(int i, int j, bool value);
|
|
|
|
// Zugang zum Pixel (i,j) im 1D Array
|
|
// Ueberlegen Sie wie aus (i,j) den flachen Index bei row-major bekommen
|
|
int operator()(int i, int j);
|
|
|
|
// Gibt zurueck ob Feld am Rand liegt
|
|
bool touchesBoundary(int i, int j);
|
|
|
|
// Gibt Zahl der lebenden Zellen zurueck, die das Feld umgeben
|
|
int livingCells(int i, int j);
|
|
|
|
// Prueft ob Zelle lebt oder nicht
|
|
bool isLiving(int i, int j);
|
|
|
|
// Gibt die BoundaryCondition zurueck
|
|
BoundaryCondition boundaryCondition();
|
|
|
|
private :
|
|
int _width;
|
|
int _height;
|
|
bool* _fields;
|
|
void copy(Board& other);
|
|
BoundaryCondition _boundCond;
|
|
};
|
|
|
|
Board::Board(int width, int height, BoundaryCondition cond) {
|
|
// initialize all values
|
|
_width = width;
|
|
_height = height;
|
|
_boundCond = cond;
|
|
_fields = new bool[width * height];
|
|
}
|
|
|
|
Board::~Board() {
|
|
_fields = 0;
|
|
}
|
|
|
|
void Board::copy(Board& other) {
|
|
_width = other.width();
|
|
_height = other.height();
|
|
_boundCond = other.boundaryCondition();
|
|
_fields = new bool[_width * _height];
|
|
for (int i = 0; i < _height; i++) {
|
|
for (int j = 0; j < _width; j++) {
|
|
updateField(i, j, other.isLiving(i, j));
|
|
}
|
|
}
|
|
}
|
|
|
|
Board::Board(Board& other) {
|
|
copy(other);
|
|
}
|
|
|
|
Board& Board::operator=(Board& other) {
|
|
if (this == &other) {
|
|
return *this;
|
|
}
|
|
copy(other);
|
|
return *this;
|
|
}
|
|
|
|
double Board::width() {
|
|
return _width;
|
|
}
|
|
|
|
double Board::height() {
|
|
return _height;
|
|
}
|
|
|
|
BoundaryCondition Board::BoundaryCondition() {
|
|
return _boundCond;
|
|
}
|
|
|
|
void Board::updateField(int i, int j, bool value) {
|
|
// i = Zeile und wegen row-major Konvention muss i mit der Breite
|
|
// multipliziert werden
|
|
_fields[i * _width + j] = value;
|
|
}
|
|
|
|
bool Board::touchesBoundary(int i, int j) {
|
|
return i == _height - 1 || i == -1 || j == _width - 1 || j == -1;
|
|
}
|
|
|
|
int Board::livingCells(int i, int j) {
|
|
bool surround[8] = { isLiving(i+1, j+1), isLiving(i, j+1), isLiving(i-1, j+1)
|
|
, isLiving(i+1, j), isLiving(i-1, j)
|
|
, isLiving(i+1, j-1), isLiving(i, j-1), isLiving(i-1, j-1)};
|
|
int numLiving = 0;
|
|
for (int i = 0; i < 8; i++) {
|
|
if (surround[i] == true) {
|
|
numLiving += 1;
|
|
}
|
|
}
|
|
}
|
|
|
|
bool Board::isLiving(int i, int j) {
|
|
if (touchesBoundary(i, j)) {
|
|
return _boundCond.boundary(i, j);
|
|
} else {
|
|
return _fields[i * _width + j];
|
|
}
|
|
}
|
|
|
|
int Board::operator()(int i, int j) {
|
|
// i = Zeile und wegen row-major Konvention muss i mit der Breite
|
|
// Pixel multipliziert werden
|
|
return _fields[i * _width+ j];
|
|
}
|