ライフゲームの絶滅
Posted: 2008年10月26日(日) 18:10
数日前からライフゲームを作っているのですが、
初期の生物数をいくら増やしても絶対に絶滅してしまいます。
条件が厳しすぎるのか、あるいは、コードが
間違っているのかもわかりませんが、
その点についてのご指摘のほどを
お願いします。
サンプルにもライフゲームがありましたが、
api?を使わずに作成したいので、
その点を考慮してくださると嬉しいです。
試行錯誤中のソースのため見ずらいです。
コメントでどうにか理解してもらえたら
よいのですが…
//Aの周囲には2つのセルがある場合
//Aにセルがあるなら次の世代もセルがあり、ないなら次の世代もない。
//Aの周囲には3つのセルがある場合
//Aにセルがあってもなくても次の世代にはセルが発生する。
//それ以外の場合
//次の世代にはセルが消滅する。
#include <stdio.h>
#include <time.h>
#include <string.h>
#include <stdlib.h>
#define AT_FIRST 30//初期数
#define TATE 15 //縦のマス数
#define YOKO 15 //横のマス数
int hantei(int x,int y);//周囲の数判定関数
int sleep(unsigned long x);//時間経過を待つ
void cpu(int x,int y,int kosuu);//書き換え処理中枢
void write0(int x,int y);//0に書き換え
void write1(int x,int y);//1に書き換え
void output(void);//画面への表示
int field[TATE + 2][YOKO + 2];
int fieldnow[TATE + 2][YOKO + 2];
int main(void)
{
int k,j;
int i = 0;
int kakuninT,kakuninY;
srand((unsigned)time(NULL));
/*
//2の枠設定
for(k = 0;k <= YOKO;k++){
fieldnow[0][k] = 2;
fieldnow[k][0] = 2;
}
for(k = 0;k <= TATE;k++){
fieldnow[TATE][k] = 2;
fieldnow[k][YOKO] = 2;
}
*/
//初期の表示
do{
kakuninT = ((rand() + (TATE)) % (TATE) + 1);
kakuninY = ((rand() + (YOKO)) % (YOKO) + 1);
//同一のがないか確認
if(fieldnow[kakuninT][kakuninY] == 0){
fieldnow[kakuninT][kakuninY] = 1;
i++;
}
}while(i != AT_FIRST);
//ここから繰り返す
do{
output();
//コピー
for(i = 0;i <= TATE + 2;i++){
for(j = 0;j <= YOKO + 2;j++){
field[j] = fieldnow[j];
}
}
for(i = 1;i < TATE + 2;i++){
for(j = 1;j < YOKO + 2;j++){
cpu(i,j,hantei(i,j));
}
}
printf("\n");
sleep(1000);
system("cls");
}while(1);
return 0;
}
int hantei(int x,int y)
{
int kosuu = 0;
//処理
if(field[x][y] != 2){
if(field[x--][y--] == 1)
kosuu++;
if(field[x][y--] == 1)
kosuu++;
if(field[x++][y--] == 1)
kosuu++;
if(field[x--][y] == 1)
kosuu++;
if(field[x][y] == 1)
kosuu++;
if(field[x++][y] == 1)
kosuu++;
if(field[x--][y++] == 1)
kosuu++;
if(field[x][y++] == 1)
kosuu++;
if(field[x++][y++] == 1)
kosuu++;
}
return kosuu;
}
void cpu(int x,int y,int kosuu)
{
if(kosuu == 3){
write1(x,y);
}else{
if(kosuu != 2){
write0(x,y);
}
}
return;
}
void write0(int x,int y)
{
fieldnow[x][y] = 0;
}
void write1(int x,int y)
{
fieldnow[x][y] = 1;
}
int sleep(unsigned long x)
{
clock_t c,s = clock();
do{
if((c = clock()) == (clock_t)-1)//エラー判定
return 0;
}while(1000UL * (c - s) / CLOCKS_PER_SEC < x);
return 1;
}
void output(void)
{
int x,y;//座標
for(x = 0;x <= TATE + 2;x++){
for(y = 0;y <= YOKO + 2;y++){
switch(fieldnow[x][y]){
case 0:
printf("□");
break;
case 1:
printf("■");
break;
case 2:
printf("◆");
break;
}
}
printf("\n");
}
}
初期の生物数をいくら増やしても絶対に絶滅してしまいます。
条件が厳しすぎるのか、あるいは、コードが
間違っているのかもわかりませんが、
その点についてのご指摘のほどを
お願いします。
サンプルにもライフゲームがありましたが、
api?を使わずに作成したいので、
その点を考慮してくださると嬉しいです。
試行錯誤中のソースのため見ずらいです。
コメントでどうにか理解してもらえたら
よいのですが…
//Aの周囲には2つのセルがある場合
//Aにセルがあるなら次の世代もセルがあり、ないなら次の世代もない。
//Aの周囲には3つのセルがある場合
//Aにセルがあってもなくても次の世代にはセルが発生する。
//それ以外の場合
//次の世代にはセルが消滅する。
#include <stdio.h>
#include <time.h>
#include <string.h>
#include <stdlib.h>
#define AT_FIRST 30//初期数
#define TATE 15 //縦のマス数
#define YOKO 15 //横のマス数
int hantei(int x,int y);//周囲の数判定関数
int sleep(unsigned long x);//時間経過を待つ
void cpu(int x,int y,int kosuu);//書き換え処理中枢
void write0(int x,int y);//0に書き換え
void write1(int x,int y);//1に書き換え
void output(void);//画面への表示
int field[TATE + 2][YOKO + 2];
int fieldnow[TATE + 2][YOKO + 2];
int main(void)
{
int k,j;
int i = 0;
int kakuninT,kakuninY;
srand((unsigned)time(NULL));
/*
//2の枠設定
for(k = 0;k <= YOKO;k++){
fieldnow[0][k] = 2;
fieldnow[k][0] = 2;
}
for(k = 0;k <= TATE;k++){
fieldnow[TATE][k] = 2;
fieldnow[k][YOKO] = 2;
}
*/
//初期の表示
do{
kakuninT = ((rand() + (TATE)) % (TATE) + 1);
kakuninY = ((rand() + (YOKO)) % (YOKO) + 1);
//同一のがないか確認
if(fieldnow[kakuninT][kakuninY] == 0){
fieldnow[kakuninT][kakuninY] = 1;
i++;
}
}while(i != AT_FIRST);
//ここから繰り返す
do{
output();
//コピー
for(i = 0;i <= TATE + 2;i++){
for(j = 0;j <= YOKO + 2;j++){
field[j] = fieldnow[j];
}
}
for(i = 1;i < TATE + 2;i++){
for(j = 1;j < YOKO + 2;j++){
cpu(i,j,hantei(i,j));
}
}
printf("\n");
sleep(1000);
system("cls");
}while(1);
return 0;
}
int hantei(int x,int y)
{
int kosuu = 0;
//処理
if(field[x][y] != 2){
if(field[x--][y--] == 1)
kosuu++;
if(field[x][y--] == 1)
kosuu++;
if(field[x++][y--] == 1)
kosuu++;
if(field[x--][y] == 1)
kosuu++;
if(field[x][y] == 1)
kosuu++;
if(field[x++][y] == 1)
kosuu++;
if(field[x--][y++] == 1)
kosuu++;
if(field[x][y++] == 1)
kosuu++;
if(field[x++][y++] == 1)
kosuu++;
}
return kosuu;
}
void cpu(int x,int y,int kosuu)
{
if(kosuu == 3){
write1(x,y);
}else{
if(kosuu != 2){
write0(x,y);
}
}
return;
}
void write0(int x,int y)
{
fieldnow[x][y] = 0;
}
void write1(int x,int y)
{
fieldnow[x][y] = 1;
}
int sleep(unsigned long x)
{
clock_t c,s = clock();
do{
if((c = clock()) == (clock_t)-1)//エラー判定
return 0;
}while(1000UL * (c - s) / CLOCKS_PER_SEC < x);
return 1;
}
void output(void)
{
int x,y;//座標
for(x = 0;x <= TATE + 2;x++){
for(y = 0;y <= YOKO + 2;y++){
switch(fieldnow[x][y]){
case 0:
printf("□");
break;
case 1:
printf("■");
break;
case 2:
printf("◆");
break;
}
}
printf("\n");
}
}