Skip to content

Commit c53608a

Browse files
committed
read board initialization from file and add some examples
1 parent 088dc59 commit c53608a

File tree

5 files changed

+72
-36
lines changed

5 files changed

+72
-36
lines changed

app/Main.hs

+13-10
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
module Main where
22

33
import Lib
4-
import System.Posix.Unistd
4+
import Control.Concurrent
5+
6+
import Data.Array
57

68
{-
79
clear screen
@@ -10,14 +12,15 @@ import System.Posix.Unistd
1012
recursive call with updated board
1113
-}
1214
gameOfLife :: Board -> IO ()
13-
gameOfLife b = if not $ isBoardEmpty b then
14-
do clearScreen
15-
displayBoard b
16-
usleep 500000
17-
gameOfLife $ updateBoard b
18-
else
19-
do clearScreen
20-
putStr "Done.\n"
15+
gameOfLife b = if not $ isBoardEmpty b then
16+
do clearScreen
17+
displayBoard b
18+
threadDelay 500000
19+
gameOfLife $ updateBoard b
20+
else
21+
do clearScreen
22+
putStr "Done.\n"
2123

2224
main :: IO()
23-
main = gameOfLife rpentominoPredecessor
25+
main = do board <- createBoard "examples/blinker_block.txt"
26+
gameOfLife board

examples/blinker_block.txt

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
2+
3+
4+
OOO
5+
6+
7+
OO
8+
OO
9+
10+

examples/rpentomino_predecessor.txt

+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
2+
3+
4+
5+
6+
7+
8+
O
9+
10+
OOO OO
11+
12+
13+
14+
15+
16+
17+
18+
19+
20+
21+
22+
23+
24+
25+
26+
27+
28+
29+
30+

package.yaml

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
name: game-of-life
2-
version: 0.1.1.0
2+
version: 0.2.1.0
33
github: "cozyDoomer/game-of-life-haskell"
44
license: "GPLv3"
55
author: "Christian Unterrainer"
@@ -15,7 +15,7 @@ description: Please see the README on GitHub at https://github.com/cozyD
1515
dependencies:
1616
- base >= 4.7 && < 5
1717
- array
18-
- unix
18+
- polyparse
1919

2020
library:
2121
source-dirs: src

src/Lib.hs

+17-24
Original file line numberDiff line numberDiff line change
@@ -2,38 +2,30 @@ module Lib where
22

33
import Data.Array
44

5-
width :: Int
6-
width = 20
7-
8-
height :: Int
9-
height = 20
10-
115
-- Board type using Data.Array with custom Show typeclass
126
newtype Board = B (Array (Int, Int) String)
137

148
instance Show Board where
159
show (B b) = showRows b 0
1610

11+
unpack :: Board -> Array (Int, Int) String
12+
unpack (B b) = b
13+
1714
showRows :: Array (Int, Int) String -> Int -> String
18-
showRows r i
19-
-- tail recursion
15+
showRows r i -- tail recursion
2016
| i < maxRow = "|" ++ rowStr ++ "|\n" ++ showRows r (i+1)
2117
| otherwise = "|" ++ rowStr ++ "|\n"
2218
where maxRow = fst . snd $ bounds r
2319
maxCol = snd . snd $ bounds r
2420
rowStr = concat [ r ! (i, j) ++ " " | j <- [0 .. maxCol] ]
2521

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)
3729

3830
-- command line related
3931
clearScreen :: IO ()
@@ -44,15 +36,17 @@ displayBoard b = putStr $ show b
4436

4537
-- count living neighbors; when out of bounds continue on the other side of the board
4638
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
4840
where boardArray = unpack b
41+
width = fst . snd $ bounds boardArray
42+
height = snd . snd $ bounds boardArray
4943
neighborIndices = [ (i, j) | i <- [fst p + 1, fst p, fst p - 1],
5044
j <- [snd p + 1, snd p, snd p - 1],
5145
i /= fst p || j /= snd p]
5246

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)
5650

5751
-- game of life logic for each cell: https://en.wikipedia.org/wiki/Conway%27s_Game_of_Life#Rules
5852
nextCellValue :: (Int, Int) -> Board -> String
@@ -63,7 +57,6 @@ nextCellValue (i,j) b
6357
where boardArray = unpack b
6458
neighborCount = countNeighbors (i, j) b
6559

66-
--
6760
updateBoard :: Board -> Board
6861
updateBoard b = B (boardArray // [(i, nextCellValue i b) | i <- indices boardArray])
6962
where boardArray = unpack b

0 commit comments

Comments
 (0)