#include #include #include using namespace std ; #include "LifeBoard.h" static void clearScreen() { cout << "\033[2J\033[H" ; } void Cell::setNeighbors(vector list) { neighbors = list ; } bool Cell::isAlive() { return alive ; } void Cell::setAlive(bool b) { alive = b ; } void Cell::update() { alive = aliveNext ; } void Cell::willSurvive() { int count = 0 ; for (unsigned int i=0 ; i < neighbors.size() ; i++) { if (neighbors[i]->isAlive()) count++ ; } aliveNext = false ; if (alive && count >=2 && count <= 3) aliveNext = true ; if (!alive && count == 3) aliveNext = true ; } unsigned int LifeBoard::pos(unsigned int r, unsigned int c) { return r * cols + c ; } LifeBoard::LifeBoard(unsigned int r, unsigned int c, bool *b) : cells(r*c), rows(r), cols(c) { // testing // cout << "# cells = " << cells.size() << endl ; if (b==NULL) { for (unsigned int i=0 ; i < cells.size() ; i++) { cells[i].setAlive(false) ; } } else { // cout << "initialize\n" ; for (unsigned int i=0 ; i < cells.size() ; i++) { cells[i].setAlive(b[i]) ; } } vector cornerList(3) ; // Top Left cornerList[0] = &cells[pos(0,1)] ; cornerList[1] = &cells[pos(1,1)] ; cornerList[2] = &cells[pos(1,0)] ; cells[pos(0,0)].setNeighbors(cornerList) ; // Top Right cornerList[0] = &cells[pos(0,cols-2)] ; cornerList[1] = &cells[pos(1,cols-2)] ; cornerList[2] = &cells[pos(2,cols-1)] ; cells[pos(0,cols-1)].setNeighbors(cornerList) ; // Bottom Left cornerList[0] = &cells[pos(rows-2,0)] ; cornerList[1] = &cells[pos(rows-2,1)] ; cornerList[2] = &cells[pos(rows-1,1)] ; cells[pos(rows-1,0)].setNeighbors(cornerList) ; // Bottom Right cornerList[0] = &cells[pos(rows-2,cols-1)] ; cornerList[1] = &cells[pos(rows-2,cols-2)] ; cornerList[2] = &cells[pos(rows-1,cols-2)] ; cells[pos(rows-1,cols-1)].setNeighbors(cornerList) ; vector edgeList(5) ; // Top Row for (unsigned int i = 1 ; i < cols -1 ; i++ ) { edgeList[0] = &cells[pos(0,i-1)] ; edgeList[1] = &cells[pos(1,i-1)] ; edgeList[2] = &cells[pos(1,i)] ; edgeList[3] = &cells[pos(1,i+1)] ; edgeList[4] = &cells[pos(0,i+1)] ; cells[pos(0,i)].setNeighbors(edgeList) ; } // Bottom Row for (unsigned int i = 1 ; i < cols -1 ; i++ ) { edgeList[0] = &cells[pos(rows-1,i-1)] ; edgeList[1] = &cells[pos(rows-2,i-1)] ; edgeList[2] = &cells[pos(rows-2,i)] ; edgeList[3] = &cells[pos(rows-2,i+1)] ; edgeList[4] = &cells[pos(rows-1,i+1)] ; cells[pos(rows-1,i)].setNeighbors(edgeList) ; } // Leftmost Column for (unsigned int i = 1 ; i < rows-1 ; i++ ) { edgeList[0] = &cells[pos(i-1,0)] ; edgeList[1] = &cells[pos(i-1,1)] ; edgeList[2] = &cells[pos(i,1)] ; edgeList[3] = &cells[pos(i+1,1)] ; edgeList[4] = &cells[pos(i+1,0)] ; cells[pos(i,0)].setNeighbors(edgeList) ; } // Rightmost Column for (unsigned int i = 1 ; i < rows-1 ; i++ ) { edgeList[0] = &cells[pos(i-1,cols-1)] ; edgeList[1] = &cells[pos(i-1,cols-2)] ; edgeList[2] = &cells[pos(i,cols-2)] ; edgeList[3] = &cells[pos(i+1,cols-2)] ; edgeList[4] = &cells[pos(i+1,cols-1)] ; cells[pos(i,cols-1)].setNeighbors(edgeList) ; } vector middleList(8) ; for (unsigned int i = 1 ; i < rows-1 ; i++ ) { for (unsigned int j = 1 ; j < cols -1 ; j++ ) { middleList[0] = &cells[pos(i-1,j-1)] ; middleList[1] = &cells[pos(i-1,j)] ; middleList[2] = &cells[pos(i-1,j+1)] ; middleList[3] = &cells[pos(i,j-1)] ; middleList[4] = &cells[pos(i,j+1)] ; middleList[5] = &cells[pos(i+1,j-1)] ; middleList[6] = &cells[pos(i+1,j)] ; middleList[7] = &cells[pos(i+1,j+1)] ; cells[pos(i,j)].setNeighbors(middleList) ; } } return ; } void LifeBoard::setPattern(unsigned int r, unsigned int c, bool *b) { for (unsigned int i = 0 ; i < r * c ; i++) { cells[i].setAlive(b[i]) ; } } void LifeBoard::update() { for (unsigned int i = 0 ; i < cells.size() ; i++) { cells[i].willSurvive() ; } for (unsigned int i = 0 ; i < cells.size() ; i++) { cells[i].update() ; } } void LifeBoard::display(ostream& os) { for (unsigned int r = 0 ; r < rows ; r++) { for (unsigned int c = 0 ; c < cols ; c++) { if (cells[pos(r,c)].alive) { os << "\u2588 " ; } else { os << ". " ; } } os << endl ; } } void LifeBoard::run(unsigned int steps, unsigned int delay) { char temp[50] ; clearScreen() ; display() ; cout << "Iteration #0\n" ; cout << "Type enter to continue..." ; cin.getline(temp, 50) ; for (int i = 1 ; i <= steps ; i++) { update() ; clearScreen() ; display() ; cout << "Iteration #" << i << endl ; // cout << "Delay = " << delay << endl ; usleep(delay*1000) ; // convert to microseconds } } void LifeBoard::batchRun(unsigned int steps) { for (int i = 1 ; i <= steps ; i++) { update() ; } }