Life001.cpp

Go to the documentation of this file.
00001 #include "macros.h" // needs to be declared as first entry in .cpp or .h file!
00002 #include <string>
00003 #include <iostream>
00004 using namespace std;
00005 #include "AbstractExercise.h"
00006 #include <ctime>
00007 #include <cstdlib>
00008 #include "Life001.h"
00009 // ...
00010 
00011 namespace {
00012     const int SIZE_X = 30;
00013     const int SIZE_Y = 20;
00014     const char ALIVE = '*';
00015     const char DEAD  = ' ';
00016     typedef char lifeMatrix_t[SIZE_X][SIZE_Y];
00017 }
00018 
00024 class ModN {
00025 public:
00026 
00031     ModN(int mod, int value = 0) : fMod(mod), fValue(value), fCompleted(false) {}
00032 
00037     inline ModN& operator++() {
00038         fValue = (fValue + 1) % fMod;
00039         fCompleted = (fValue == 0);
00040         return *this;
00041         string s;
00042     }
00043 
00048     inline ModN& operator--() {
00049         fValue = (fValue + fMod - 1) % fMod;
00050         fCompleted = (fValue == fMod - 1);
00051         return *this;
00052     }
00053 
00058     inline bool operator==(const ModN& operand) const { return (fMod == operand.fMod) && (fValue == operand.fValue); }
00059 
00068     inline operator int() const { return fValue; }
00069 
00077     inline bool completed() { return fCompleted; }
00078 private:
00079     int fMod;
00080     int fValue;
00081     bool fCompleted;
00082 };
00083 
00088 class LifeMatrix {
00089 public:
00093     inline void display() const {
00094         for(int i = 0; i<SIZE_Y; i++) {
00095             cout << "|";
00096             for(int j = 0; j<SIZE_X; j++){
00097                 cout << fMatrix[j][i];
00098             }
00099             cout << "|";
00100             cout << endl;
00101         }   
00102         cout << endl;
00103     }
00104 
00111     inline int countNeighbours (const ModN& x, const ModN& y) const {
00112         int neighbours = 0;
00113 
00114         ModN mX = x;
00115         --mX;
00116         for(int i = 0; i<3; i++){ // can't use mX as counter because of mod n !
00117             ModN mY = y;
00118             --mY;
00119             for(int j = 0; j<3; j++){
00120                 neighbours += !((mX == x)&&(mY == y)) && isAlive(mX, mY) ? 1 : 0;
00121                 ++mY;
00122             }
00123             ++mX;
00124         }
00125         return neighbours;
00126     }
00127 
00132     inline void fill(){
00133         for(int i = 0; i<SIZE_X; i++){
00134             for(int j = 0; j<SIZE_Y; j++){
00135                 fMatrix[i][j] = fillGlider(i, j);
00136             }
00137         }   
00138     }
00139 
00145     inline void kill(const ModN& i, const ModN& j){
00146         fMatrix[i][j] = DEAD;
00147     }
00148 
00154     inline void enliven(const ModN& x, const ModN& y){
00155         fMatrix[x][y] = ALIVE;
00156     }
00157 
00163     inline bool isAlive(const ModN& x, const ModN& y) const {
00164         return fMatrix[x][y] == ALIVE;
00165     }
00166 
00170     static inline void initRand() {
00171         long sek;
00172         time(&sek);
00173         srand((unsigned)sek);
00174     }
00175 
00176 private:
00177 
00181     inline char fillRand(int x, int y) {
00182         return rand()%2 ? ALIVE : DEAD;
00183     }
00184 
00188     inline char fillSquare58(int x, int y){
00189         return (x>5)&&(x<8)&&(y>5)&&(y<8) ? ALIVE : DEAD;
00190     }
00191 
00195     inline char fillLine(int x, int y){
00196         return (x==8 || x== 12)&&(y>5)&&(y<9)  ? ALIVE : DEAD;
00197     }
00198 
00202     inline char fillGlider(int x, int y){
00203         return 
00204             (x==0 && y== 0)
00205             ||(x==0 && y== 1)
00206             ||(x==0 && y== 2)
00207             ||(x==1 && y== 0)
00208             ||(x==2 && y== 1)
00209             ? ALIVE : DEAD;
00210     }
00211 
00212     lifeMatrix_t fMatrix;
00213 };
00214 
00219 Life001::Life001() : fNow(new LifeMatrix()), fFuture(new LifeMatrix()) {}
00220 
00224 void Life001::run(){
00225     LifeMatrix::initRand();
00226     fill();
00227     while(true){
00228         display();
00229         calculate();
00230         wait();
00231     }
00232 }
00233 
00234 Life001::~Life001(){
00235     delete fNow;
00236     delete fFuture;
00237 }
00238 
00242 inline void Life001::fill(){
00243     fNow->fill();
00244 }
00245 
00249 inline void Life001::display(){
00250     cls();
00251     fNow->display();
00252 }
00253 
00261 inline void Life001::calculate(){
00262     for(ModN i(SIZE_X, 0); !i.completed(); ++i){
00263         for(ModN j(SIZE_Y, 0); !j.completed(); ++j){
00264             int n = fNow->countNeighbours(i, j);
00265             if((n < 2)||(n > 3)){
00266                 fFuture->kill(i, j);
00267             } else if ((n == 2) && (fNow->isAlive(i, j))) {
00268                 fFuture->enliven(i, j);
00269             } else if (n == 3){
00270                 fFuture->enliven(i, j);
00271             } else {
00272                 fFuture->kill(i, j);
00273             }
00274         }
00275     }
00276     swap();
00277 }
00278 
00282 inline void Life001::swap(){
00283     LifeMatrix* tmp = fNow;
00284     fNow = fFuture;
00285     fFuture = tmp;
00286 }
00287 
00291 void Life001::wait() {
00292     for(long i= 0;i<19999999L;i++){}
00293 }
00294 
00298 void Life001::cls(){
00299     system("cls");
00300 }
00301 

Generated on Thu Jul 3 19:12:45 2008 for Exercise Framework by  doxygen 1.5.1