ライフゲーム

ライフゲームのルール

誕生:3つの生命体に囲まれた場所には生命が誕生して増える。(食べ物に余裕があると増える)

維持:2つか3つの生命体に囲まれた場所にいる生命体は生き残る。(食べ物が生命を維持出来るだけある)

死滅:それ以外の生命体は死ぬ。(多すぎると食べ物が不足するし、少ないと繁殖できない)

課題11-1 ライフゲーム(1)

生命のいるセルをo、いないセルをスペースで表しています。

プログラム名 k1101.c

 0: /* ライフゲーム(1) k1101.c */
 1: #include <stdio.h>
 2: #include <string.h>
 3: #define COLS0 41
 4: #define COLS  40
 5: #define LINES 20
 6: char now[LINES][COLS0]=
 7: {
 8: "                                        ",
 9: "                                        ",
10: "                                        ",
11: "                                        ",
12: "               ooooo                    ",
13: "                                        ",
14: "                                        ",
15: "                                        ",
16: "            o                           ",
17: "           o                            ",
18: "           ooo                          ",
19: "                       oooooo           ",
20: "                       oooooo           ",
21: "                  oo                    ",
22: "                                        ",
23: "                                        ",
24: "                                        ",
25: "                           ooo          ",
26: "                                        ",
27: "                                        "
28: };
29: char nxt[LINES][COLS0];
30: int setnxt()
31: {
32:   int x,y,i,j,jb,ib,je,ie,alivect;
33:   char alive='o';
34:   char dead =' ';
35:   int ylast=LINES-1;
36:   int xlast=COLS-1;
37:   for(y=0; ylast>=y; y++){
38:     for(x=0; xlast>=x; x++){
39:       jb = y-1;
40:       je = y+1;
41:       ib = x-1;
42:       ie = x+1;
43:       if(y==0)   {jb = 0;}
44:       if(y>ylast){je = ylast;}
45:       if(x==0)   {ib = 0;}
46:       if(x>xlast){ie = xlast;}
47:       alivect=0;
48:       for(j=jb; je>=j; j++){
49:          for(i=ib; ie>=i; i++){
50:             if (now[j][i]==alive) alivect++;
51:          }
52:       }
53:       if(now[y][x]==alive){
54:          alivect--;
55:          if(alivect==2 || alivect==3) {
56:               nxt[y][x]=alive;
57:          }
58:          else {
59:               nxt[y][x]=dead;
60:          }
61:       }
62:       else{
63:          if(alivect==3) {nxt[y][x]=alive;} else {nxt[y][x]=dead;}
64:       }
65:     }/* x */
66:     nxt[y][COLS0-1]='\0';
67:   }/* y */
68:   return 0;
69: }
70: 
71: int main()
72: { 
73:    int ct,y;
74:    char a;
75:    for(ct=0;1000>ct;ct++){
76:       printf("\e[0;0H");   /* カーソルを左上に \e はエスケープ*/
77:       for(y=0;LINES>y;y++){
78:          printf("%s*\n",now[y]);
79:       }
80:       if( setnxt() ) return 1;
81:       for(y=0;LINES>y;y++){
82:          strcpy(now[y],nxt[y]);
83:       }
84:       printf("%d",ct);
85:       sleep(1);
86:       /*scanf("%c", &a);*/
87:    }
88:    return 0;
89: }

k1101.c のダウンロード

実行結果 k1101.c

実行結果はこうなります。

                 o                      *
                 o                      *
                 o                      *
                                        *
             ooo   ooo                  *
                                        *
                 o                      *
                 o                      *
                 o                      *
                                        *
                                        *
                                        *
                                        *
       o o                              *
       oo                               *
        o                               *
                            o           *
                            o           *
                            o           *
                                        *
世代数:17   ←世代数(何回繰り返したか)
終了するには [Ctrl]+[c] を押してください。
        Ctrlキーを押しながら c を押す

課題11-2 ライフゲーム(2)

半角英字の表示だと升目が縦長になるので、全角の文字を使ってみました。結果の表示部分のみ違っています。

プログラム名 k1102.c

 1: /* ライフゲーム(2) k1102.c */
 2: #include <stdio.h>
 3: #include <string.h>
 4: #define COLS0 41
 5: #define COLS  40
 6: #define LINES 30
 7: char alive='o';
 8: char dead =' ';
 9: char now[LINES][COLS0]=
10: {
11: "                                        ",
12: "                                        ",
13: "                                        ",
14: "                                o       ",
15: "                                o       ",
16: "                                o       ",
17: "                                o       ",
18: "               ooooo            o       ",
19: "                                        ",
20: "                                        ",
21: "                                        ",
22: "            o                           ",
23: "           o                            ",
24: "           ooo          o    o          ",
25: "                   oooooooooooooooo     ",
26: "                                        ",
27: "                                        ",
28: "                                        ",
29: "                                        ",
30: "                                        ",
31: "                                        ",
32: "                                        ",
33: "                         ooooo          ",
34: "                                        ",
35: "                                        ",
36: "                                        ",
37: "                                        ",
38: "                                        ",
39: "                                        ",
40: "                                        "
41: };
42: char nxt[LINES][COLS0];
43: int setnxt()
44: {
45:   int x,y,i,j,jb,ib,je,ie,alivect;
46:   int ylast=LINES-1;
47:   int xlast=COLS-1;
48:   for(y=0; ylast>=y; y++){
49:     for(x=0; xlast>=x; x++){
50:       jb = y-1;
51:       je = y+1;
52:       ib = x-1;
53:       ie = x+1;
54:       if(y==0)   {jb = 0;}
55:       if(y>ylast){je = ylast;}
56:       if(x==0)   {ib = 0;}
57:       if(x>xlast){ie = xlast;}
58:       alivect=0;
59:       for(j=jb; je>=j; j++){
60:          for(i=ib; ie>=i; i++){
61:             if (now[j][i]==alive) alivect++;
62:          }
63:       }
64:       if(now[y][x]==alive){
65:          alivect--;
66:          if(alivect==2 || alivect==3) {
67:               nxt[y][x]=alive;
68:          }
69:          else {
70:               nxt[y][x]=dead;
71:          }
72:       }
73:       else{
74:          if(alivect==3) {nxt[y][x]=alive;} else {nxt[y][x]=dead;}
75:       }
76:     }/* x */
77:     nxt[y][COLS0-1]='\0';
78:   }/* y */
79:   return 0;
80: }
81: 
82: int knjdisp()
83: {
84:   int x,y;
85:   char jalive[]="● ";
86:   //char jdead[] ="○ ";
87:   char jdead[] ="  ";
88:   int ylast=LINES-1;
89:   int xlast=COLS-1;
90:   printf("\e[0;0H");   /* カーソルを左上に */
91:   for(y=0; ylast>=y; y++){
92:     for(x=0; xlast>=x; x++){
93:        if(now[y][x]==alive) printf(jalive); else printf(jdead);
94:     }
95:     printf("|\n");
96:   }
97:   for(x=0; xlast>=x; x++){
98:     printf("— ");
99:   }
100:   printf("\n");
101: }
102: 
103: int main()
104: { 
105:    int ct,y;
106:    for(ct=0;1000>ct;ct++){
107:       /*printf("%c[0;0H",(char)0x1b);*/
108:       knjdisp();
109:       if( setnxt() ) return 1;
110:       for(y=0;LINES>y;y++){
111:          strcpy(now[y],nxt[y]);
112:       }
113:       printf("%d",ct);
114:       usleep(50000);  /* 0.5sec usleep :マイクロ秒(1/1000000秒)*/
115:       /*scanf("%c", &a);*/
116:    }
117:    return 0;
118: }

k1102.c のダウンロード

実行結果 k1102.c

実行結果はこうなります。

考察

初期状態と最終状態だけを示しました。最初が少し違うだけでも結果は大きく異なります。また、ルールを変更すれば結果が変わります。

シミュレーションはどういうルールを採用し、どういう初期状態から始めるかで結果が違いますから、実際の現象をシミュレートするにはよくよく研究し検証しなければなりません。コンピュータでシミュレーションをやっただけで結果を信用するのは危険です。

個数 初期状態 最終状態 説明
3 1,2個はすぐになくなりますが、3個は振動します。
4 この形で止まります。
5 再び振動します。
6 死に絶えます。始めの数が多くても最終的に広がるとは限りません。
7 この形で止まります。
8 この形で止まります。
9 再び振動します。

エディタで初期値の幅が揃っていないときは

デフォルトとして指定されているフォントは「固定幅」のはずですが、スペースは小さめに表示される様です。

「システムの固定幅フォントを使う」のチェックを外してから下のフォントをクリックして適当な「固定幅」フォントを選びます。 日本語フォントではPのついていないものが固定幅です。

この「geditの設定」を出すにはメニューから[編集]-[設定]-[フォントと色]と進みます。

聖愛中学高等学校
http://www.seiai.ed.jp/
Jan. 2012