Comment detail

ライフゲーム (Nested Flatten)
ぴこぴこ動くので、多分間違ってないかと(^ ^;
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
!変数宣言が必要
/*初期マップとは配列=,
"0,1,0,0,0,0,1,1,1,0
0,0,0,0,1,0,0,1,1,0
0,0,0,1,0,0,1,0,1,0
1,0,1,1,0,0,1,0,0,0
0,1,0,0,0,0,0,0,1,0
1,0,0,0,1,0,1,1,0,1
0,1,0,0,0,0,1,0,0,0
0,0,0,0,0,0,0,0,0,1
1,0,0,0,0,0,1,0,0,1
0,0,0,0,1,1,0,0,1,0"
wとは整数=9
hとは整数=9*/

初期マップとは配列=,
"0,0,0,0,0,0
0,0,0,1,1,0
0,0,0,1,1,0
0,1,1,0,0,0
0,1,1,0,0,0
0,0,0,0,0,0"

wとは整数=5
hとは整数=5
現マップとは配列=初期マップ
次マップとは配列
iとは整数
jとは整数
セル数とは整数
マップラベルとはラベル

マップラベル=現マップをマップ整形
1の間
    iで0からhまで繰り返す
        jで0からwまで繰り返す
            セル数=周囲セル数取得(現マップ,i,j,h,w)
            もし(現マップ[i,j]=0)ならば
                もし(セル数=3)ならば
                    次マップ[i,j]=1 #誕生
                違えば
                    次マップ[i,j]=0 #死亡
            違えば
                もし(セル数=2||セル数=3)ならば
                    次マップ[i,j]=1 #維持
                違えば
                    次マップ[i,j]=0 #死亡
    現マップ=次マップ
    マップラベル=現マップをマップ整形
    0.2秒待つ

●マップ整形(mapを)
    tmpとは文字列
    tmplineとは文字列
    mapを反復
        tmpline=対象の改行を""に置換
        tmpline=tmplineの0を" "に置換
        tmpline=tmplineの1を"■"に置換
        tmp=tmp&tmpline&改行
    tmpで戻る

●周囲セル数取得(map,y,x,h,w)
    nxとは整数
    nyとは整数
    countとは整数
    "{y-1},{x-1}
{y-1},{x}
{y-1},{x+1}
{y},{x-1}
{y},{x+1}
{y+1},{x-1}
{y+1},{x}
{y+1},{x+1}"を反復
        もし(対象[0,0]=-1)ならば
            ny=h
        違えば
            ny=対象[0,0]
        もし(対象[0,1]=-1)ならば
            nx=w
        違えば
            nx=対象[0,1]
        もし(map[ny,nx]=1)ならば
            count=count+1
    countで戻る
失敗しました。
全部貼らなきゃだった・・・

題意を取り違えてたっぽいので追加修正。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <time.h>

#define WIDTH  10
#define HEIGHT 10


int calc_life(int a[HEIGHT][WIDTH],int x,int y){
    int life;
    int x_l,x_r,y_u,y_d;
    y_u=(y+HEIGHT-1)%HEIGHT;
    y_d=(y+1)%HEIGHT;
    x_l=(x+WIDTH-1)%WIDTH;
    x_r=(x+1)%WIDTH;
            
    life= (a[y_u][x_l]&1)+(a[y_u][x]&1)+(a[y_u][x_r]&1)
         +(a[ y ][x_l]&1)              +(a[ y ][x_r]&1)
         +(a[y_d][x_l]&1)+(a[y_d][x]&1)+(a[y_d][x_r]&1);
    return life;
}
void next_gen(int a[HEIGHT][WIDTH]){
    int life;
    int x,y;
    for(y=0;y<HEIGHT;y++){
        for(x=0;x<WIDTH;x++){
            life=calc_life(a,x,y);

            if((life|(a[y][x]&1))==3) a[y][x]|=2;
        }
    }
    for(y=0;y<HEIGHT;y++){
        for(x=0;x<WIDTH;x++){
            a[x][y]>>=1;
        }
    }
}

void put_gen(int a[HEIGHT][WIDTH]){
    int x,y;
    for(y=0;y<HEIGHT;y++){
        for(x=0;x<WIDTH;x++){
            putchar('[');
            putchar(a[y][x]==1?'*':' ');
            putchar(']');
        }
            putchar('\n');
    }
}

void lifegame(int a[HEIGHT][WIDTH]){
    int gen=0;
    do{
        printf("T=%d\n",gen);
        put_gen(a);
        next_gen(a);
        gen++;
    }while(getch()==0x20);
}

void init_life(int a[HEIGHT][WIDTH]){
    int x,y;
    int count=0;
    
    for(y=0;y<HEIGHT;y++){
        for(x=0;x<WIDTH;x++){
            a[y][x]=0;
        }
    }

    srand(time(NULL));
    do{
        x=rand()/(RAND_MAX/WIDTH);
        y=rand()/(RAND_MAX/HEIGHT);
        if(calc_life(a,x,y)<=(2+(rand()/(RAND_MAX/2)))){
            a[y][x]=1;
            count++;
        }
    }while(count<((HEIGHT*WIDTH)*(2+(rand()/(RAND_MAX/2)))/10));
}

int main(){
    int a[HEIGHT][WIDTH];
    init_life(a);
    lifegame(a);
    
    return 0;
}
グダグダしてきましたが、Wikipediaによると"23/3"などというルール表記があるようなのでそれに対応。
世代スキップも追加。
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <time.h>

#define WIDTH  10
#define HEIGHT 10

/* セルの生死判定 */
int calc_life(int a[HEIGHT][WIDTH],int x,int y){
    int life;
    int x_l,x_r,y_u,y_d;
    y_u=(y+HEIGHT-1)%HEIGHT;
    y_d=(y+1)%HEIGHT;
    x_l=(x+WIDTH-1)%WIDTH;
    x_r=(x+1)%WIDTH;
            
    life= (a[y_u][x_l]&1)+(a[y_u][x]&1)+(a[y_u][x_r]&1)
         +(a[ y ][x_l]&1) /*注目セル */+(a[ y ][x_r]&1)
         +(a[y_d][x_l]&1)+(a[y_d][x]&1)+(a[y_d][x_r]&1);
    return life;
}

/* 世代の進行 */
void next_gen(int a[HEIGHT][WIDTH],char* rule){
    int life;
    int x,y;
    char* birth;
    char* ptr_rule;

    /* 誕生ルール検出 */
    birth=rule;
    while(*birth++!='/');
    
    /*生存・誕生判定*/
    for(y=0;y<HEIGHT;y++){
        for(x=0;x<WIDTH;x++){
            life=calc_life(a,x,y);
            
            if(a[y][x]&1){
                /*生存判定*/
                ptr_rule=rule;
                do{
                    if(life==*ptr_rule-'0') a[y][x]|=2;
                }while(*++ptr_rule!='/');
            }else{
                /*誕生判定*/
                ptr_rule=birth;
                do{
                    if(life==*ptr_rule-'0') a[y][x]|=2;
                }while(*++ptr_rule);
            }
        }
    }
    
    /* 次世代へ進行 */
    for(y=0;y<HEIGHT;y++){
        for(x=0;x<WIDTH;x++){
            a[x][y]>>=1;
        }
    }
}

/* 現世代の表示 */
void put_gen(int a[HEIGHT][WIDTH]){
    int x,y;
    for(y=0;y<HEIGHT;y++){
        for(x=0;x<WIDTH;x++){
            printf("[%c]",a[y][x]==1?'*':' ');
        }
        putchar('\n');
    }
}

/* ライフゲーム制御 */
void lifegame(int a[HEIGHT][WIDTH],char* rule){
    int gen=0;
    char c;
    int step;
    
    while(1){
        printf("T=%d\n",gen);
        put_gen(a);
        step=0;

        while(1){
            c=getche();
            if(c<'0'||'9'<c) break;
            step*=10;
            step+=c-'0';
        }
        if(c==0x1b) break;
        if(step==0&&(c==0x20||c==0x0d)) step=1;
        putchar('\n');
        while(step--){
            next_gen(a,rule);
            gen++;
        }
    }
}

/* ランダム初期値の設定 */
void init_life(int a[HEIGHT][WIDTH]){
    int x,y;
    int count=0;
    
    for(y=0;y<HEIGHT;y++){
        for(x=0;x<WIDTH;x++){
            a[y][x]=0;
        }
    }

    srand(time(NULL));
    do{
        x=rand()/(RAND_MAX/WIDTH);
        y=rand()/(RAND_MAX/HEIGHT);
        if(calc_life(a,x,y)<=(2+(rand()/(RAND_MAX/2)))){
            a[y][x]=1;
            count++;
        }
    }while(count<((HEIGHT*WIDTH)*(2+(rand()/(RAND_MAX/2)))/10));
}

int main(){
    int a[HEIGHT][WIDTH]={
/* 出題
        {0,1,0,0,0,0,1,1,1,0},
        {0,0,0,0,1,0,0,1,1,0},
        {0,0,0,1,0,0,1,0,1,0},
        {1,0,1,1,0,0,1,0,0,0},
        {0,1,0,0,0,0,0,0,1,0},
        {1,0,0,0,1,0,1,1,0,1},
        {0,1,0,0,0,0,1,0,0,0},
        {0,0,0,0,0,0,0,0,0,1},
        {1,0,0,0,0,0,1,0,0,1},
        {0,0,0,0,1,1,0,0,1,0}
/*/
//グライダー
        {0,0,0,0,0,0,0,0,0,0},
        {0,0,0,0,0,0,0,0,0,0},
        {0,0,0,0,0,0,0,0,0,0},
        {0,0,0,0,0,0,0,0,0,0},
        {0,0,0,1,0,0,0,0,0,0},
        {0,0,1,0,0,0,0,0,0,0},
        {0,0,1,1,1,0,0,0,0,0},
        {0,0,0,0,0,0,0,0,0,0},
        {0,0,0,0,0,0,0,0,0,0},
        {0,0,0,0,0,0,0,0,0,0},
/*/
        {0,0,0,0,0,0,0,0,0,0},
        {0,0,0,0,0,0,0,0,0,0},
        {0,0,0,1,0,0,0,0,0,0},
        {0,0,1,1,0,1,0,0,0,0},
        {0,0,0,1,0,1,0,0,0,0},
        {0,0,0,0,0,1,0,0,0,0},
        {0,0,0,0,0,0,1,0,0,0},
        {0,0,0,0,0,0,1,0,1,0},
        {0,0,0,0,0,0,0,0,0,0},
        {0,0,0,0,0,0,0,0,0,0},
//*/
    };
//    init_life(a);
    lifegame(a,"23/3");
//    lifegame(a,"23/36"); //HighLife?
    
    return 0;
}

すいません、配列が範囲を超える場合の処理を書いてませんでしたorz

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
●周囲セル数取得(map,y,x,h,w)
    nxとは整数
    nyとは整数
    countとは整数
    "{y-1},{x-1}
{y-1},{x}
{y-1},{x+1}
{y},{x-1}
{y},{x+1}
{y+1},{x-1}
{y+1},{x}
{y+1},{x+1}"を反復
        もし(対象[0,0]=-1)ならば,ny=h
        違えば,もし(対象[0,0]=h+1)ならば,ny=0
        違えば,ny=対象[0,0]
        もし(対象[0,1]=-1)ならば,nx=w
        違えば,もし(対象[0,1]=w+1)ならば,nx=0
        違えば,nx=対象[0,1]
        もし(map[ny,nx]=1)ならば
            count=count+1
    countで戻る

Index

Feed

Other

Link

Pathtraq

loading...