![見出し画像](https://assets.st-note.com/production/uploads/images/102551428/rectangle_large_type_2_4a69ca2f25a5d4ff39f3151a0dda501f.png?width=1200)
#01 ライフゲーム
プログラミングの勉強のため、一瞬fortranを勉強していた時に作成したものです。だいぶ前につくったものですが、面白かったので。
ライフゲームとは
1970年にケンブリッジ大のコンウェイが発明したセルオートマトン。初期条件を与えれば一定の規則で世代が進み、生と死を表すセルが更新されていく。Wikipediaわかりやすい
本を探すと以下のものくらいしか見つからなかった。気がする。
1974年にはTime誌が「ライフゲイムの大群が数百万ドルの貴重なコンピュータ時間を食ってしまっている」と苦言を呈したほど流行ったらしい。
代表的なパターン
白いセルが「生(1)」を、黒いセルが「死(0)」を表していて、初期条件を与えれば、あとは世代を追って一定規則でころころ変わる。
個人的にはたった5つの「生」でスタートして、ランダムそうな模様を展開するR pentominoが面白い。名前がついているのもまたいい。
![](https://assets.st-note.com/production/uploads/images/102549125/picture_pc_75b62ae77d8adaf37b740619ca7d4ca5.gif)
初期条件は以下のように与える。Nebulaの例。
![](https://assets.st-note.com/img/1681008538470-OB6dJeLtwy.png)
他にも例をいくつか。
![](https://assets.st-note.com/production/uploads/images/102549899/picture_pc_063fa6faf17555b6254b3bde8d358ed3.gif)
![](https://assets.st-note.com/production/uploads/images/102549948/picture_pc_5c0e2303abd1ee0bd4761a74bda03803.gif)
ソースコード
プログラムは以下の記事を大いに参考にさせていただいています。
Fortranで実装、gnuplotで描画しました。もうgnuplotなんて全然使ってない。。
描画領域を正方形にして、初期条件を乱数ではなく、Excelで作成した init_field.txt から読み込ませてます。境界の条件はcshiftとeoshiftを使い分けて、固定境界か周期境界かを選べるようにしました。
! Conway's Game of Life
module lifegame
implicit none
integer :: n
integer, allocatable :: field( : , : )
integer, allocatable :: neighbors( : , : )
contains
subroutine init_field( size )
integer, intent( in ) :: size
integer i
integer ios
n = size
allocate( field( n, n ) )
allocate( neighbors( n, n ) )
open(10, file="init_field.txt")
do i=0, n
read(10, *, iostat=ios) field
if (ios .lt. 0) exit
end do
close(10)
end subroutine init_field
subroutine print_field()
implicit none
integer :: i
do i = 1, n
write (*, '( * ( i0, :, " " ) )' ) field( :, i )
end do
end subroutine print_field
subroutine one_epoch
implicit none
integer :: dx, dy, i
neighbors = 0
do concurrent ( dx = -1 : 1, dy = -1 : 1 )
! 周期境界条件(cshift)
neighbors = neighbors + cshift( cshift(field, dx, 1), dy, 2 )
! 固定境界条件(eoshift, 境界の外は死(0))
! neighbors = neighbors + eoshift( eoshift(field, dx, 0, 1), dy, 0, 2 )
end do
where( neighbors == 3 )
field = 1
elsewhere( neighbors == 4 )
field = field
elsewhere
field = 0
endwhere
end subroutine one_epoch
end module lifegame
! MainProgram
program main
use lifegame
implicit none
integer :: epoch, size
integer :: i
write( *, * ) "# size?"
read( *, * ) size
write( *, * ) "# epoch?"
read( *, * ) epoch
call init_field( size )
call print_field
do i = 1, epoch
call one_epoch
write (*, *)
call print_field
end do
stop
end program main
gifアニメの出力はgnuplotで。
reset
set term gif animate size 560, 400 # 出力をgifアニメに設定
set output "field.gif" # 出力ファイル名
set size square
set nozeroaxis
set notics
unset colorbox
set palette grey # gray0 = 黒
set title font "Arial,30"
set key below
do for [n=0:1000:1] {
plot "field.log" index n matrix with image title sprintf("generation %d", n)
}
fortran
fortranは以下の本とか読んでいました。
今ならchatgpt使って、最近のプログラムにも簡単に書き換えられるのかもと思いつつ。chatgptもいろいろ試して、記事書いてみたい。
コンパイラ
GNU Fortran (x86_64-posix-seh-rev0, Built by MinGW-W64 project) 8.1.0
準備があればさくっとかける。どんどんかくぞ。
2023/4/12追記
調べたら記事たくさんあった!レベル違う。奥が深い。
chatgptなら、プログラムの書き換えだけじゃなくてこういう使い方もあるのか。そんなに詳しくない言語もなんとかなりそう。
この記事が気に入ったらサポートをしてみませんか?