Skip to content

Commit

Permalink
- Добавлены экземпляры класса Eq для типов Item, Object.
Browse files Browse the repository at this point in the history
- Добвлен класс типов Openable a.
- Добавлен экземпляр класса Openable для типа Object.
- Упрощены функции открытия объекта.
  • Loading branch information
unknown authored and unknown committed May 22, 2011
1 parent c68efa4 commit c5a2bf0
Show file tree
Hide file tree
Showing 4 changed files with 84 additions and 53 deletions.
22 changes: 10 additions & 12 deletions GameState.hs
Original file line number Diff line number Diff line change
Expand Up @@ -100,28 +100,26 @@ tryWeld item1 item2 fromObjects curGS =
(xs) -> tooMany item1 matched1


applyOpen obj loc locs inv = let
newObj = obj {objectContainerState = Opened}
applyOpenedObject newObj loc locs inv = let
newLoc = loc {locObjects = updateObjects newObj (locObjects loc)} -- Ïîäìåíÿåì îäèí îáúåêò èç ñïèñêà îáúåêòîâ íîâûì îáúåêòîì.
newLocs = updateLocations newLoc locs -- Ïîäìåíÿåì îäíó ëîêàöèþ èç ñïèñêà ëîêàöèé íîâîé ëîêàöèåé.
newInv = updateObjects newObj inv
in (newObj, newLoc, newLocs, newInv)
in (newLoc, newLocs, newInv)

tryOpenS :: String -> Objects -> GameState -> GameAction
tryOpenS str objects curGS = case parseObject str objects of
Right obj -> tryOpen' obj curGS
Left str -> PrintMessage str

tryOpen' :: Object -> GameState -> GameAction
tryOpen' o gs@(GameState locs curLoc inv) =
case objectContainerState o of
NotContainer -> PrintMessage $ cannotBeOpenedError $ o
Opened -> PrintMessage $ alreadyOpenedError $ o
Closed -> let
(newObj, newLoc, newLocs, newInv) = applyOpen o curLoc locs inv
newState = gs {gsLocations = newLocs, gsCurrentLocation = newLoc, gsInventory = newInv}
msg = successOpeningObjectMsg newObj (objectContents newObj)
in SaveState newState msg
case open o of
Left errorMsg -> PrintMessage errorMsg
Right newO -> let
(newLoc, newLocs, newInv) = applyOpenedObject newO curLoc locs inv
newState = gs {gsLocations = newLocs, gsCurrentLocation = newLoc, gsInventory = newInv}
msg = successOpeningObjectMsg newO (objectContents newO)
in SaveState newState msg

tryOpen :: Item -> Objects -> Inventory -> GameState -> GameAction
tryOpen item locObjects inv curGS =
Expand Down
93 changes: 57 additions & 36 deletions Objects.hs
Original file line number Diff line number Diff line change
Expand Up @@ -98,46 +98,18 @@ showLeftBracket = head
showRightBracket = head . tail
showDelimiter = last

standartObjectShowingF :: ShowObjectsFunc
standartObjectShowingF = ((\x _ -> showObject x), \_ -> 0, 0)

standartBoundStrs :: ShowObjectsBoundStrings
standartBoundStrs = ["[", "].", ", "]

modifyObjectShowingFunc :: ShowObjectsFunc -> ShowObjectsFunc
modifyObjectShowingFunc (showingLambda, enumChangeF, enumVal) = (showingLambda, enumChangeF, enumChangeF enumVal)

applyObjectShowingF :: ShowObjectsFunc -> Object -> String
applyObjectShowingF (showingLambda, _, enumVal) obj = showingLambda obj enumVal

-- Ïåðå÷èñëÿåò îáúåêòû â âèäå [ñïèñêà]. Åñëè íå ïåðåäàíà ñòðîêà Intro, áóäåò ïîäñòàâëåíà ñòðîêà ïî óìîë÷àíèþ.
describeObjects :: IntroString -> Objects -> String
describeObjects [] = showObjects ([], "\nThere are some objects here: ") standartObjectShowingF standartBoundStrs
describeObjects str = showObjects ([], str) standartObjectShowingF standartBoundStrs

-- Ïîêàçûâàåò îñîáûå ñâîéñòâà îáúåêòîâ (åñëè îíè åñòü).
investigateObjects :: IntroString -> Objects -> String
investigateObjects str = showObjects ([], str) ((\x _ -> printf "\n%s: %s" (showObject x) (objectDescription'. objectName $ x)), \_ -> 0, 0) ["","",""]

-- Ïåðå÷èñëÿåò îáúåêòû èíâåíòàðÿ â âèäå [ñïèñêà]. Åñëè èíâåíòàðü ïóñò, òàê è ñîîáùàåò.
showInventory :: Inventory -> String
showInventory = showObjects ("No objects in your inventory.", "You have: ") standartObjectShowingF standartBoundStrs

-- Ïåðå÷èñëÿåò îáúåêòû â âèäå ïðîíóìåðîâàííîãî ñïèñêà, íà÷èíàþùåãîñÿ ñ 0.
enumerateObjects :: IntroString -> Objects -> String
enumerateObjects str = showObjects ([], str) ((\x n -> printf "\n%d: %s" n (showObject x)), \y -> y + 1, 0) ["","",""]

isItemsEqual :: Item -> Item -> Bool
Combined x1 x2 `isItemsEqual` y = x1 == y || x2 == y
x `isItemsEqual` Combined y1 y2 = y1 == x || y2 == x
x `isItemsEqual` y = x == y
-- Ïîçâîëÿåò ñðàâíèâàòü îáúåêòû ïî èõ ÷àñòè÷íîìó ñîâïàäåíèþ.
isItemsEquivalent :: Item -> Item -> Bool
Combined x1 x2 `isItemsEquivalent` y = x1 == y || x2 == y
x `isItemsEquivalent` Combined y1 y2 = y1 == x || y2 == x
x `isItemsEquivalent` y = x == y

matchedObjects :: Item -> Objects -> Objects
matchedObjects _ [] = []
matchedObjects itm objects = filter (\x -> isItemsEqual (objectItem x) itm) objects
matchedObjects itm objects = filter (\x -> isItemsEquivalent (objectItem x) itm) objects

updateObjects :: Object -> Objects -> Objects
updateObjects obj objects = obj : [newObj | newObj <- objects, (objectName newObj) /= (objectName obj)]
updateObjects obj objects = obj : [newObj | newObj <- objects, newObj /= obj]

----------- Messages, Errors ------------

Expand All @@ -147,8 +119,14 @@ notVisibleObjectError item = printf "You don't see any %s here." (show item)
cannotBeOpenedError :: Object -> String
cannotBeOpenedError obj = printf "The %s cannot be opened." (showObject obj)

cannotBeClosedError :: Object -> String
cannotBeClosedError obj = printf "The %s cannot be closed." (showObject obj)

alreadyOpenedError :: Object -> String
alreadyOpenedError obj = printf "%s already open." (showObject obj)
alreadyOpenedError obj = printf "%s already opened." (showObject obj)

alreadyClosedError :: Object -> String
alreadyClosedError obj = printf "%s already closed." (showObject obj)

successPickupingObjectMsg :: Object -> String
successPickupingObjectMsg obj = showObject obj ++ " added to your inventory."
Expand All @@ -160,3 +138,46 @@ successOpeningObjectMsg :: Object -> Objects -> String
successOpeningObjectMsg obj [] = "Opened."
successOpeningObjectMsg obj (o:[]) = printf "Opening %s reveals %s." (showObject obj) (showObject o)
successOpeningObjectMsg obj os = describeObjects (printf "Opening %s reveals some objects: ") os

instance Openable Object where
open obj = case objectContainerState obj of
Opened -> Left $ alreadyOpenedError obj
Closed -> Right $ obj {objectContainerState = Opened}
NotContainer -> Left $ cannotBeOpenedError obj
close obj = case objectContainerState obj of
Opened -> Right $ obj {objectContainerState = Opened}
Closed -> Left $ alreadyClosedError obj
NotContainer -> Left $ cannotBeClosedError obj
showStated o@(Object _ _ Opened _) = "(opened) " ++ showObject o
showStated o@(Object _ _ Closed _) = "" ++ showObject o
showStated o@(Object _ _ NotContainer _) = showObject o

----------------------- Ôóíêöèè îòîáðàæåíèÿ îáúåêòà è ñïèñêà îáúåêòîâ. ---------------------------
standartObjectShowingF :: ShowObjectsFunc
standartObjectShowingF = ((\x _ -> showStated x), \_ -> 0, 0)

standartBoundStrs :: ShowObjectsBoundStrings
standartBoundStrs = ["[", "].", ", "]

modifyObjectShowingFunc :: ShowObjectsFunc -> ShowObjectsFunc
modifyObjectShowingFunc (showingLambda, enumChangeF, enumVal) = (showingLambda, enumChangeF, enumChangeF enumVal)

applyObjectShowingF :: ShowObjectsFunc -> Object -> String
applyObjectShowingF (showingLambda, _, enumVal) obj = showingLambda obj enumVal

-- Ïåðå÷èñëÿåò îáúåêòû â âèäå [ñïèñêà]. Åñëè íå ïåðåäàíà ñòðîêà Intro, áóäåò ïîäñòàâëåíà ñòðîêà ïî óìîë÷àíèþ.
describeObjects :: IntroString -> Objects -> String
describeObjects [] = showObjects ([], "\nThere are some objects here: ") standartObjectShowingF standartBoundStrs
describeObjects str = showObjects ([], str) standartObjectShowingF standartBoundStrs

-- Ïîêàçûâàåò îñîáûå ñâîéñòâà îáúåêòîâ (åñëè îíè åñòü).
investigateObjects :: IntroString -> Objects -> String
investigateObjects str = showObjects ([], str) ((\x _ -> printf "\n%s: %s" (showObject x) (objectDescription'. objectName $ x)), \_ -> 0, 0) ["","",""]

-- Ïåðå÷èñëÿåò îáúåêòû èíâåíòàðÿ â âèäå [ñïèñêà]. Åñëè èíâåíòàðü ïóñò, òàê è ñîîáùàåò.
showInventory :: Inventory -> String
showInventory = showObjects ("No objects in your inventory.", "You have: ") standartObjectShowingF standartBoundStrs

-- Ïåðå÷èñëÿåò îáúåêòû â âèäå ïðîíóìåðîâàííîãî ñïèñêà, íà÷èíàþùåãîñÿ ñ 0.
enumerateObjects :: IntroString -> Objects -> String
enumerateObjects str = showObjects ([], str) ((\x n -> printf "\n%d: %s" n (showObject x)), \y -> y + 1, 0) ["","",""]
20 changes: 16 additions & 4 deletions Types.hs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ type LongDescribedRooms = Rooms

data Direction = North | South | West | East | NoDirection
deriving (Show, Eq, Read)

data Item =
Combined Item Item
| Phone
Expand All @@ -21,8 +21,12 @@ data Item =
| Table
| Lighter

deriving (Eq, Show, Read)
deriving (Show, Read, Ord)

instance Eq Item where
(Combined i1 i2) == (Combined i3 i4) = i1 == i3 && i2 == i4
x1 == x2 = x1 `compare` x2 == EQ

data ContainerState =
NotContainer
| Opened
Expand All @@ -36,7 +40,10 @@ data Object = Object {
objectName :: ObjectName,
objectContainerState :: ContainerState,
objectContents :: Objects
} deriving (Eq, Show, Read)
} deriving (Show, Read)

instance Eq Object where
(Object item1 name1 _ _) == (Object item2 name2 _ _) = item1 == item2 && name1 == name2

type ObjectIdentifier = (ObjectName, Item)

Expand Down Expand Up @@ -97,4 +104,9 @@ data GameAction =
| QuitGame OutputMessage
| ReadUserInput
| ReadMessagedUserInput InputOutputString InputCommand
| SaveState GameState OutputMessage
| SaveState GameState OutputMessage

class Openable a where
open :: a -> Either String a
close :: a -> Either String a
showStated :: a -> String
2 changes: 1 addition & 1 deletion save.a2g
Original file line number Diff line number Diff line change
@@ -1 +1 @@
GameState {gsLocations = [Location {locRoom = SouthRoom, locPaths = [Path {pathDirection = North, pathRoom = NorthRoom},Path {pathDirection = South, pathRoom = SouthRoom}], locShortDescription = "You are standing in the middle room at the wooden table.", locLongDescription = "Room looks nice: small, clean, beauty. There is phone and papers on the big wooden table. It is rainy and dark behind the window. A lightnings beat to the lighthouse on a mountain.", locObjects = [Object {objectItem = Drawer, objectName = "Drawer", objectContainerState = Opened, objectContents = [Object {objectItem = Lighter, objectName = "Lighter", objectContainerState = NotContainer, objectContents = []}]},Object {objectItem = Phone, objectName = "Digital Phone", objectContainerState = NotContainer, objectContents = []},Object {objectItem = Table, objectName = "Table", objectContainerState = NotContainer, objectContents = []},Object {objectItem = Rope, objectName = "Rope", objectContainerState = NotContainer, objectContents = []},Object {objectItem = Hook, objectName = "Hook", objectContainerState = NotContainer, objectContents = []},Object {objectItem = Umbrella, objectName = "Blue Umbrella", objectContainerState = NotContainer, objectContents = []},Object {objectItem = Phone, objectName = "Broken Phone", objectContainerState = NotContainer, objectContents = []}], locLongDescribed = False},Location {locRoom = NorthRoom, locPaths = [Path {pathDirection = South, pathRoom = SouthRoom},Path {pathDirection = West, pathRoom = Corridor}], locShortDescription = "This is big light room.", locLongDescription = "SouthRoom is the big nice place with many lamps on the walls.", locObjects = [Object {objectItem = Umbrella, objectName = "Blue Umbrella", objectContainerState = NotContainer, objectContents = []}], locLongDescribed = False}], gsCurrentLocation = Location {locRoom = SouthRoom, locPaths = [Path {pathDirection = North, pathRoom = NorthRoom},Path {pathDirection = South, pathRoom = SouthRoom}], locShortDescription = "You are standing in the middle room at the wooden table.", locLongDescription = "Room looks nice: small, clean, beauty. There is phone and papers on the big wooden table. It is rainy and dark behind the window. A lightnings beat to the lighthouse on a mountain.", locObjects = [Object {objectItem = Drawer, objectName = "Drawer", objectContainerState = Opened, objectContents = [Object {objectItem = Lighter, objectName = "Lighter", objectContainerState = NotContainer, objectContents = []}]},Object {objectItem = Phone, objectName = "Digital Phone", objectContainerState = NotContainer, objectContents = []},Object {objectItem = Table, objectName = "Table", objectContainerState = NotContainer, objectContents = []},Object {objectItem = Rope, objectName = "Rope", objectContainerState = NotContainer, objectContents = []},Object {objectItem = Hook, objectName = "Hook", objectContainerState = NotContainer, objectContents = []},Object {objectItem = Umbrella, objectName = "Blue Umbrella", objectContainerState = NotContainer, objectContents = []},Object {objectItem = Phone, objectName = "Broken Phone", objectContainerState = NotContainer, objectContents = []}], locLongDescribed = False}, gsInventory = [Object {objectItem = Umbrella, objectName = "Red Umbrella", objectContainerState = NotContainer, objectContents = []}]}
GameState {gsLocations = [Location {locRoom = SouthRoom, locPaths = [Path {pathDirection = North, pathRoom = NorthRoom},Path {pathDirection = South, pathRoom = SouthRoom}], locShortDescription = "You are standing in the middle room at the wooden table.", locLongDescription = "Room looks nice: small, clean, beauty. There is phone and papers on the big wooden table. It is rainy and dark behind the window. A lightnings beat to the lighthouse on a mountain.", locObjects = [Object {objectItem = Drawer, objectName = "Drawer", objectContainerState = Opened, objectContents = [Object {objectItem = Lighter, objectName = "Lighter", objectContainerState = NotContainer, objectContents = []}]},Object {objectItem = Phone, objectName = "Digital Phone", objectContainerState = NotContainer, objectContents = []},Object {objectItem = Umbrella, objectName = "Red Umbrella", objectContainerState = NotContainer, objectContents = []},Object {objectItem = Table, objectName = "Table", objectContainerState = NotContainer, objectContents = []},Object {objectItem = Rope, objectName = "Rope", objectContainerState = NotContainer, objectContents = []},Object {objectItem = Hook, objectName = "Hook", objectContainerState = NotContainer, objectContents = []},Object {objectItem = Umbrella, objectName = "Blue Umbrella", objectContainerState = NotContainer, objectContents = []},Object {objectItem = Phone, objectName = "Broken Phone", objectContainerState = NotContainer, objectContents = []}], locLongDescribed = False},Location {locRoom = NorthRoom, locPaths = [Path {pathDirection = South, pathRoom = SouthRoom},Path {pathDirection = West, pathRoom = Corridor}], locShortDescription = "This is big light room.", locLongDescription = "SouthRoom is the big nice place with many lamps on the walls.", locObjects = [Object {objectItem = Umbrella, objectName = "Blue Umbrella", objectContainerState = NotContainer, objectContents = []}], locLongDescribed = False}], gsCurrentLocation = Location {locRoom = SouthRoom, locPaths = [Path {pathDirection = North, pathRoom = NorthRoom},Path {pathDirection = South, pathRoom = SouthRoom}], locShortDescription = "You are standing in the middle room at the wooden table.", locLongDescription = "Room looks nice: small, clean, beauty. There is phone and papers on the big wooden table. It is rainy and dark behind the window. A lightnings beat to the lighthouse on a mountain.", locObjects = [Object {objectItem = Drawer, objectName = "Drawer", objectContainerState = Opened, objectContents = [Object {objectItem = Lighter, objectName = "Lighter", objectContainerState = NotContainer, objectContents = []}]},Object {objectItem = Phone, objectName = "Digital Phone", objectContainerState = NotContainer, objectContents = []},Object {objectItem = Umbrella, objectName = "Red Umbrella", objectContainerState = NotContainer, objectContents = []},Object {objectItem = Table, objectName = "Table", objectContainerState = NotContainer, objectContents = []},Object {objectItem = Rope, objectName = "Rope", objectContainerState = NotContainer, objectContents = []},Object {objectItem = Hook, objectName = "Hook", objectContainerState = NotContainer, objectContents = []},Object {objectItem = Umbrella, objectName = "Blue Umbrella", objectContainerState = NotContainer, objectContents = []},Object {objectItem = Phone, objectName = "Broken Phone", objectContainerState = NotContainer, objectContents = []}], locLongDescribed = False}, gsInventory = [Object {objectItem = Drawer, objectName = "Drawer", objectContainerState = Opened, objectContents = [Object {objectItem = Lighter, objectName = "Lighter", objectContainerState = NotContainer, objectContents = []}]}]}

0 comments on commit c5a2bf0

Please sign in to comment.