-
Notifications
You must be signed in to change notification settings - Fork 0
/
Room.hs
86 lines (69 loc) · 3.45 KB
/
Room.hs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
module Room (Room,buildRoom,buildEmptyRoom,mergeRoom,r_id,passage,contents,setSinglePassage,mergePassage,getPassAsStr,getPassageText,charDirToStr) where
import Data.List(nub,intersperse)
type Passage = [[Bool]]
--Contents key: 0 - bottomless pit, 1 - bats
data Room = Room {r_id :: Int, passage :: Passage, contents :: [Int]} deriving (Eq)
buildRoom :: Int -> Passage -> [Int] -> Room
buildRoom a b c = Room a (setPassage b) c
buildEmptyRoom :: Room
buildEmptyRoom = Room (-1) (setPassage [[False,False,False],[False,False,False],[False,False,False]]) []
setPassage :: Passage -> Passage
setPassage p
| length p /= 3 = error "Passage must have 3 rows."
| foldr (||) False (map ((/=3) . length) p) = error "Passage must have 3 columns in each row."
| otherwise = p
mergePassage :: (Bool->Bool->Bool) -> Passage -> Passage -> Passage
mergePassage c (a:as) (b:bs)
| null as || null bs = [mergeRow a b]
| otherwise = (mergeRow a b):(mergePassage c as bs)
where
mergeRow (x:xs) (y:ys) | null xs || null ys = [c x y]
| otherwise = (c x y):(mergeRow xs ys)
mergeRoom :: Room -> Room -> Maybe Room
mergeRoom r1 r2
| r_id r1 < 0 && r_id r2 < 0 = Nothing
| r_id r1 < 0 = Just $ buildRoom (r_id r2) (mergePassage (||) (passage r1) (passage r2)) (nub $ concat [contents r1, contents r2])
| otherwise = Just $ buildRoom (r_id r1) (mergePassage (||) (passage r1) (passage r2)) (nub $ concat [contents r1, contents r2])
setSinglePassage :: Char -> Passage
setSinglePassage c =
case c of
'n' -> setPassage [[False,True,False],[False,False,False],[False,False,False]]
'e' -> setPassage [[False,False,False],[False,False,True],[False,False,False]]
's' -> setPassage [[False,False,False],[False,False,False],[False,True,False]]
'w' -> setPassage [[False,False,False],[True,False,False],[False,False,False]]
_ -> setPassage [[False,False,False],[False,False,False],[False,False,False]]
unsetSinglePassage :: Char -> Passage
unsetSinglePassage c = map (map not) $ setSinglePassage c
-- returns a list of the full names of passages (North, South, East, West)
getFullPassList :: Room -> [String]
getFullPassList r = map charDirToStr $ getPassAsStr r
charDirToStr :: Char -> String
charDirToStr c =
case c of
'n' -> "North"
's' -> "South"
'e' -> "East"
'w' -> "West"
getPassageText :: Room -> String
getPassageText r
| numPass == 1 = ("There is a passage to the " ++ (head passages) ++ ".")
| numPass == 2 = ("There are passages to the " ++ (head passages) ++ " and " ++ (last passages) ++ ".")
| otherwise = ("There are passages to the " ++ (getPText passages) ++ ".")
where
passages = getFullPassList r
numPass = length passages
getPText (p:ps)
| null ps = ("and " ++ p)
| otherwise = (p ++ ", " ++ getPText ps)
getPText _ = ""
getPassAsStr :: Room -> String
getPassAsStr r = (concat $ map getPassAtIndex [(0,1),(1,0),(1,2),(2,1)])
where
p = passage r
getPassAtIndex iii | iii == (0,1) && ((!!) ((!!) p (fst iii)) (snd iii)) = "n"
| iii == (1,0) && ((!!) ((!!) p (fst iii)) (snd iii)) = "w"
| iii == (1,2) && ((!!) ((!!) p (fst iii)) (snd iii)) = "e"
| iii == (2,1) && ((!!) ((!!) p (fst iii)) (snd iii)) = "s"
| otherwise = ""
instance Show Room where
show a = "<id:" ++ (show $ r_id a) ++ "," ++ "pass:" ++ getPassAsStr a ++ ",[" ++ ( intersperse ','$ concat $ map show (contents a) ) ++ "]>"