packages feed

game-of-life-0.1.0.5: Main.hs

module Main where

import Simulation

import qualified UI.HSCurses.Curses as Curses
import Control.Monad(replicateM)
import System.Random
import Control.Concurrent(threadDelay)
import Data.List(intercalate)
import Data.Array

-- Delay between iterations (μs)
delay :: Int
delay = 50000

-- Probability of a cell being Alive on board generation
density :: Float
density = 0.37

main :: IO ()
main = do
  window <- Curses.initScr
  Curses.raw True
  _ <- Curses.cursSet Curses.CursorInvisible
  Curses.timeout 0
  (rows, cols) <- Curses.scrSize
  randomBoard rows (cols-1) >>= life window
  Curses.resetParams
  Curses.endWin

life :: Curses.Window -> Board -> IO ()
life window board = do
    _ <- drawBoard board window
    threadDelay delay
    Curses.getch >>= \ch -> case Curses.decodeKey ch of 
      Curses.KeyUnknown _ -> life window (step board)
      _                   -> return ()

drawBoard :: Board -> Curses.Window -> IO ()
drawBoard board window = do
  Curses.move 0 0
  Curses.wAddStr window (boardRep board)
  Curses.wRefresh window

boardRep :: Board -> String
boardRep board = intercalate "\n" [rowStrings r | r <- [0..rs-1]]
  where
  rowStrings :: Int -> String
  rowStrings r = concat [show (grid ! r ! c) | c <- [0..cs-1]]
  rs = bRows board 
  cs = bCols board 
  grid = bGrid board

randomBoard :: Int -> Int -> IO Board
randomBoard rows cols = randomGrid rows cols >>= 
                                \grid -> return $ Board grid rows cols

randomGrid :: Int -> Int -> IO Grid
randomGrid rs cs = replicateM cs randomRow >>= \rows -> return $ listArray (0, rs-1) rows
  where
  randomRow :: IO (Array Int State)
  randomRow = randomListOfCells >>= \cells -> return $ listArray (0, cs-1) cells

  randomListOfCells :: IO [State]
  randomListOfCells = fmap (map randomCell) (replicateM cs randomIO)

  randomCell :: Float -> State
  randomCell r
    | r < density  = Alive
    | r >= density = Dead
    | otherwise    = Dead