labyrinth 0.4.0.0 → 0.4.1.0
raw patch · 3 files changed
+47/−35 lines, 3 files
Files
- labyrinth.cabal +1/−1
- src/Labyrinth/Action.hs +33/−30
- src/Labyrinth/Map.hs +13/−4
labyrinth.cabal view
@@ -1,5 +1,5 @@ name: labyrinth-version: 0.4.0.0+version: 0.4.1.0 synopsis: A complicated turn-based game description: Players take turns in a labyrinth, competing with each other to pick a treasure and carry it out. They only know
src/Labyrinth/Action.hs view
@@ -324,8 +324,9 @@ if b > 0 then do pos <- use (currentPlayer . position)+ out <- gets $ isOutside pos ct <- use (cell pos . ctype)- if ct == Hospital || ct == Armory+ if not out && (ct == Hospital || ct == Armory) then return $ ShootR Forbidden else do currentPlayer . pbullets -= 1@@ -335,6 +336,37 @@ else return $ ShootR NoBullets +performShootFrom :: Position -> Direction -> ActionState ShootResult+performShootFrom pos dir =+ let endShot = return ShootOK+ endShotIf cond act = if cond then endShot else act+ in do+ wayOut <- gets $ wayOutside pos+ endShotIf wayOut $ do+ out <- gets $ isOutside pos+ ct <- use (cell pos . ctype)+ endShotIf (not out && ct == Hospital) $ do+ hit <- playersAliveAt pos+ pi <- use currentTurn+ let othersHit = delete pi hit+ if null othersHit+ then endShotIf (not out && ct == Armory) $ do+ let npos = advance pos dir+ nout <- gets $ isOutside npos+ w <- use (wall pos dir)+ if (out && nout) || w == NoWall+ then performShootFrom (advance pos dir) dir+ else endShot+ else do+ forM_ othersHit $ \i -> do+ ph <- use (player i . phealth)+ dropBullets i+ dropTreasure i+ when (ph == Wounded) $ dropGrenades i+ player i . pjustShot .= True+ player i . phealth %= pred+ return Scream+ allPlayers :: Monad m => LabState m [PlayerId] allPlayers = do cnt <- gets playerCount@@ -366,35 +398,6 @@ notFallen :: Monad m => PlayerId -> LabState m Bool notFallen i = liftM not $ isFallen i--performShootFrom :: Position -> Direction -> ActionState ShootResult-performShootFrom pos dir = do- outside <- gets $ isOutside pos- ct <- use (cell pos . ctype)- cnt <- gets playerCount- hit <- playersAliveAt pos- if not outside && ct == Hospital- then return ShootOK- else do- pi <- use currentTurn- let othersHit = delete pi hit- if null othersHit- then if outside || ct == Armory- then return ShootOK- else do- w <- use (wall pos dir)- if w == NoWall- then performShootFrom (advance pos dir) dir- else return ShootOK- else do- forM_ othersHit $ \i -> do- ph <- use (player i . phealth)- dropBullets i- dropTreasure i- when (ph == Wounded) $ dropGrenades i- player i . pjustShot .= True- player i . phealth %= pred- return Scream dropBullets :: PlayerId -> ActionState () dropBullets i = do
src/Labyrinth/Map.hs view
@@ -121,15 +121,24 @@ isInside :: Position -> Labyrinth -> Bool isInside (Pos x y) l = and [ x >= 0- , x < w- , y >= 0- , y < h- ]+ , x < w+ , y >= 0+ , y < h+ ] where w = l ^. labWidth h = l ^. labHeight isOutside :: Position -> Labyrinth -> Bool isOutside p = not . isInside p++wayOutside :: Position -> Labyrinth -> Bool+wayOutside (Pos x y) l = or [ x < (-1)+ , x > w+ , y < (-1)+ , y > h+ ]+ where w = l ^. labWidth+ h = l ^. labHeight outerPos :: Labyrinth -> [(Position, Direction)] outerPos l = concat [ [(Pos x 0, U) | x <- [0..w - 1]]