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
00009
00010
00011
00012 namespace {
00013 const int SIZE_X = 30;
00014 const int SIZE_Y = 20;
00015 const char ALIVE = '*';
00016 const char DEAD = ' ';
00017 typedef char lifeMatrix_t[SIZE_X][SIZE_Y];
00018 }
00019
00020
00021
00022 class LifeMatrix {
00023 public:
00024 inline void display(){
00025 for(int i = 0; i<SIZE_Y; i++){
00026 cout << "|";
00027 for(int j = 0; j<SIZE_X; j++){
00028 cout << fMatrix[j][i];
00029 }
00030 cout << "|";
00031 cout << endl;
00032 }
00033 cout << endl;
00034 }
00035
00036 inline int neighbours (int x, int y){
00037 int n = 0;
00038 int nX = indexLeft(x);
00039 for(int i = 0; i<3; i++){
00040 int nY = indexDown(y);
00041 for(int j = 0; j<3; j++){
00042 if((x != nX)||(y != nY)) {
00043 n += fMatrix[nX][nY] == ALIVE;
00044 }
00045 nY = indexUp(nY);
00046 }
00047 nX = indexRight(nX);
00048 }
00049 return n;
00050 }
00051
00052 inline void fill(){
00053 for(int i = 0; i<SIZE_X; i++){
00054 for(int j = 0; j<SIZE_Y; j++){
00055 fMatrix[i][j] = fillGlider(i, j);
00056 }
00057 }
00058 }
00059 inline void set(int i, int j, char ch){
00060 fMatrix[i][j] = ch;
00061 }
00062 inline char get(int i, int j){
00063 return fMatrix[i][j];
00064 }
00065 private:
00066
00067 inline int LifeMatrix::indexLeft (int x){
00068 return (x + SIZE_X -1)%SIZE_X;
00069 }
00070
00071 inline int LifeMatrix::indexRight (int x){
00072 return (x + 1)%SIZE_X;
00073 }
00074
00075 inline int LifeMatrix::indexUp (int y){
00076 return (y + 1)%SIZE_Y;
00077 }
00078
00079 inline int LifeMatrix::indexDown (int y){
00080 return (y + SIZE_Y -1)%SIZE_Y;
00081 }
00082
00083 inline char fillRand(int i, int j){
00084 return rand()%2 ? ALIVE : DEAD;
00085 }
00086
00087 inline char fillSquare58(int i, int j){
00088 return (i>5)&&(i<8)&&(j>5)&&(j<8) ? ALIVE : DEAD;
00089 }
00090
00091 inline char fillLine(int i, int j){
00092 return (i==8 || i== 12)&&(j>5)&&(j<9) ? ALIVE : DEAD;
00093 }
00094
00095 inline char fillGlider(int i, int j){
00096 return
00097 (i==0 && j== 0)
00098 ||(i==0 && j== 1)
00099 ||(i==0 && j== 2)
00100 ||(i==1 && j== 0)
00101 ||(i==2 && j== 1)
00102 ? ALIVE : DEAD;
00103 }
00104
00105 lifeMatrix_t fMatrix;
00106 };
00107
00108
00109
00110
00116 class LifeExercise : public AbstractExercise {
00117 public:
00118
00124 LifeExercise(string name) : AbstractExercise(name){
00125 long sek;
00126 time(&sek);
00127 srand((unsigned)sek);
00128 fNow = new LifeMatrix();
00129 fFuture = new LifeMatrix();
00130 }
00131
00132 ~LifeExercise(){
00133 delete fNow;
00134 delete fFuture;
00135 }
00136
00137
00138 protected:
00139
00144 void execute();
00145 private:
00146 LifeMatrix *fNow;
00147 LifeMatrix *fFuture;
00148
00149 inline void LifeExercise::swap(){
00150 LifeMatrix *tmp = fNow;
00151 fNow = fFuture;
00152 fFuture = tmp;
00153 }
00154
00155
00156 inline void LifeExercise::fill(){
00157 fNow->fill();
00158 }
00159
00160 inline void LifeExercise::display(){
00161 fNow->display();
00162 }
00163
00171 inline void calc(){
00172 int i, j;
00173 for(i = 0; i<SIZE_X; i++){
00174 for(j = 0; j<SIZE_Y; j++){
00175 int n = fNow->neighbours(i, j);
00176
00177 if((n < 2)||(n > 3)){
00178 fFuture->set(i,j,DEAD);
00179 } else if ((n == 2) && (fNow->get(i,j) == ALIVE)) {
00180 fFuture->set(i,j,ALIVE);
00181 } else if (n == 3){
00182 fFuture->set(i,j,ALIVE);
00183 } else {
00184 fFuture->set(i,j,DEAD);
00185 }
00186 }
00187 }
00188 swap();
00189 }
00190
00191 };
00192
00198 namespace {
00199 LifeExercise proto("LifeExercise");
00200 }
00201
00202 void LifeExercise::execute(){
00203 fill();
00204 long h;
00205 while(true){
00206 display();
00207 calc();
00208 for(h= 0;h<19999999;h++){}
00209 system("cls");
00210 }
00211 }