-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmodel.py
154 lines (120 loc) · 4.39 KB
/
model.py
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
import board
l_orientations = [
[(0, 1), (1, 1), (2, 1), (2, 2)],
[(1, 0), (1, 1), (1, 2), (0, 2)],
[(2, 1), (1, 1), (0, 1), (0, 0)],
[(1, 2), (1, 1), (1, 0), (2, 0)]
]
i_orientations = [
[(0, 1), (1, 1), (2, 1), (3, 1)],
[(1, 0), (1, 1), (1, 2), (1, 3)]
]
sq_orientations = [[(0, 1), (1, 1), (1, 0), (0, 0)]]
three_orientations = [
[(0, 1), (1, 1), (2, 1), (1, 2)],
[(1, 0), (1, 1), (1, 2), (0, 1)],
[(1, 1), (1, 1), (0, 1), (0, 0)],
[(1, 2), (1, 1), (1, 0), (1, 0)]
]
z_orientations = [
[(0, 0), (0, 1), (1, 1), (1, 2)],
[(2, 0), (1, 1), (2, 1), (1, 2)]
]
s_orientations = [
[(2, 0), (0, 1), (1, 1), (1, 0)],
[(1, 0), (1, 1), (2, 1), (2, 2)]
]
rl_orientations = [
[(0, 1), (1, 1), (2, 1), (2, 0)],
[(1, 0), (1, 1), (1, 2), (2, 0)],
[(2, 1), (1, 1), (0, 1), (0, 0)],
[(1, 2), (1, 1), (1, 0), (0, 2)]
]
ALL_PIECES = [
l_orientations,
i_orientations,
sq_orientations,
three_orientations,
z_orientations,
s_orientations,
rl_orientations,
]
#
# Current Coord is the top-left corner of the bounding box
# That way, we can check what happens if we drop the entire
# box down by one (or left or whatever) and see if it fits
#
class Piece(object):
def __init__(self, character, orientations, initial_coord, game_board):
self.character = character
self.orientations = orientations
self.current_orientation = 0
self.current_coord = initial_coord
self.game_board = game_board
def __iter__(self):
return iter(self.board_coords())
def rotate_right(self):
self.current_orientation += 1
if self.current_orientation == len(self.orientations):
self.current_orientation = 0
def rotate_left(self):
self.current_orientation -= 1
if self.current_orientation < 0:
self.current_orientation = len(self.orientations) - 1
def move(self, vector):
x, y = self.current_coord
dx, dy = vector
self.current_coord = (x + dx, y + dy)
def drop(self):
x, y = self.current_coord
self.current_coord = (x, y + 1)
def move_left(self):
x, y = self.current_coord
self.current_coord = (x - 1, y)
def move_right(self):
x, y = self.current_coord
self.current_coord = (x + 1, y)
def orientation(self):
return self.orientations[self.current_orientation]
def board_coords(self):
return self.coords_offset_by(self.orientation(), self.current_coord)
def coord_offset_by(self, coord, vector):
x, y = coord
dx, dy = vector
return (x + dx, y + dy)
def coords_offset_by(self, coords, vector):
return [self.coord_offset_by(c, vector) for c in coords]
def repositioned(self, vector):
return self.coords_offset_by(self.orientation(), vector)
def can_drop(self):
new_orientation = self.coords_offset_by(self.repositioned((0, 1)), self.current_coord)
if any(coord not in self.game_board for coord in new_orientation):
return False
if any(self.game_board[coord] for coord in new_orientation):
return False
return True
def can_go_left(self):
new_orientation = self.coords_offset_by(self.repositioned((-1, 0)), self.current_coord)
if any(coord not in self.game_board for coord in new_orientation):
return False
if any(self.game_board[coord] for coord in new_orientation):
return False
return True
def can_go_right(self):
new_orientation = self.coords_offset_by(self.repositioned((+1, 0)), self.current_coord)
if any(coord not in self.game_board for coord in new_orientation):
return False
if any(self.game_board[coord] for coord in new_orientation):
return False
return True
class TetrisBoard(board.Board):
def move_piece(self, piece, vector):
for coord in piece.board_coords:
del self[coord]
piece.move(vector)
for coord in piece.board_coords:
self[coord] = piece.character
if __name__ == '__main__':
b = TetrisBoard((10, 20))
l_shape = Piece("*", l_orientations, (0, 0), b)
three_shape = Piece("+", three_orientations, (0, 0), b)