00001 #include "macros.h"
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++){
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