-
Notifications
You must be signed in to change notification settings - Fork 0
/
engine_old_no_spots.py
194 lines (165 loc) · 6.28 KB
/
engine_old_no_spots.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
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
import random
class Engine:
def __init__(self):
self.size = 4
self.board = [[0 for i in range(self.size)] for i in range(self.size)]
self.score = 0
##self.moved = False
#self.mergedList = []
self.numMoves = 0
self.moveList = ['d','l','u','r']
self.addRandBlock()
self.addRandBlock()
def scoreBonus(self, val):
"""
Returns the score to add when tile merged
"""
score = {
2: 4,
4: 8,
8: 16,
16: 32,
32: 64,
64: 128,
128: 256,
256: 512,
512: 1024,
1024: 2048,
2048: 4096,
4096: 8192,
8192: 16384,
16384: 32768,
32768: 65536,
65536: 131072,
}
return score[val]
def rotateBoard(self, board, count): ### gc opt this part with the aim to improve perfermance
"""
Rotate the board in order to make moves in different directions
"""
rotated = [[0 for i in range(self.size)] for i in range(self.size)]
if count == 0: ## anticlockwise or left rotate 90 degree
for row in range(self.size):
for col in range(self.size):
rotated[row][col] = board[row][col]
elif count == 1: ## anticlockwise or left rotate 90 degree
for row in range(self.size):
for col in range(self.size):
rotated[self.size - col - 1][row] = board[row][col]
elif count == 2: ## rotate 180
for row in range(self.size):
for col in range(self.size):
rotated[self.size - row - 1][self.size - col - 1] = board[row][col]
elif count == 3: ## clockwise or right rotate 90 degree
rotated = [[0 for i in range(self.size)] for i in range(self.size)]
for row in range(self.size):
for col in range(self.size):
rotated[col][self.size - row - 1] = board[row][col] ## row==old_col,col==old_row
board = rotated
return rotated
def makeMove(self, moveDir):
"""
Shift the board to make the given move
"""
# Check if the game is already over
if self.gameOver():
pass
board = self.board
# Set how many rotations based on the move
rotateCount = self.moveList.index(moveDir)
moved = False
# Rotate board to orient the board downwards
if rotateCount:
board = self.rotateBoard(board, rotateCount)
#make an array to track merged tiles
merged = [[0 for i in range(self.size)] for i in range(self.size)]
for row in range(self.size - 1):
for col in range(self.size):
currentTile = board[row][col]
nextTile = board[row+1][col]
#go to next tile if current tile is empty
if not currentTile:
continue
#if next position is empty, move all tiles down
if not nextTile:
for x in range(row+1):
board[row-x+1][col] = board[row-x][col]
board[0][col] = 0
moved = True
continue
#if tile was merged already, go to next tile
if merged[row][col]:
#self.mergedList.append([row,col])
continue
if currentTile == nextTile:
#if three consecutive tiles of same value, dont merge first two
if (row < self.size - 2 and nextTile == board[row+2][col]):
continue
#merge tiles and set new value, shift all other tiles down
board[row+1][col] *= 2
for x in range(row):
board[row-x][col] = board[row-x-1][col]
board[0][col] = 0
#mark tile as merged and add appropriate score
merged[row+1][col] = 1
self.score += self.scoreBonus(currentTile)
moved = True
#return board to original orientation
if rotateCount:
board = self.rotateBoard(board, 4 - rotateCount)
self.board = board
#if tiles were moved, increment number of moves and add a random block
if moved: ## if not moved, then move up
self.numMoves += 1
self.addRandBlock()
#self.moved = True
return True
return False
def must_makeMove(self, moveDir):
if self.gameOver():
return False
_bool = self.makeMove(moveDir)
if _bool:
return True
else:
for moveDir in ['d','r','l','u']:
_bool = self.makeMove(moveDir)
if _bool:
return True
return False
def addRandBlock(self, val=None):
"""
Places a random tile (either 2 or 4) on the board
tile = 4: 10 percent chance
tile = 2: 90 percent chance
"""
avail = self.availableSpots()
if avail:
(row, column) = avail[random.randint(0, len(avail) - 1)]
if random.randint(0,9) == 9:
self.board[row][column] = 4
else:
self.board[row][column] = 2
def availableSpots(self):
"""
Returns a list of all empty spaces on the board
"""
spots = []
for row in enumerate(self.board):
for col in enumerate(row[1]):
if col[1] == 0:
spots.append((row[0], col[0]))
return spots
def gameOver(self):
"""
Returns True if no move can be made
"""
if self.availableSpots():
return False
board = self.board
for row in range(self.size):
for col in range(self.size):
if (row < self.size - 1 and board[row][col] == board[row+1][col]) \
or (col < self.size - 1 and board[row][col] == board[row][col+1]):
return False
return True