SSブログ

ライフゲーム [プログラミング]

ライフゲームといってもボードゲームの人生ゲームではなく、昔のUNIXには/usr/game/lifeとしてインストールされていたもののことです。

ふと思い立って、Cで実装してみました。ネットに溢れている実装例は見ていないので、正解ではないでしょうが、それっぽく動きます。ncursesを試しに使ってみたらきれいにできました。



//
// life
//

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <unistd.h>
#include <ncurses.h>
#include <string.h>

#define XSIZE 40
#define YSIZE 20
#define DIVBY 5
#define USLEEP 500000
#define MESSAGE "hit any key to exit"

int prev[XSIZE][YSIZE], post[XSIZE][YSIZE];

// initialize array
void init_array() {
int i, j, r;

srand( (unsigned)time( NULL ) );

for ( i = 0; i < XSIZE; i++ ) {
for ( j = 0; j < YSIZE; j++ ) {
r = rand() % DIVBY;
if ( r != 0 ) {
prev[i][j] = 0;
} else {
prev[i][j] = 1;
}
}
}
}

// judge dead or alive
int dora( int sum, int now ) {
if ( now == 1 ) {
if ( sum == 2 || sum == 3 ) {
return(1);
} else {
return(0);
}
} else {
if ( sum == 3 ) {
return(1);
} else {
return(0);
}
}
}

// change generation
void chgen() {
int i, j;
int z;

for ( i = 0; i < XSIZE; i++ ) {
for ( j = 0; j < YSIZE; j++ ) {
if ( i == 0 && j == 0 ) {
z = prev[i+1][j] + prev[i+1][j+1] + prev[i][j+1];
} else if ( i == XSIZE-1 && j == YSIZE-1 ) {
z = prev[i-1][j] + prev[i-1][j-1] + prev[i][j-1];
} else if ( i == 0 ) {
z = prev[i][j-1] + prev[i][j+1] \
+ prev[i+1][j-1] + prev[i+1][j] + prev[i+1][j+1];
} else if ( i == XSIZE-1 ) {
z = prev[i][j-1] + prev[i][j+1] \
+ prev[i-1][j-1] + prev[i-1][j] + prev[i-1][j+1];
} else if ( j == 0 ) {
z = prev[i-1][j] + prev[i+1][j] \
+ prev[i-1][j+1] + prev[i][j+1] + prev[i+1][j+1];
} else if ( j == YSIZE-1 ) {
z = prev[i-1][j] + prev[i+1][j] \
+ prev[i-1][j-1] + prev[i][j-1] + prev[i+1][j-1];
} else {
z = prev[i-1][j-1] + prev[i-1][j] \
+ prev[i-1][j+1] + prev[i][j-1] + prev[i][j+1] \
+ prev[i+1][j-1] + prev[i+1][j] + prev[i+1][j+1];
}
post[i][j] = dora(z, prev[i][j]);
}
}
}

// copy array
void copy_array() {
int i, j;

for ( i = 0; i < XSIZE; i++ ) {
for ( j = 0; j < YSIZE; j++ ) {
prev[i][j] = post[i][j];
}
}
}

// judge loop
int isSilence() {
int i, j;
int z = 0;

for ( i = 0; i < XSIZE; i++ ) {
for ( j = 0; j < YSIZE; j++ ) {
if ( prev[i][j] != post[i][j] ) {
z++;
}
}
}
return(z);
}

// main routine
int main() {
int i, j;
int x, y, w, h;
int gen;

// initialize screen
initscr();
getmaxyx( stdscr, h, w );

// initialize array
init_array();

erase();
for (;;) {
gen++;
x = w / 2;
y = ( h - YSIZE ) / 2 - 2;
move(y, x);
printw("%d", gen);
for ( i = 0; i < XSIZE; i++ ) {
for ( j = 0; j < YSIZE; j++ ) {
// display
x = ( w - XSIZE ) / 2 + i;
y = ( h - YSIZE ) / 2 + j;
move(y, x);
if ( prev[i][j] == 0 ) {
addch('.');
} else {
addch('@');
}
}
}
refresh();

// change generation
chgen();

// jedge silence
if ( 0 == isSilence() ) {
break;
}

copy_array();
usleep( USLEEP );
}

x = w / 2 - strlen( MESSAGE ) / 2;
y = h / 2 + YSIZE / 2 + 2;
move(y, x);
printw( MESSAGE );

timeout(-1);
getch();

endwin();
return(0);
}



動かすとこんな感じ。

life.png

ずっと見ていられます。


nice!(0)  コメント(0)  トラックバック(0) 

nice! 0

コメント 0

コメントを書く

お名前:
URL:
コメント:
画像認証:
下の画像に表示されている文字を入力してください。

トラックバック 0

この広告は前回の更新から一定期間経過したブログに表示されています。更新すると自動で解除されます。