Skip to content
Snippets Groups Projects
Commit cb89a878 authored by Unai Zalakain's avatar Unai Zalakain
Browse files

Throw stones only on positions that are free

And complain if there is no place left to throw any stones.
parent 4816dcef
No related branches found
No related tags found
No related merge requests found
...@@ -32,11 +32,11 @@ instance Options MainOptions where ...@@ -32,11 +32,11 @@ instance Options MainOptions where
"Number of players" "Number of players"
create :: MainOptions -> Either String (IO Game) create :: MainOptions -> IO (Either String Game)
create options create options
| max (options&optWidth) (options&optHeight) > 24 = Left "Cannot have more than 24 on either axis." | max (options&optWidth) (options&optHeight) > 24 = return $ Left "Cannot have more than 24 on either axis."
| otherwise = Right $ do g <- getStdGen | otherwise = do g <- getStdGen
return $ B.throwStones game (optNumStones options) g return $ B.throwStones game (optNumStones options) g
where players = take (optNumPlayers options) [Green ..] where players = take (optNumPlayers options) [Green ..]
game = Game { pieces = Map.empty game = Game { pieces = Map.empty
, boardSize = (optWidth options, optHeight options) , boardSize = (optWidth options, optHeight options)
...@@ -47,8 +47,9 @@ create options ...@@ -47,8 +47,9 @@ create options
main :: IO () main :: IO ()
main = runCommand $ \opts args -> main = runCommand $ \opts args -> do
case create opts of game <- create opts
case game of
Left message -> print message Left message -> print message
Right game -> do game >>= play Right g -> do play g
return () return ()
module Snorkels.Board ( odule Snorkels.Board (
-- * Checkers -- * Checkers
isValid isValid
, isTrapped , isTrapped
...@@ -32,7 +32,7 @@ import qualified Data.Set as Set ...@@ -32,7 +32,7 @@ import qualified Data.Set as Set
import Snorkels.Types import Snorkels.Types
-- | -- |
-- Given some @(min, max)@ bounds, check if an 'Int' is in them. -- Given some @(min, max)@ bounds, check if an 'Int' is in them.
-- @min@ is inclusive, @max@ isn't. -- @min@ is inclusive, @max@ isn't.
inRange :: (Int, Int) -> Int -> Bool inRange :: (Int, Int) -> Int -> Bool
...@@ -56,17 +56,17 @@ neighbours :: Position -> Set.Set Position ...@@ -56,17 +56,17 @@ neighbours :: Position -> Set.Set Position
neighbours position = Set.map (`offset` position) neighbourOffsets neighbours position = Set.map (`offset` position) neighbourOffsets
where neighbourOffsets = Set.fromList [(-1, 0), (1, 0), (0, -1), (0, 1)] where neighbourOffsets = Set.fromList [(-1, 0), (1, 0), (0, -1), (0, 1)]
-- | -- |
-- Check if some 'Position' is within the bounds of a board -- Check if some 'Position' is within the bounds of a board
isValid :: Game -> Position -> Bool isValid :: Game -> Position -> Bool
isValid game = inBounds $ game&boardSize isValid game = inBounds $ game&boardSize
-- | -- |
-- Check if some 'Position's are within the bounds of a game -- Check if some 'Position's are within the bounds of a game
areValid :: Game -> Set.Set Position -> Set.Set Position areValid :: Game -> Set.Set Position -> Set.Set Position
areValid game = Set.filter (isValid game) areValid game = Set.filter (isValid game)
-- | -- |
-- Get all the 'Position's that are within a board -- Get all the 'Position's that are within a board
allPositions :: Game -> Set.Set Position allPositions :: Game -> Set.Set Position
allPositions game = Set.fromList [(x, y) | x <- [0..width-1], y <- [0..height-1]] allPositions game = Set.fromList [(x, y) | x <- [0..width-1], y <- [0..height-1]]
...@@ -171,8 +171,16 @@ shufflePositions positions g = map (p !!) $ randomRs (0, length p - 1) g ...@@ -171,8 +171,16 @@ shufflePositions positions g = map (p !!) $ randomRs (0, length p - 1) g
where p = Set.toList positions where p = Set.toList positions
throwStone :: RandomGen g => Game -> g -> Either String Game
throwStone game g
| null $ freePositions game = Left "There is no place to throw a stone."
| otherwise = Right $ putPiece game pos Stone
where pos = head $ shufflePositions (freePositions game) g
-- | -- |
-- Randomly throw the given number of 'Stone's on the board. -- Randomly throw the given number of 'Stone's on the board.
throwStones :: RandomGen g => Game -> Int -> g -> Game throwStones :: RandomGen g => Game -> Int -> g -> Either String Game
throwStones game n g = foldl throwStone game $ take n $ shufflePositions (freePositions game) g throwStones game 0 _ = Right game
where throwStone b p = putPiece b p Stone throwStones game n g = case throwStone game g of
Right game -> throwStones game (n-1) g
Left message -> Left message
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment