//Создать класс живущих с местоположением. Определить наследуемые классы
//- лиса, кролик и трава. Лиса ест кролика. Кролик ест траву.
//Лиса может умереть - определен возраст. Кролик тоже может умереть.
//Кроме этого определен класс - отсутствие жизни.
//Если в окрестности имеется больше травы, чем кроликов,
//то трава остается, иначе трава съедена.
//Если лис слишком старый он может умереть.
//Если лис слишком много (больше 5 в окрестности),
//лисы больше не появляются. Если кроликов меньше лис, то лис ест кролика.
#include <iostream>
using namespace std;
#include "conio.h"
// моделирование хищник - жертва с использованием
// иерархии классов
const int N=6, // размер квадратной площади (мира)
STATES=4, // количество видов жизни
DRAB=5,DFOX=5, // количество циклов жизни кролика и лиса
CYCLES=10; // общее число циклов моделирования мира
enum state{EMPTY,GRASS,RABBIT,FOX};
class living; // forvard объявление
typedef living *world[N][N]; // world- модель мира
void init(world);
void gener(world);
void update(world,world);
void dele(world);
class living
{
protected:
int row,col; // местоположение в модели
void sums(world w,int sm[]); //
public:
living(int r,int c):row(r),col(c){}
virtual state who() = 0; // идентификация состояний
virtual living *next(world w)=0; // расчет next
virtual void print()=0; // вывод содержимого поля модели
};
void living::sums(world w,int sm[])
{
int i,j;
sm[EMPTY]=sm[GRASS]=sm[RABBIT]=sm[FOX]=0;
int i1=-1,i2=1,j1=-1,j2=1;
if(row==0) // 0=0 +
i1=0; // координаты внешних клеток модели
if(row==N-1) // 0=5 -
i2=0;
if(col==0) //0=0+
j1=0;
if(col==N-1) // 0=5 -
j2=0;
for(i=i1;i<=i2;++i)
for(j=j1;j<=j2;++j)
sm[w[row+i][col+j]->who()]++;
}
class fox:public living
{
protected:
int age; // используется для принятия решения о смерти лиса
public:
fox(int r,int c,int a=0):living(r,c),age(a){}//
state who() {return FOX;} // отложенный метод для foxes
living *next(world w); // отложенный метод для foxes
void print(){cout << " ли ";}
};
class rabbit:public living
{
protected:
int age; // используется для принятия решения о смерти кролика
public:
rabbit(int r,int c,int a=0):living(r,c),age(a){}
state who() {return RABBIT;} // отложенный метод для rabbit
living *next(world w); // отложенный метод для rabbit
void print(){cout << " кр ";}
};
class grass:public living
{
public:
grass(int r,int c):living(r,c){}
state who() {return GRASS;} // отложенный метод для grass
living *next(world w); // отложенный метод для grass
void print(){cout << " тр ";}
};
class empty : public living// жизнь отсутствует
{
public:
empty(int r,int c):living(r,c){}
state who() {return EMPTY;} // отложенный метод для empty
living *next(world w); // отложенный метод для empty
void print(){cout << " ";}
};
living *grass::next(world w)
{
int sum[STATES];
sums(w,sum);
if(sum[GRASS]>sum[RABBIT]) // кролик ест траву
return (new grass(row,col));
else
return (new empty(row,col));
}
living *rabbit::next(world w)
{
int sum[STATES];
sums(w,sum);
if(sum[FOX]>=sum[RABBIT]) // лис ест кролика
return (new empty(row,col));
else if(age>DRAB) // кролик слишком старый
return(new empty(row,col));
else
return(new rabbit(row,col,age+1)); // кролик постарел
}
living *fox::next(world w)
{
int sum[STATES];
sums(w,sum);
if(sum[FOX]>5) // слишком много лис
return (new empty(row,col));
else if(age>DFOX) // лис слишком старый
return(new empty(row,col));
else
return(new fox(row,col,age+1)); // лис постарел
}
// заполнение пустой площади
living *empty::next(world w)
{
int sum[STATES];
sums(w,sum);
if(sum[FOX]>1) // если лис больше
return (new fox(row,col)); // добавляем Лис
else if(sum[RABBIT]>1) // если Кроликов больше
return (new rabbit(row,col));//добавляются кролики
else if(sum[GRASS])
return (new grass(row,col));// третьими добавляются растения
else
return (new empty(row,col));// иначе пусто
}
void init(world w)
{
int i,j;
for(i=0;i<N;++i)
for(j=0;j<N;++j)
w[i][j]=new empty(i,j);
}
// генерация исходной модели мира
void gener(world w)
{
int i,j;
for(i=0;i<N;++i)
for(j=0;j<N;++j)
{
if(i%2==0 && j%3==0)
w[i][j]=new fox(i,j);
else if(i%3==0 && j%2==0)
w[i][j]=new rabbit(i,j);
else
if(i%5==0)
w[i][j]=new grass(i,j);
else w[i][j]=new empty(i,j);
}
}
void pr_state(world w)
{
int i,j;
for(i=0;i<N;++i)
{
cout<<endl;
for(j=0;j<N;++j)
w[i][j]->print();
}
cout << endl;
}
// новый world w_new рассчитывается из старого world w_old
void update(world w_new, world w_old)
{
int i,j;
for(i=0;i<N;++i)
for(j=0;j<N;++j)
w_new[i][j]=w_old[i][j]->next(w_old);
}
// очистка мира
void dele(world w)
{
int i,j;
for(i=1;i<N-1;++i)
for(j=1;j<N-1;++j) delete(w[i][j]);
}
int main()
{
world odd,even;
int i;
init(odd);
init(even);
gener(even); // генерация начального мира
cout<<"1 цикл жизни модели"<<endl;
pr_state(even); // вывод сгенерированной модели
for(i=0;i<CYCLES-1;++i) //цикл моделирования
{
getch();
cout<<i+2<<" цикл жизни модели"<<endl;
if(i%2)
{
update(even,odd); // создание even модели из odd модели
pr_state(even); // вывод сгенерированной модели even
dele(odd); // удаление модели odd
}
else
{
update(odd,even); // создание odd модели из even модели
pr_state(odd); // вывод сгенерированной модели odd
dele(even); // удаление модели even
}
}
return 1;
}