Life游戏
作者:Ackarlix
Life游戏是一个模拟游戏,并没有真正的玩家。Life游戏在一个没有边界的矩形网格中展开,其中的各个元胞(即每一个格子,英文为cell)都可以北一个有机体占用或者处于空闲状态。被占用的元胞处于alive(生)状态,为被占用的元胞处于dead(死)状态,元胞状态从一代向另一代转换,是否为alive状态主要取决于与其相邻的元胞alive状态的数量,其规则如下:
(1)与某一元胞相邻的元胞是指与该元胞垂直相连、水平相连,或是通过对角线相连的元胞。
(2)如果某元胞状态为alive,但与其相邻的元胞没有一个处于alive状态,或者是与其相邻的元胞仅有一个处于alive状态,那么在下一代中该元胞就因为孤立而转变为dead状态。
(3)如果某元胞状态为alive,并且与其相邻的状态为alive的元胞数量为4个或者更多,那么在下一代中该元胞由于过分拥塞而转变为dead状态。
(4)如果某个状态为alive的元胞有2个或者3个相邻的状态为alive的元胞,那么在下一代中该元胞状态仍为alive。
(5)如果某元胞状态为dead,并且与其相邻的状态为alive的元胞数量恰好为3个,那么在下一代中该元胞状态将转变为alive。其他类型的所有状态为dead的元胞(与其相邻的状态为alive的元胞数量为1、2、4、5、6、7、8ge)状态保持不变。
(6)每一代所有的生(状态转变为alive)和死(状态转变为dead)发生在相同的时间。这样一个正在转变为dead状态的元胞将有助于另外一个元胞转变为alive状态,但是通过降低拥塞并不能阻止其他元胞转变为dead状态。同时,正在转变为alive状态的元胞不会保持或者取消上一代中状态为alive的元胞。
演示代码:
#include <iostream>
#include <iomanip>
using namespace std;
void Change_Na(int i, int j);
void Change_Nc(int i, int j);
typedef struct
{
char L;
int n;
}Live;
Live Elem[20][39];
Live Temp[20][39];
void TemptoElem()
{
for (int i=0; i<20; ++i)
{
for (int j=0; j<39; ++j)
{
Elem[i][j].L = Temp[i][j].L;
Elem[i][j].n = Temp[i][j].n;
}
}
}
void ElemtoTemp()
{
for (int i=0; i<20; ++i)
{
for (int j=0; j<39; ++j)
{
Temp[i][j].L = Elem[i][j].L;
Temp[i][j].n = Elem[i][j].n;
}
}
}
void Liveinit()
{
for (int i=0; i<20; i++)
{
for (int j=0; j<39; j+=2)
{
Temp[i][j].n = 0;
Temp[i][j].L = '.';
}
}
TemptoElem(); //将Temp[i][j]复制给Elem[i][j]
}
void Insert()
{
cout << "How many member do you want to input?/n";
int n;
cin >> n;
int m=1;
while (m<=n)
{
int x, y;
cin >> x >> y;
if (x>20 || y>20)
{
cout << "Your nember is wrong!/n";
goto Loop;
}
if (Elem[x-1][2*(y-1)].L != '*') //goto Loop;
{
Temp[x-1][2*(y-1)].L = '*';
Change_Na(x-1, 2*(y-1));
}
TemptoElem();
++m;
}
}
void Print_N()
{
for (int i=0; i<21; i++) cout << setw(2) << i;
cout << endl;
for (int k=0; k<20; ++k)
{
cout << setw(2) << k+1 << " ";
for (int l=0; l<39; ++l)
{
if (l%2 == 0) cout << Elem[k][l].n;
else cout << ' ';
}
cout << endl;
}
}
void Print_L()
{
for (int i=0; i<21; i++) cout << setw(2) << i;
cout << endl;
for (int k=0; k<20; ++k)
{
cout << setw(2) << k+1 << " ";
for (int l=0; l<39; ++l) cout << Elem[k][l].L;
cout << endl;
}
}
void Change_Na(int i, int j)
{
for (int n=0; n<3 && i+1-n>=0; n++)
{
for (int m=0; m<5 && j+2-m>=0; m+=2)
{
if (n==1 && m==2) continue;
Temp[i+1-n][j+2-m].n += 1;
}
}
}
void Change_Nc(int i, int j)
{
for (int n=0; n<3 && i+1-n>=0; n++)
{
for (int m=0; m<5 && j+2-m>=0; m+=2)
{
if (n==1 && m==2) continue;
if (Elem[i+1-n][j+2-m].n != 0) Temp[i+1-n][j+2-m].n -= 1;
}
}
}
void Live_Order()
{
while (1)
{
char Check;
cin >> Check;
if (Check == 'e') break;
for (int i=0; i<20; i++)
{
for (int j=0; j<39; j+=2)
{
switch (Elem[i][j].n)
{
case 0:
if (Elem[i][j].L == '*')
{
Temp[i][j].L = '.';
Change_Nc(i, j);
}
break;
case 1:
if (Elem[i][j].L == '*')
{
Temp[i][j].L = '.';
Change_Nc(i, j);
}
break;
case 2:
break;
case 3:
if (Elem[i][j].L == '*') continue;
if (Elem[i][j].L == '.')
{
Temp[i][j].L = '*';
Change_Na(i, j);
}
break;
case 4:
if (Elem[i][j].L == '*')
{
Temp[i][j].L = '.';
Change_Nc(i, j);
}
break;
case 5:
if (Elem[i][j].L == '*')
{
Temp[i][j].L = '.';
Change_Nc(i, j);
}
break;
case 6:
if (Elem[i][j].L == '*')
{
Temp[i][j].L = '.';
Change_Nc(i, j);
}
break;
case 7:
if (Elem[i][j].L == '*')
{
Temp[i][j].L = '.';
Change_Nc(i, j);
}
break;
case 8:
if (Elem[i][j].L == '*')
{
Temp[i][j].L = '.';
Change_Nc(i, j);
}
break; //Can't drop "Break".
}
}
}
TemptoElem();
Print_L();
}
}
void Print()
{
cout << "What do you want to print? (N):Prtint_N() (L):Print_L()/n";
char Key;
cin >> Key;