Life Gameでハマる

現実の仕事は既存コードのバグで数日ハマっている。
なので、気晴らしにHaskellでも…と思ってたらこちらもハマるorz

ライフゲーム

きっかけはM・ミッチェル・ワールドロップの『複雑系―科学革命の震源地・サンタフェ研究所の天才たち (新潮文庫)』を読み返して、感銘を受けたため。
Haskellマンデルブロ集合は誰かやってたしなぁ、じゃあライフゲームでも作るかと思い立つ。
http://ja.wikipedia.org/wiki/%E3%83%A9%E3%82%A4%E3%83%95%E3%82%B2%E3%83%BC%E3%83%A0
1時間くらいで出来るかなーっと。

wxHaskell

何はともあれGUI。定番?のwxHaskellをインストール。
http://wxhaskell.sourceforge.net/

>ghc -package wx -o helloworld HelloWorld.hs
HelloWorld.hs:4:0:
    Failed to load interface for `Graphics.UI.WX':
        Bad interface file: C:\haskell\wxhaskell-0.9.4\lib\imports/Graphics/UI/WX.hi

            mismatched interface file versions: expected 6042, found 6040

バージョンが違うらしい。確かに今使ってるGHCは6.4.2だし。
しょうがないのでバージョンダウンする。
http://www.haskell.org/ghc/download_ghc_64.html

無事コンパイル完。めでたしめでたし。

プロトタイプ

セルを表現するためには…

boolean field[50][50]

っちゅー、2次元配列が欲しいけど、Haskellでどうやるんだ?
…紆余曲折の末、IOUArrayを使うことにする。
で、小さなプロトタイプ。

module Main where

import Data.Array.IO
import Data.Array.Base
import Graphics.UI.WXCore
import Graphics.UI.WX

drawPoints :: Int -> Int -> IOUArray (Int, Int) Bool -> DC a -> IO ()
drawPoints x y f dc = do alive <- readArray f (x,y)
                         when alive (drawPoint dc (pt x y) [color := black])

gui :: IO ()
gui = do f <- frame [text := "Life game Prototype", 
                 fullRepaintOnResize := False, 
                 clientSize := sz 50 50, 
                 on paint := onpaint]
         return ()
  where
     onpaint dc viewArea
       = do field <- newArray ((0,0),(49,49)) False :: IO (IOUArray (Int, Int) Bool)
            writeArray field (10,10) True
            writeArray field (20,20) True
            writeArray field (30,30) True
            writeArray field (40,40) True
            mapM_ (\(x,y) -> drawPoints x y field dc) $ indices field

main :: IO ()
main = start gui

セルが1ドットは小さすぎるw
まぁ、後からなんとでもなるだろう。

本実装…できず

ライフゲームの肝である、世代交代のロジックがうまく組めない。
戦略としては、indices fieldに対して、セルのまわりの生き死にをwriteArrayで書き換えるラムダをあてがってやればいいと思ったんだけども。
なんというか、モナドの連鎖の整合性を保つために型を合わせるのに四苦八苦。
うーん、IOUArrayを使ったのがマズかったのだろうか、GUIにwxHaskellを選んだのがマズかったのか。
どのみち、副作用ばかりでHaskellらしくなくなるのは確かだ。
失意のまま、今日は挫折。


明日は運動して気晴らしすることとしようorz