Main Page   Namespace List   Class Hierarchy   Compound List   File List   Compound Members   File Members  

LifeExercise.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 // ...
00009 
00010 namespace {
00011     const int SIZE_X = 30;
00012     const int SIZE_Y = 20;
00013     const char ALIVE = '*';
00014     const char DEAD  = ' ';
00015     typedef char lifeMatrix_t[SIZE_X][SIZE_Y];
00016 }
00017 
00023 class ModN {
00024 public:
00025 
00030     ModN(int mod, int value = 0) : fMod(mod), fValue(value), fCompleted(false) {}
00031 
00036     inline ModN& operator++(int) {
00037         fValue = (fValue + 1) % fMod;
00038         fCompleted = (fValue == 0);
00039         return *this;
00040     }
00041 
00046     inline ModN& operator--(int) {
00047         fValue = (fValue + fMod - 1) % fMod;
00048         fCompleted = (fValue == fMod - 1);
00049         return *this;
00050     }
00051 
00056     inline bool operator==(const ModN& operand) const { return (fMod == operand.fMod) && (fValue == operand.fValue); }
00057 
00066     inline operator int() const { return fValue; }
00067 
00074     inline bool completed() { return fCompleted; }
00075 private:
00076     int fMod;
00077     int fValue;
00078     bool fCompleted;
00079 };
00080 
00085 class LifeMatrix {
00086 public:
00090     inline void display() const {
00091         for(int i = 0; i<SIZE_Y; i++) {
00092             cout << "|";
00093             for(int j = 0; j<SIZE_X; j++){
00094                 cout << fMatrix[j][i];
00095             }
00096             cout << "|";
00097             cout << endl;
00098         }   
00099         cout << endl;
00100     }
00101 
00108     inline int countNeighbours (const ModN& x, const ModN& y) const {
00109         int neighbours = 0;
00110 
00111         ModN mX = x;
00112         mX--;
00113         for(int i = 0; i<3; i++){ // can't use mX as counter because of mod n !
00114             ModN mY = y;
00115             mY--;
00116             for(int j = 0; j<3; j++){
00117                 neighbours += !((mX == x)&&(mY == y)) && isAlive(mX, mY) ? 1 : 0;
00118                 mY++;
00119             }
00120             mX++;
00121         }
00122         return neighbours;
00123     }
00124 
00129     inline void fill(){
00130         for(int i = 0; i<SIZE_X; i++){
00131             for(int j = 0; j<SIZE_Y; j++){
00132                 fMatrix[i][j] = fillGlider(i, j);
00133             }
00134         }   
00135     }
00136 
00142     inline void kill(const ModN& i, const ModN& j){
00143         fMatrix[i][j] = DEAD;
00144     }
00145 
00151     inline void enliven(const ModN& x, const ModN& y){
00152         fMatrix[x][y] = ALIVE;
00153     }
00154 
00160     inline bool isAlive(const ModN& x, const ModN& y) const {
00161         return fMatrix[x][y] == ALIVE;
00162     }
00163 
00167     static inline void initRand() {
00168         long sek;
00169         time(&sek);
00170         srand((unsigned)sek);
00171     }
00172 
00173 private:
00174 
00178     inline char fillRand(int x, int y) {
00179         return rand()%2 ? ALIVE : DEAD;
00180     }
00181 
00185     inline char fillSquare58(int x, int y){
00186         return (x>5)&&(x<8)&&(y>5)&&(y<8) ? ALIVE : DEAD;
00187     }
00188 
00192     inline char fillLine(int x, int y){
00193         return (x==8 || x== 12)&&(y>5)&&(y<9)  ? ALIVE : DEAD;
00194     }
00195 
00199     inline char fillGlider(int x, int y){
00200         return 
00201             (x==0 && y== 0)
00202             ||(x==0 && y== 1)
00203             ||(x==0 && y== 2)
00204             ||(x==1 && y== 0)
00205             ||(x==2 && y== 1)
00206             ? ALIVE : DEAD;
00207     }
00208 
00209     lifeMatrix_t fMatrix;
00210 };
00211 
00216 class Life {
00217 public:
00218     Life() : fNow(new LifeMatrix()), fFuture(new LifeMatrix()) {}
00219 
00223     inline void run(){
00224         LifeMatrix::initRand();
00225         fill();
00226         while(true){
00227             display();
00228             calculate();
00229             wait();
00230         }
00231     }
00232 
00233     ~Life(){
00234         delete fNow;
00235         delete fFuture;
00236     }
00237 private:
00238 
00242     inline void Life::fill(){
00243         fNow->fill();
00244     }
00245 
00249     inline void Life::display(){
00250         cls();
00251         fNow->display();
00252     }
00253 
00261     inline void 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 Life::swap(){
00283         LifeMatrix* tmp = fNow;
00284         fNow = fFuture;
00285         fFuture = tmp;
00286     }
00287 
00291     static inline void Life::wait() {
00292         for(long i= 0;i<19999999L;i++){}
00293     }
00294 
00298     static inline void Life::cls(){
00299         system("cls");
00300     }
00301 
00302     LifeMatrix* fNow;
00303     LifeMatrix* fFuture;
00304 };
00305 
00310 class LifeExercise : public AbstractExercise {
00311 public:
00312 
00313     LifeExercise(string name) : AbstractExercise(name){}
00314 
00315 protected:
00316 
00317     void execute();
00318 
00319 private:
00320     Life fLife;
00321 };
00322     
00323 namespace {
00324     LifeExercise proto("LifeExercise");
00325 }
00326 
00327 void LifeExercise::execute(){
00328     fLife.run();
00329 }
00330 
00331 

Generated on Sat Jul 19 18:19:54 2003 for Exercise Framework by doxygen1.2.18