Created
November 17, 2014 05:31
-
-
Save chadbrewbaker/e0d335a3d7c7dc6b23d5 to your computer and use it in GitHub Desktop.
gdocr14 Haskell Life
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Test.QuickCheck | |
import Data.List | |
type Height = Integer | |
type Width = Integer | |
type Cell = (Height, Width) | |
type LiveCells = [Cell] | |
type World = (LiveCells, Height, Width) | |
type AliveNeighborCount = Integer | |
type AmIAlive = Bool | |
emptyWorld :: World | |
emptyWorld = ([],500,500) | |
twoWorld = ([(0,0), (0,1)], 500, 500) | |
getCells :: World -> LiveCells | |
getCells (x,y,z) = x | |
getHeight :: World -> Height | |
getHeight (x,y,z) = y | |
getWidth :: World -> Width | |
getWidth (x,y,z) = z | |
alive :: [Cell] -> World -> [Cell] | |
alive cells w = intersect cells (getCells w) | |
singleAlive :: World -> Cell -> Bool | |
singleAlive w c = (length (intersect [c] (getCells w))) > 0 | |
neighborsOf :: Cell -> World -> [Cell] | |
neighborsOf c w = [(hsucc (fst c), snd c), (hsucc(fst c), wsucc(snd c)),(fst c, wsucc(snd c)),(hpred(fst c), wsucc(snd c)),(hpred(fst c), snd c), | |
(hpred(fst c), wpred(snd c)),(fst c, wpred(snd c)),(hsucc(fst c), wpred(snd c)) ] | |
where | |
hsucc x = mod (succ x) (getHeight w) | |
hpred x = mod (pred x) (getHeight w) | |
wsucc x = mod (succ x) (getWidth w) | |
wpred x = mod (pred x) (getWidth w) | |
neighborhood :: World -> Cell -> [Cell] | |
neighborhood w c = [c] ++ (neighborsOf c w) | |
neighborsAlive :: World -> Cell -> Integer | |
neighborsAlive w cell = toInteger (length (delete cell (nub (alive (neighborsOf cell w) w) )) ) | |
aliveNextTickSub :: AliveNeighborCount -> AmIAlive -> AmIAlive | |
aliveNextTickSub 0 False = False | |
aliveNextTickSub 3 False = True | |
aliveNextTickSub 3 True = False | |
aliveNextTickSub count isalive | |
| count < 2 && isalive = False | |
| (count == 2 || count == 3) && isalive = True | |
| isalive && count > 3 = False | |
| (not isalive) && (count == 3) = True | |
| otherwise = False | |
aliveNextTick :: World -> Cell -> AmIAlive | |
aliveNextTick w c = aliveNextTickSub (neighborsAlive w c) (singleAlive w c) | |
cellsToCheck :: World -> [Cell] | |
cellsToCheck w = (nub.concat) (map (neighborhood w) (getCells w)) | |
tick :: World -> World | |
tick w = (filter (aliveNextTick w) (cellsToCheck w) , getHeight w, getWidth w) | |
prop_empty_world (Positive x) (Positive y) = tick([], x, y) == ([], x, y) | |
prop_lonely_cell_returns_empty_world (Positive x) (Positive y) = tick([(0,0)], x, y) == ([], x, y) | |
prop_empty_world_has_nothing_alive x y = aliveNextTick emptyWorld (mod x 500, mod y 500) == False | |
runTests :: IO () | |
runTests = do | |
print (emptyWorld == (tick twoWorld)) | |
quickCheck prop_empty_world | |
quickCheck prop_lonely_cell_returns_empty_world | |
quickCheck prop_empty_world_has_nothing_alive |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment