@@ -2,38 +2,30 @@ module Lib where
2
2
3
3
import Data.Array
4
4
5
- width :: Int
6
- width = 20
7
-
8
- height :: Int
9
- height = 20
10
-
11
5
-- Board type using Data.Array with custom Show typeclass
12
6
newtype Board = B (Array (Int , Int ) String )
13
7
14
8
instance Show Board where
15
9
show (B b) = showRows b 0
16
10
11
+ unpack :: Board -> Array (Int , Int ) String
12
+ unpack (B b) = b
13
+
17
14
showRows :: Array (Int , Int ) String -> Int -> String
18
- showRows r i
19
- -- tail recursion
15
+ showRows r i -- tail recursion
20
16
| i < maxRow = " |" ++ rowStr ++ " |\n " ++ showRows r (i+ 1 )
21
17
| otherwise = " |" ++ rowStr ++ " |\n "
22
18
where maxRow = fst . snd $ bounds r
23
19
maxCol = snd . snd $ bounds r
24
20
rowStr = concat [ r ! (i, j) ++ " " | j <- [0 .. maxCol] ]
25
21
26
- unpack :: Board -> Array (Int , Int ) String
27
- unpack (B b) = b
28
-
29
- -- example boards
30
- rpentominoPredecessor :: Board
31
- rpentominoPredecessor = B (listArray ((0 , 0 ), (width- 1 , height- 1 )) [ if i `elem` alive then " O" else " " | i <- [0 .. width* height] ])
32
- where alive = [207 , 208 , 209 , 191 , 211 , 212 ]
33
-
34
- blinkerAndBlock :: Board
35
- blinkerAndBlock = B (listArray ((0 , 0 ), (width- 1 , height- 1 )) [ if i `elem` alive then " O" else " " | i <- [0 .. width* height] ])
36
- where alive = [204 , 205 , 206 , 232 , 233 , 252 , 253 ]
22
+ createBoard :: String -> IO Board
23
+ createBoard s = do fileString <- readFile s
24
+ -- TODO: read line wise
25
+ let height = (length $ filter (== ' \n ' ) fileString) + 1
26
+ let fileList = fmap (\ x -> [x]) (filter (/= ' \n ' ) fileString)
27
+ let width = length fileList `div` height
28
+ pure $ B (listArray ((0 , 0 ), (width- 1 , height- 1 )) fileList)
37
29
38
30
-- command line related
39
31
clearScreen :: IO ()
@@ -44,15 +36,17 @@ displayBoard b = putStr $ show b
44
36
45
37
-- count living neighbors; when out of bounds continue on the other side of the board
46
38
countNeighbors :: (Int , Int ) -> Board -> Int
47
- countNeighbors p b = length . filter (== " O" ) . map (\ i -> boardArray ! i) $ map handleOverflow neighborIndices
39
+ countNeighbors p b = length . filter (== " O" ) . map (\ i -> boardArray ! i) $ map ( handleOverflow (width, height)) neighborIndices
48
40
where boardArray = unpack b
41
+ width = fst . snd $ bounds boardArray
42
+ height = snd . snd $ bounds boardArray
49
43
neighborIndices = [ (i, j) | i <- [fst p + 1 , fst p, fst p - 1 ],
50
44
j <- [snd p + 1 , snd p, snd p - 1 ],
51
45
i /= fst p || j /= snd p]
52
46
53
- handleOverflow :: (Int , Int ) -> (Int , Int )
54
- handleOverflow (i,j) = (i `mod` width,
55
- j `mod` height)
47
+ handleOverflow :: (Int , Int ) -> (Int , Int ) -> ( Int , Int )
48
+ handleOverflow (width, height) ( i,j) = (i `mod` width,
49
+ j `mod` height)
56
50
57
51
-- game of life logic for each cell: https://en.wikipedia.org/wiki/Conway%27s_Game_of_Life#Rules
58
52
nextCellValue :: (Int , Int ) -> Board -> String
@@ -63,7 +57,6 @@ nextCellValue (i,j) b
63
57
where boardArray = unpack b
64
58
neighborCount = countNeighbors (i, j) b
65
59
66
- --
67
60
updateBoard :: Board -> Board
68
61
updateBoard b = B (boardArray // [(i, nextCellValue i b) | i <- indices boardArray])
69
62
where boardArray = unpack b
0 commit comments