SSブログ
English Version

PIC24FJ64GAでGAME言語(その4) [PIC]

 ノスタルジックなGAME言語ですが、インターネット上でソースを探してもあまり見つからないですね
 GAME言語関連のファイルの多くを8インチのディスクに保存していたのですが、今となっては8インチのディスクのアクセス環境がありません orz

 そこで同様にノスタルジックな ライフゲーム を作ってみました。
 シリアル接続でのキャラクタ表示なので更にノスタルジックさをかもし出しますw
 初期パターンは乱数で生成していて起動の度に変化します。多くの場合はすぐに絶滅したり定常パターンになってしまいますが、運がよければ?長い世代に渡って変化し続けます。

表示例
   515 generation
..................................................
........##.......##...............................
.......#..#.....#..#..............................
........##.......##..................##...........
.....................................##...........
.............#....................................
............#.#...................................
............#.#.................##................
.............#..........#.......##............###.
........................#.........................
.................##...#..#...#..............#.....
.................##...###....#..............#.....
.............#..........##....#.............#.....
............#.#......###.##.......................
............#.#......#............................
.............#....................................



 ライフゲームソース(GAME言語)
1' Life Game 2015/08/31 by skyriver
10 X=50 Y=16
12 T=0
20 S=& CNT=X*Y+S
30 $=$1B "[2J"
40 I=X*Y-1 @ S:I)=0 CNT:I)=0 I=I-1 @=(I<0)
50 I=0,X*Y/20
60  A=('X/2)+(X/4) B=('Y/2)+(Y/4) S:X*B+A)=1
70 @=I+1
100 @
110  $=$1B "[0;0H"
120  T=T+1 ?(6)=T " generation"/
130  B=0,Y-1
140   A=0,X-1
150    Z="." ;=S:X*B+A)<>0 Z="#" !=1000
160    $=Z
170   @=A+1
180   /
190  @=B+1
200  I=0,X*Y-1
210   Z=CNT:I) CNT:I)=0
220   ;=(Z<2)|(Z>3) S:I)=0
230   ;=Z=3 S:I)=1
240  @=I+1
250 @=(0)
260 #=-1
1000' count up around cell
1010 E=B-1,B+1
1020  G=%((E+Y)/Y)
1030  D=A-1,A+1
1040   F=%((D+X)/X)
1050   CNT:X*G+F)=CNT:X*G+F)+1
1060  @=D+1+(E=B)
1070 @=E+1
1080 ]

★2015/08/31 プログラムを短縮化

★2015/09/02 追記
 ライフゲームのパターン変化は面白いのでつい見入ってしまいますが、上記のpicでのライフゲームは1世代の更新が約1秒弱なので長寿のパターンを見ていると結構時間が掛かります。
 そこでperlで書き直してみました。Windows上のCygwin環境で動かしたところ、256x70のセル数で1秒当たり100世代程度(PCの構成にも依存しますが)の更新になりました。init()内の最初にあるセル数設定部分を調整して遊んでみてください。
★2015/09/04 追記
 更新が早すぎて細部が見えないので 100ms のスリープを入れました。

 ライフゲームソース(perl)
#!/usr/bin/perl
# Life Game 2015/09/04 by skyriver
#

use strict;
use warnings;
use Time::HiRes 'sleep';

my ($SizeX, $SizeY);
my @Cnt;
my @Life;
my ($X,$Y);

init();
main();
exit( 0 );


sub init {
    $SizeX = 79;
    $SizeY = 30;
    for( $Y = 0 ; $Y < $SizeY ; $Y++ ) {
        for( $X = 0 ; $X < $SizeX ; $X++ ) {
            $Cnt[$Y][$X] = 0;
            $Life[$Y][$X] = 0;
        }
    }
    for( my $i = 0 ; $i < ($SizeX * $SizeY) / 20 ; $i++ ) {
        $X = rand( $SizeX / 2 ) + $SizeX / 4;
        $Y = rand( $SizeY / 2 ) + $SizeY / 4;
        $Life[$Y][$X] = 1;
    }
    printf( "\x1b[2J" );    # clear console
}


sub main {
    my ($gen,$mark,$count);

    for( ; ; ) {
        printf( "\x1b[0;0H" );  # move cursor to home
        printf( "%7d generation\n", ++$gen );
        for( $Y = 0 ; $Y < $SizeY ; $Y++ ) {
            for( $X = 0 ; $X < $SizeX ; $X++ ) {
                if( $Life[$Y][$X] == 0 ) {
                    $mark = ".";
                } else {
                    $mark = "#";
                    inc();
                }
                printf( $mark );
            }
            printf( "\n" );
        }
        for( $Y = 0 ; $Y < $SizeY ; $Y++ ) {
            for( $X = 0 ; $X < $SizeX ; $X++ ) {
                $count = $Cnt[$Y][$X];
                $Cnt[$Y][$X] = 0;       # clear counter
                if( $count < 2 ) {
                    $Life[$Y][$X] = 0;
                }
                elsif( $count == 3 ) {
                    $Life[$Y][$X] = 1;
                }
                elsif( $count > 3 ) {
                    $Life[$Y][$X] = 0;
                }
            }
        }
        sleep( 0.1 );
    }
}

# count up around cell($X,$Y)
sub inc {
    my ($xx,$yy,$tx,$ty);

    for( $yy = $Y - 1 ; $yy <= $Y+1 ; $yy++ ) {
        $ty = $yy;
        if( $ty < 0 ) {
            $ty += $SizeY;
        }
        elsif( $ty >= $SizeY ) {
            $ty -= $SizeY;
        }
        for( $xx = $X - 1 ; $xx <= $X+1 ; $xx += 1 + ($yy == $Y) ) {
            $tx = $xx;
            if( $tx < 0 ) {
                $tx += $SizeX;
            }
            elsif( $tx >= $SizeX ) {
                $tx -= $SizeX;
            }
            $Cnt[$ty][$tx]++;
        }
    }
}


★2016/02/11 追記
 マイコン用に開発した独自言語でのライフゲーム(定常状態で再スタート機能付き)

 ライフゲームソース(picle
# Life Game in picle language
# by skyriver 2016/02/02

var SizeX,SizeY;
var _Cnt,_Life;
var X,Y;
var Gen;

proc Clear() {
    var i;
    Gen = 0;
    for ( i = SizeX*SizeY-1; i >= 0; i=i-1 ) {
        _Cnt[i] = 0;
        _Life[i] = 0;
    }
    for ( i = SizeX*SizeY/16; i > 0; i=i-1 ) {
        X = Rand_(SizeX/2) + SizeX/4;
        Y = Rand_(SizeY/2) + SizeY/4;
        _Life[Y*SizeX+X] = 1;
    }
    PrnChar_($1B);  # clear console
    PrnStr_("[2J");
}

proc Init() {
    SizeX = 50;
    SizeY = 16;
    _Cnt = Array_;
    _Life = Array_(SizeX*SizeY/2);
    Clear();
}

proc Inc() {
    var xx,yy,ytmp,pos;
    for ( yy=Y-1; yy<=Y+1; yy=yy+1 ) {
        ytmp = (yy+SizeY)%SizeY*SizeX;
        for ( xx=X-1; xx<=X+1; xx=xx+1+(yy=Y) ) {
            pos = ytmp+(xx+SizeX)%SizeX;
            _Cnt[pos] = _Cnt[pos]+1;
        }
    }
}

proc main() {
    var mark,count,pos;
    var flg,flgb,scnt;
    Seed_(123);
    Init();
    scnt = 0;
    do {
        Gen = Gen+1;
        PrnChar_($1B);  # move cursor to home
        PrnStr_("[0;0H");
        PrnDecF_(Gen,5);
        PrnStr_(" generation¥n");
        flg = 0;
        for ( Y=0; Y<SizeY; Y=Y+1 ) {
            for ( X=0; X<SizeX; X=X+1 ) {
                if (_Life[Y*SizeX+X]=0 ) {
                    mark = '.';
                } else {
                    mark = '#';
                    Inc();
                    flg = flg+1;
                }
                PrnChar_(mark);
            }
            PrnStr_("¥n");
        }
        for ( pos=SizeY*SizeX-1; pos>=0; pos=pos-1 ) {
            count = _Cnt[pos];
            _Cnt[pos] = 0;
            if (count=3) {
                _Life[pos]=1;
            } else {
                if (count<>2) {
                    _Life[pos]=0;
                }
            }
        }
        if ( (scnt>5)|(flg=0) ) {
            Clear();
            scnt = 0;
            flg = -1;
        } else {
            if ( Gen%12=0 ) {
                if (flg=flgb ) {
                    scnt = scnt+1;
                } else {
                    flgb = flg;
                    scnt = 0;
                }
            }
        }
    } while (1);
}


[TOP] [ 前へ ] 連載記事 [ 次へ ]
nice!(0)  コメント(0)  トラックバック(3) 
共通テーマ:趣味・カルチャー

nice! 0

コメント 0

コメントを書く

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

トラックバック 3