Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Read board from a file #1

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 2 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,9 @@ This is the [game of life](https://en.wikipedia.org/wiki/Conway%27s_Game_of_Life

To execute the game you do:

`stack run`
`stack run -- -f <life file> -r <number of rows> -c <number of columns>`

If you want to see a different game (not the glider one), open the REPL and use:

`playGame OTHER_GAME`
It will load a `.life` file in a matrix of the specified size. You can read about the `Life` format [here](https://conwaylife.com/wiki/Life_1.06).

## Developers

Expand Down
14 changes: 12 additions & 2 deletions app/Main.hs
Original file line number Diff line number Diff line change
@@ -1,9 +1,19 @@
module Main where

import GameOfLife
import Games
import Display
import Types
import Parser
import Text.Megaparsec
import Options.Applicative
import qualified Data.Text as T
import Options (parseOptions, Options(..))

main :: IO ()
main = playGame gliderGrid
main = do
options <- execParser parseOptions
contents <- readFile (file options)
let positions = runParser parseLife (file options) (T.pack contents)
case positions of
Left err -> print err
Right positions -> playGame $ createGrid (rows options) (cols options) positions
4 changes: 4 additions & 0 deletions examples/Blinker.life
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#Life 1.06
0 0
1 0
2 0
6 changes: 6 additions & 0 deletions examples/Glider.life
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#Life 1.06
0 1
1 2
2 0
2 1
2 2
14 changes: 12 additions & 2 deletions h-vita.cabal
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
cabal-version: 1.12

-- This file has been generated from package.yaml by hpack version 0.34.4.
-- This file has been generated from package.yaml by hpack version 0.36.0.
--
-- see: https://github.com/sol/hpack

Expand All @@ -27,7 +27,8 @@ library
exposed-modules:
Display
GameOfLife
Games
Options
Parser
Types
other-modules:
Paths_h_vita
Expand All @@ -37,6 +38,9 @@ library
base >=4.7 && <5
, gloss
, matrix
, megaparsec
, optparse-applicative
, text
default-language: Haskell2010

executable h-vita-exe
Expand All @@ -51,6 +55,9 @@ executable h-vita-exe
, gloss
, h-vita
, matrix
, megaparsec
, optparse-applicative
, text
default-language: Haskell2010

test-suite h-vita-test
Expand All @@ -66,4 +73,7 @@ test-suite h-vita-test
, gloss
, h-vita
, matrix
, megaparsec
, optparse-applicative
, text
default-language: Haskell2010
3 changes: 3 additions & 0 deletions package.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@ dependencies:
- base >= 4.7 && < 5
- matrix
- gloss
- optparse-applicative
- megaparsec
- text

library:
source-dirs: src
Expand Down
15 changes: 14 additions & 1 deletion src/Display.hs
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,22 @@ import Data.Matrix
import Graphics.Gloss
import Graphics.Gloss.Interface.Pure.Simulate
import GameOfLife
import Games
import Types

createGrid :: Int -> Int -> [Location] -> Matrix Cell
createGrid rows cols positions = matrix rows cols getCellState
where
centerRow = (rows + 1) `div` 2
centerCol = (cols + 1) `div` 2

index :: Int -> Int -> Location
index x y = (centerRow - x, y - centerCol)

getCellState :: Location -> Cell
getCellState (x, y)
| index x y `elem` positions = alive
| otherwise = dead

render :: DisplayCellSize -> Grid -> Picture
render (width, height) grid = Pictures $ toList $ mapPos cellToRect grid
where
Expand Down
34 changes: 0 additions & 34 deletions src/Games.hs

This file was deleted.

32 changes: 32 additions & 0 deletions src/Options.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
module Options where

import Options.Applicative

data Options = Options {
file :: FilePath,
rows :: Int,
cols :: Int
}

parseOptions :: ParserInfo Options
parseOptions = info
(helper <*> (
Options
<$> strOption (
long "file"
<> short 'f'
<> metavar "FILE"
<> help "File path"
)
<*> option auto (
long "rows"
<> short 'r'
<> help "Number of rows"
)
<*> option auto (
long "columns"
<> short 'c'
<> help "Number of columns"
)
))
(fullDesc <> header "h-vita")
21 changes: 21 additions & 0 deletions src/Parser.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{-# LANGUAGE OverloadedStrings #-}

module Parser where

import Types
import Text.Megaparsec ( Parsec, many, optional )
import Text.Megaparsec.Char
import Data.Void
import Data.Text
import Text.Megaparsec.Char.Lexer (decimal, signed)

type Parser = Parsec Void Text

parseLife :: Parser [Location]
parseLife = header *> many position

header :: Parser Text
header = string "#Life 1.06" *> eol

position :: Parser Location
position = (,) <$> (signed space decimal <* space) <*> (signed space decimal <* optional eol)