ライフゲーム [プログラミング]
ライフゲームといってもボードゲームの人生ゲームではなく、昔の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);
}
動かすとこんな感じ。
ずっと見ていられます。
2016-08-11 16:36
nice!(0)
コメント(0)
トラックバック(0)
コメント 0