-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.hs
75 lines (50 loc) · 1.57 KB
/
main.hs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
cls :: IO()
cls = putStr "\ESC[2J"
type Pos = (Int, Int)
writeat:: Pos -> String -> IO()
writeat p xs = do goto p
putStr xs
goto:: Pos -> IO()
goto (x, y) = putStr ("\ESC["++ show y++";"++ show x ++ "H")
width:: Int
width = 200
height :: Int
height = 100
type Board = [Pos]
glider::Board
glider = [(4,2), (2,3),(4,3), (3,4),(4,4)]
showcells::Board ->IO()
showcells b = sequence_ [writeat p "0"| p<-b]
isAlive:: Board -> Pos -> Bool
isAlive b p = elem p b
isEmpty::Board -> Pos -> Bool
isEmpty b p = not (isAlive b p)
neighbs::Pos -> [Pos]
neighbs (x,y) = map wrap [(x-1, y-1), (x, y-1), (x+1, y-1),(x-1, y),(x+1, y), (x-1, y+1), (x, y+1),(x+1, y+1)]
wrap:: Pos -> Pos
wrap (x, y) = (((x-1) `mod` width)+1, ((y-1) `mod` height) + 1)
liveneighbs::Board -> Pos -> Int
liveneighbs b = length . filter (isAlive b). neighbs
survivors::Board -> [Pos]
survivors b = [p | p <-b, elem (liveneighbs b p) [2,3]]
-- births:: Board -> [Pos]
-- births b = [(x, y) | x <- [1..width],
-- y <- [1..height],
-- isEmpty b (x, y),
-- liveneighbs b (x, y)==3 ]
births:: Board -> [Pos]
births b = [p | p <- rmdups (concat (map neighbs b)), isEmpty b p, liveneighbs b p == 3]
rmdups:: Eq a => [a] -> [a]
rmdups [] = []
rmdups (x:xs) = x:rmdups (filter (/=x) xs)
nextgen::Board -> Board
nextgen b = survivors b ++ births b
life::Board -> IO()
life b = do cls
showcells b
wait 500000
life (nextgen b)
wait::Int -> IO()
wait n = sequence_ [return ()| _<- [1..n]]
main::IO()
main = life glider