From 2d2fb5a14a4f5c1b522d0fab0728ab852958fd7e Mon Sep 17 00:00:00 2001 From: Chris Hendrix and Sean Brady Date: Fri, 19 Jun 2015 14:06:10 -0700 Subject: [PATCH] Moved ownership of Player to cell --- src/Rogue/Model.elm | 123 +++++++++++++++++++++---------------------- src/Rogue/Update.elm | 48 ++++++++++++++--- src/Rogue/View.elm | 44 ++++++---------- 3 files changed, 114 insertions(+), 101 deletions(-) diff --git a/src/Rogue/Model.elm b/src/Rogue/Model.elm index b2d0b64..b603a9b 100644 --- a/src/Rogue/Model.elm +++ b/src/Rogue/Model.elm @@ -1,7 +1,7 @@ module Rogue.Model where import Array exposing (..) -import List exposing (member) +import List exposing (..) import Maybe exposing (..) import Random exposing (..) @@ -9,13 +9,7 @@ import Now type alias Location = (Int, Int) -type alias GameMap = - { board : Board - , start : Location - , currentPlayerLocation : Location - } - -type alias Board = Array (Array Cell) +type alias GameMap = Array (Array Cell) type Player = Player @@ -24,36 +18,25 @@ type alias Game = , player : Player } -type Cell = Open Location | Barrier Location - -isOpen : Cell -> Bool -isOpen cell = - case cell of - (Open _) -> True - (Barrier _) -> False - -cellAt : Location -> Board -> Maybe Cell -cellAt (rowNum,colNum) board = - get rowNum board `andThen` (\row -> get colNum row) +type Cell = Open { player : Maybe Player } | Barrier {} -isAt : Location -> Cell -> Bool -isAt queried cell = queried == (loc cell) +type alias Dir = + { x : Int + , y : Int + } -loc : Cell -> Location -loc c = - case c of - Open l -> l - Barrier l -> l +type alias Input = + { dir : Dir + } -newBoardWithBarriersAt : Int -> List Location -> Board -newBoardWithBarriersAt size barrierLocations = +newBoardWithBarriersAt : Int -> List Location -> Player -> GameMap +newBoardWithBarriersAt size barrierLocations p = initialize size ( \row -> initialize size ( - \col -> if (row,col) `member` barrierLocations then Barrier (row, col) else Open (row, col))) - -newBoard : Int -> Board -newBoard size = - newBoardWithBarriersAt size [] + \col -> if | (row,col) == (0,0) -> Open { player = Just p } + | (row,col) `member` barrierLocations -> Barrier {} + | otherwise -> Open { player = Nothing })) + randomizeLocationsWithin : Int -> Int -> List Location randomizeLocationsWithin size numLocations = @@ -62,42 +45,54 @@ randomizeLocationsWithin size numLocations = in generate locationGenerator (initialSeed (round Now.loadTime)) |> fst -gameMap : Int -> GameMap -gameMap size = - let startLoc = (0,0) in - { board = newBoardWithBarriersAt size (randomizeLocationsWithin size 11) - , start = startLoc - , currentPlayerLocation = startLoc - } +gameMap : Int -> Player -> GameMap +gameMap size p = + newBoardWithBarriersAt size (randomizeLocationsWithin size 11) p defaultGame : Game defaultGame = let - g = gameMap 10 + p = Player + g = gameMap 10 p in { gameMap = g - , player = Player + , player = p } -type alias Dir = - { x : Int - , y : Int - } - -type alias Input = - { dir : Dir - } - -numRows : Board -> Int -numRows b = length b - -numCols : Board -> Int -numCols = numRows - -within : Board -> Location -> Bool -within board (row, col) = - row >= 0 && row < numRows board && col >= 0 && col < numCols board - -translate : Location -> Dir -> Location -translate (row,col) dir = - (row - dir.y, col + dir.x) \ No newline at end of file +currentPlayerLocation : GameMap -> Maybe Location +currentPlayerLocation gameMap = + let + matrixOfLocAndHasPlayer = + Array.indexedMap ( + \rowNum row -> + Array.indexedMap ( + \colNum cell -> ((rowNum,colNum), doesContainPlayer cell) + ) row + ) gameMap + in + Array.map toList matrixOfLocAndHasPlayer + |> toList + |> concat + |> List.filter snd + |> List.map fst + |> head + +doesContainPlayer : Cell -> Bool +doesContainPlayer c = + case c of + Open {player} -> isJust player + otherwise -> False + +isJust : Maybe a -> Bool +isJust m = + case m of + Just _ -> True + Nothing -> False + +translate : Dir -> Location -> Location +translate dir (row,col)= + (row - dir.y, col + dir.x) + +cellAt : GameMap -> Location -> Maybe Cell +cellAt gameMap (rowNum, colNum) = + Array.get rowNum gameMap `andThen` get colNum \ No newline at end of file diff --git a/src/Rogue/Update.elm b/src/Rogue/Update.elm index 1ec5b71..96f1339 100644 --- a/src/Rogue/Update.elm +++ b/src/Rogue/Update.elm @@ -1,18 +1,50 @@ module Rogue.Update where import Rogue.Model exposing (..) +import Array import Maybe +import Maybe exposing (andThen) update : Input -> Game -> Game update i game = - { game | gameMap <- updateGameMap i game.gameMap } + { game | gameMap <- updateGameMap i game.player game.gameMap } -updateGameMap : Input -> GameMap -> GameMap -updateGameMap {dir} ({board,start,currentPlayerLocation} as gameMap) = +updateGameMap : Input -> Player -> GameMap -> GameMap +updateGameMap {dir} p gameMap = let - newLocation = translate currentPlayerLocation dir - newCell = cellAt newLocation board - openness = Maybe.withDefault False (Maybe.map isOpen newCell) + maybeCurLocation = currentPlayerLocation gameMap + maybeTranslatedLocation = Maybe.map (translate dir) (maybeCurLocation) + maybeNewLocation = movePlayerToLocation gameMap maybeCurLocation maybeTranslatedLocation + maybeNewGameMap = Maybe.map (updateBoard p gameMap) maybeNewLocation in - if | within board newLocation && openness -> { gameMap | currentPlayerLocation <- newLocation } - | otherwise -> gameMap \ No newline at end of file + Maybe.withDefault gameMap maybeNewGameMap + +updateBoard : Player -> GameMap -> Location -> GameMap +updateBoard p gameMap newPlayerLoc = + Array.indexedMap ( + \rowNum row -> Array.indexedMap ( + \colNum cell -> + if | (rowNum, colNum) == newPlayerLoc -> insertPerson p cell + | otherwise -> clearCell cell + ) row + ) gameMap + +insertPerson : Player -> Cell -> Cell +insertPerson p c = + case c of + Open _ -> Open {player = Just p} + otherwise -> c + +clearCell : Cell -> Cell +clearCell c = + case c of + Open _ -> Open {player = Nothing} + otherwise -> c + +movePlayerToLocation : GameMap -> Maybe Location -> Maybe Location -> Maybe Location +movePlayerToLocation gameMap fromLoc toLoc = + toLoc `andThen` (cellAt gameMap) `andThen` (\cell -> + case cell of + Open _ -> toLoc + otherwise -> fromLoc + ) diff --git a/src/Rogue/View.elm b/src/Rogue/View.elm index 0e666d7..31c0486 100644 --- a/src/Rogue/View.elm +++ b/src/Rogue/View.elm @@ -13,25 +13,24 @@ view : Game -> Element view g = viewGameMap g.gameMap viewGameMap : GameMap -> Element -viewGameMap {board,start,currentPlayerLocation} = +viewGameMap gameMap = let rowifier = (\row -> - Array.map - (\cell -> - if | isAt currentPlayerLocation cell -> person - | not <| isOpen cell -> barrier - | otherwise -> open - ) - row + Array.map viewCell row |> toList |> flow right ) in - Array.map rowifier board + Array.map rowifier gameMap |> toList |> flow down +viewCell : Cell -> Element +viewCell c = + case c of + Open {player} -> open player + Barrier _ -> barrier txt str = Text.fromString str @@ -48,7 +47,13 @@ barrier = |> (\sq -> collage 16 16 [sq]) |> standardize -open = +open : Maybe a -> Element +open p = + case p of + Just _ -> person + Nothing -> unoccupied + +unoccupied = txt "." |> standardize @@ -56,22 +61,3 @@ standardize : Element -> Element standardize el = el |> container 16 16 middle - ---toString = --- let --- rowifier = --- (\row -> --- Array.map --- (\cell -> --- if | isAt currentPlayerLocation cell -> "@" --- | not <| isOpen cell -> "#" --- | otherwise -> "." --- ) --- row --- |> toList --- |> join "" --- ) --- in --- Array.map rowifier board --- |> toList --- |> join "\n" \ No newline at end of file