2008年12月11日星期四

"Game of Life" in Haskell

This post includes a Haskell implementation of Conway’s game of life. There is nothing particularly fancy here and the implementation is not of the most efficient one either but, hi, this is my first interactive Haskell program (and it is not hard at all).


type Size = Int
type Cell = (Int, Int)

type Board = [Cell]
data Life = Life Size Board

instance Show Life where

show (Life size board) =
[if c == size then '\n'

else if (r, c) `elem` board then '@'

else '-' | r <- [0..size-1],

c <- [0..size]]

next_life :: Life -> Life

next_life (Life size board) = Life size new_board where
new_board = survivors ++ births
survivors = [cell | cell <- board,

let n = living_neighbors cell
in n == 2 || n == 3]

births = [(r,c) | r <- [0..size-1],

c <- [0..size-1],
let cell = (r, c)

in (not (cell `elem` board)) && ((living_neighbors cell) == 3)]

living_neighbors cell = length $ filter is_living $ neighbors cell
is_living cell = cell `elem` board
neighbors (r, c) = [((r - 1) `mod` size, ((c - 1) `mod` size)),

((r - 1) `mod` size, c),

((r - 1) `mod` size, ((c + 1) `mod` size)),

(r , ((c - 1) `mod` size)),

(r , ((c + 1) `mod` size)),

((r + 1) `mod` size, ((c - 1) `mod` size)),

((r + 1) `mod` size, c),

((r + 1) `mod` size, ((c + 1) `mod` size))]

interactive :: Life -> IO ()
interactive life
= do print life
c <- getChar
if c == 'q' then

return ()
else
interactive $ next_life life




Loading the above program into Hugs and an interactive session goes like this:

Main> interactive $ Life 5 [(1,3), (2,1), (2,3), (3,2), (3,3)]
-----
---@-
-@-@-
--@@-
-----


-----
--@--
---@@
--@@-
-----


-----
---@-
----@
--@@@
-----


-----
-----
--@-@
---@@
---@-

q

Main>

Have fun!

没有评论: