-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathboard.py
155 lines (135 loc) · 5.28 KB
/
board.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
155
import copy, random
from tetromino import *
from direction import *
from rotation import *
class Board:
_lineScores = (0, 1, 3, 5, 8)
def emptyGrid(self):
self.grid = {}
self.emptyRow = []
for x in range(self.width):
self.emptyRow.append(0)
for rowCount in range(self.height):
gridRow = {rowCount : copy.copy(self.emptyRow)}
self.grid.update(gridRow)
def __init__(self, colour = "Gray"):
self.colour = colour
self.width = 10
self.height = 21
self.heldPiece = None
self.startInterval = 1000
self.score = 0
self.linesCleared = 0
self.level = 1
self.levelScore = 0
self.emptyGrid()
self.holeCount = None
self.pieceList = []
def setHeldPiece(self, tetromino):
self.heldPiece = Tetromino(tetromino.shape, tetromino.rotations, tetromino.colour)
def isHeldPieceEmpty(self):
return (self.heldPiece == None)
def swapWithHeldPiece(self, tetromino):
copyTetromino = copy.deepcopy(tetromino)
tetromino = copy.deepcopy(self.heldPiece)
self.centrePiece(tetromino)
tetromino.incrementCoords(copyTetromino.xOffset, copyTetromino.yOffset)
self.setHeldPiece(copyTetromino)
return (tetromino)
def centrePiece(self, tetromino):
tetromino.centre[0] = tetromino.centre[0] + (self.width/2) - 2
for coord in tetromino.vertexCoords:
coord[0] += (self.width/2) - 2
for coord in tetromino.blockCoords:
coord[0] += (self.width/2) - 2
def generatePiece(self):
if (len(self.pieceList) == 0):
self.pieceList = list(Tetromino._allShapes.keys())
random.shuffle(self.pieceList)
tetromino = Tetromino(self.pieceList.pop())
self.centrePiece(tetromino)
return (tetromino)
def isOutOfBounds(self, tetromino):
minX = tetromino.getMinXCoord()
maxX = tetromino.getMaxXCoord()
minY = tetromino.getMinYCoord()
maxY = tetromino.getMaxYCoord()
if (minX < 0) or (minY < 0) or (maxX > self.width) or (maxY > self.height):
return True
else:
return False
def moveOrLockPiece(self, tetromino, direction, count = 1):
x = direction.value[0]
y = direction.value[1]
for i in range(count):
tetromino.incrementCoords(x, y)
if (self.isOutOfBounds(tetromino) or self.isGridBlocked(tetromino)):
tetromino.incrementCoords(-x,-y)
if (y > 0):
self.lockPieceOnGrid(tetromino)
clearedRowCount = self.clearFullRows()
self.updateScores(clearedRowCount)
return True
return False
def updateScores(self, clearedRowCount):
self.linesCleared += clearedRowCount
self.score += (self._lineScores[clearedRowCount] * self.level)
if (self.level < 15):
self.level = (self.linesCleared // 10) + 1
def getDropInterval(self):
scale = pow(0.8, self.level)
dropInterval = int(self.startInterval * scale)
return dropInterval
def isGridBlocked(self, tetromino):
for coord in tetromino.blockCoords:
y = int(coord[1])
x = int(coord[0])
if self.grid[y][x] != 0:
return True
return False
def lockPieceOnGrid(self, tetromino):
for coord in tetromino.blockCoords:
y = int(coord[1])
x = int(coord[0])
self.grid[y][x] = copy.copy(tetromino.colour)
def clearFullRows(self):
fullRowCount = 0
y = self.height - 1
while (y > 0):
emptyBlocks = 0
for x in range(self.width):
if self.grid[y][x] == 0:
emptyBlocks +=1
if emptyBlocks == self.width:
return fullRowCount
elif emptyBlocks == 0:
fullRowCount += 1
self.grid[y] = copy.copy(self.emptyRow)
for i in range (y, 1, -1):
self.grid[i] = copy.deepcopy(self.grid[i-1])
y += 1
y-=1
return fullRowCount
def rotatePiece(self, tetromino, rotation = None, count = 1):
for i in range(count):
tetromino.rotateCoords(rotation)
if (self.isOutOfBounds(tetromino) or self.isGridBlocked(tetromino)):
tetromino.rotateCoords(-rotation)
break
def newPieceOrGameOver(self, tetromino):
if (tetromino.xOffset == 0) and (tetromino.yOffset == 0):
return None
else:
tetromino = self.generatePiece()
return tetromino
def dropAndLockPiece(self, tetromino):
isLocked = False
while (not isLocked):
isLocked = self.moveOrLockPiece(tetromino,Direction.DOWN)
def dropPieceWithoutLock(self, tetromino):
while not ((self.isOutOfBounds(tetromino) or self.isGridBlocked(tetromino))):
tetromino.incrementCoords(0, 1)
tetromino.incrementCoords(0, -1)
def moveLeftAndLockPiece(self, tetromino, count):
self.moveOrLockPiece(tetromino, Direction.LEFT, count)
self.dropAndLockPiece(tetromino)