-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathShapes
More file actions
161 lines (123 loc) · 3.99 KB
/
Copy pathShapes
File metadata and controls
161 lines (123 loc) · 3.99 KB
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
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
-- | Types and functions for shapes. The list of all tetris pieces.
module Shapes where
import Data.List(transpose)
import Data.Maybe(isNothing)
import Test.QuickCheck
-- * Shapes
type Square = Maybe Colour
data Colour = Black | Red | Green | Yellow | Blue | Purple | Cyan | Grey
deriving (Eq,Bounded,Enum,Show)
-- | A geometric shape is represented as a list of lists of squares. Each square
-- can be empty or filled with a block of a specific colour.
data Shape = S [Row] deriving (Eq)
type Row = [Square]
rows :: Shape -> [Row]
rows (S rs) = rs
-- * Showing shapes
showShape :: Shape -> String
showShape s = unlines [showRow r | r <- rows s]
where
showRow :: Row -> String
showRow r = [showSquare s | s <- r]
showSquare Nothing = '.'
showSquare (Just Black) = '#' -- can change to '█' on linux/mac
showSquare (Just Grey) = 'g' -- can change to '▓'
showSquare (Just c) = head (show c)
instance Show Shape where
show = showShape
showList ss r = unlines (map show ss)++r
-- * The shapes used in the Tetris game
-- | All 7 tetrominoes (all combinations of connected 4 blocks),
-- see <https://en.wikipedia.org/wiki/Tetromino>
allShapes :: [Shape]
allShapes = [S (makeSquares s) | s <- shapes]
where
makeSquares = map (map colour)
colour c = lookup c [('I',Red),('J',Grey),('T',Blue),('O',Yellow),
('Z',Cyan),('L',Green),('S',Purple)]
shapes =
[["I",
"I",
"I",
"I"],
[" J",
" J",
"JJ"],
[" T",
"TT",
" T"],
["OO",
"OO"],
[" Z",
"ZZ",
"Z "],
["LL",
" L",
" L"],
["S ",
"SS",
" S"]]
-- * Some simple functions
-- ** A01
emptyShape :: (Int,Int) -> Shape
emptyShape = error "A01 emptyShape undefined"
emptyRow :: Int -> Row
emptyRow n = replicate n colour
-- ** A02
-- | The size (width and height) of a shape
shapeSize :: Shape -> (Int,Int)
shapeSize = error "A02 shapeSize undefined"
-- ** A03
-- | Count how many non-empty squares a shape contains
blockCount :: Shape -> Int
blockCount = error "A03 blockCount undefined"
-- * The Shape invariant
-- ** A04
-- | Shape invariant (shapes have at least one row, at least one column,
-- and are rectangular)
prop_Shape :: Shape -> Bool
prop_Shape = error "A04 prop_Shape undefined"
-- * Test data generators
-- ** A05
-- | A random generator for colours
rColour :: Gen Colour
rColour = error "A05 rColour undefined"
instance Arbitrary Colour where
arbitrary = rColour
-- ** A06
-- | A random generator for shapes
rShape :: Gen Shape
rShape = error "A06 rShape undefined"
instance Arbitrary Shape where
arbitrary = rShape
-- * Transforming shapes
-- ** A07
-- | Rotate a shape 90 degrees
rotateShape :: Shape -> Shape
rotateShape = error "A07 rotateShape undefined"
-- ** A08
-- | shiftShape adds empty squares above and to the left of the shape
shiftShape :: (Int,Int) -> Shape -> Shape
shiftShape = error "A08 shiftShape undefined"
-- ** A09
-- | padShape adds empty sqaure below and to the right of the shape
padShape :: (Int,Int) -> Shape -> Shape
padShape = error "A09 padShape undefined"
-- ** A10
-- | pad a shape to a given size
padShapeTo :: (Int,Int) -> Shape -> Shape
padShapeTo = error "A10 padShapeTo undefined"
-- * Comparing and combining shapes
-- ** B01
-- | Test if two shapes overlap
overlaps :: Shape -> Shape -> Bool
s1 `overlaps` s2 = error "A11 overlaps undefined"
-- ** B02
-- | zipShapeWith, like 'zipWith' for lists
zipShapeWith :: (Square->Square->Square) -> Shape -> Shape -> Shape
zipShapeWith = error "A12 zipShapeWith undefined"
-- ** B03
-- | Combine two shapes. The two shapes should not overlap.
-- The resulting shape will be big enough to fit both shapes.
combine :: Shape -> Shape -> Shape
s1 `combine` s2 = error "A13 zipShapeWith undefined"