[Tutor] Improving My Simple Game Code for Speed, Memory and Learning
WolfRage
wolfrage8765 at gmail.com
Tue Jan 13 04:29:46 CET 2015
Updated the code to now allow for a fill_rows optional argument for
Grid, that determines how many rows are filled with values.
I have also added some experimental code to invert the dropping, as in
all of the values can float to the top. Other code is even more
experimental and not yet working right that pulls the nodes to the right
or left, with hope of being able to apply gravity in all 4 directions.
But I still need to work out the bugs. Any help is greatly appreciated.
Thanks for all of the contributions so far.
#CODE BELOW
import random
class GameTile():
def __init__(self, col, row, values=None, value=None, **kwargs):
# values is not required because the value can be directly set.
# This is to support a future feature that will allow me to build a
# board off of a list.
# id is grid(X,Y) which is equal to grid(col,row)
self.id = str(col) + ',' + str(row)
self.col = col
self.row = row
if value is None:
value = random.choice(values)
self.value = value
self.eliminated = False
# hide_anim = hidden for animation purposes
self.hide_anim = False
# drop_value = value to be dropped during animation
self.drop_value = None
# drop_to could have inversely been a drop_from
# drop_to = the id of where the value should be dropped too.
self.drop_to = None
def __str__(self):
return "%2d" % self.value
class GameGrid():
def __init__(self, cols=8, rows=7, fill_rows=None, **kwargs):
if cols < 3 or rows < 3:
raise ValueError('Minimum board size is 3x3! %sx%s is too
small.'
% (cols, rows))
if fill_rows > rows:
string = 'Can not fill more rows than actual rows ' + \
'exist. fill_rows=%s rows=%s'
raise ValueError(string % (fill_rows, rows))
self.cols = cols
self.rows = rows
self.values = [5, 6, 11, 19, 20]
self.make_grid(fill_rows)
def __str__(self):
output = []
for row in self.transposed_grid:
s = '| '
for node in row:
s += str(node) + ' | '
output.append(s)
return '\n'.join(output)
def make_grid(self, fill_rows=None):
# grid is 2d array as x, y ie [x][y].
# transposed_grid is 2d array as y, x ie [y][x]
self.transposed_grid = []
for row_num in range(self.rows):
if fill_rows is None:
values = self.values
elif row_num < self.rows - fill_rows:
values = [0, ]
else:
values = self.values
row = [GameTile(col_num, row_num, values)
for col_num in range(self.cols)]
self.transposed_grid.append(row)
self.grid = list(zip(*self.transposed_grid))
def draw(self):
print(self)
def draw_by_id(self):
# Why does this one use self.transposed_grid instead of self.grid ?
output = []
for row in self.transposed_grid:
s = '| '
for node in row:
s += str(node.id) + ' | '
output.append(s)
return '\n'.join(output)
def draw_by_id_proc(self):
# Draw Procedurally
output = []
for row_num in range(self.rows):
s = '| '
for col_num in range(self.cols):
s += (str(self.grid[col_num][row_num].id) + '(' +
str(col_num) +
',' + str(row_num) + ')' + ' | ')
output.append(s)
return '\n'.join(output)
def draw_by_id_trans(self):
# Why does this one use self.grid instead of self.transposed_grid ?
output = []
for col in self.grid:
s = '| '
for node in col:
s += str(node.id) + ' | '
output.append(s)
return '\n'.join(output)
def draw_by_id_trans_proc (self):
# Draw Transposed & Procedurally
output = []
for col_num in range(self.cols):
s = '| '
for row_num in range(self.rows):
s += (str(self.transposed_grid[row_num][col_num].id) +
'(' +
str(col_num) + ',' + str(row_num) + ')' + ' | ')
output.append(s)
return '\n'.join(output)
def find_eliminations(self):
#First Down the columns.
i = 0
for col_list in self.grid:
while True:
try:
if self.check_total(col_list[i: i + 3]):
self.eliminate(col_list[i: i + 3])
i += 1
except ValueError:
i = 0
break
# Now across the rows.
for row_list in self.transposed_grid:
while True:
try:
if self.check_total(row_list[i: i + 3]):
self.eliminate(row_list[i: i + 3])
i += 1
except ValueError:
i = 0
break
# Set all eliminated nodes to a value of 0.
for col in self.transposed_grid:
for node in col:
if node.eliminated is True:
node.eliminated = False
node.value = 0
def check_total(self, slices):
first, second, third = slices
if first.value == second.value or second.value == third.value:
total = first.value + second.value + third.value
return total in (17, 21, 28, 29, 31, 42, 45, 46, 49, 58)
def eliminate(self, slices):
first, second, third = slices
first.eliminated = True
second.eliminated = True
third.eliminated = True
def drop_nodes(self):
i = self.rows
# first_zero_row serves as memory for how far to drop non-zero
values
first_zero_row = None
for col_list in self.grid:
while True:
# Low is on Top it is low because it is the lower
numbered row
# High is on Bottom it is high because it is the higher
numbered
low, high = col_list[i - 2: i] # Goes Up the Rows
if high.value == 0:
if low.value != 0:
if first_zero_row is None:
high.value = low.value
low.value = 0
first_zero_row = low
else:
first_zero_row.value = low.value
low.value = 0
row = first_zero_row.row - 1
col = first_zero_row.col
first_zero_row = self.grid[col][row]
else:
if first_zero_row is None:
first_zero_row = high
i -= 1
if i == 1:
i = self.rows
first_zero_row = None
break
def invert_drop_nodes(self):
i = 0
# first_zero_row serves as memory for how far to drop non-zero
values
first_zero_row = None
for col_list in self.grid:
while True:
# Low is on Top it is low because it is the lower
numbered row
# High is on Bottom it is high because it is the higher
numbered
low, high = col_list[i: i + 2] # Goes Down the Rows
if low.value == 0:
if high.value != 0:
if first_zero_row is None:
low.value = high.value
high.value = 0
first_zero_row = high
else:
first_zero_row.value = high.value
high.value = 0
row = first_zero_row.row + 1
col = first_zero_row.col
first_zero_row = self.grid[col][row]
else:
if first_zero_row is None:
first_zero_row = low
i += 1
if i == self.rows - 1:
i = 0
first_zero_row = None
break
def pull_nodes(self):
i = self.cols
# first_zero_row serves as memory for how far to drop non-zero
values
first_zero_row = None
for row_list in self.transposed_grid:
while True:
# Low is on Top it is low because it is the lower
numbered row
# High is on Bottom it is high because it is the higher
numbered
low, high = row_list[i - 2: i] # Goes Up the Columns
if high.value == 0:
if low.value != 0:
if first_zero_row is None:
high.value = low.value
low.value = 0
first_zero_row = low
else:
first_zero_row.value = low.value
low.value = 0
try:
row = first_zero_row.row - 1 # Testing
Here
col = first_zero_row.col # Or Here?
first_zero_row =
self.transposed_grid[col][row]
except:
i = self.cols
print('broke', col, row)
print(first_zero_row.col,
first_zero_row.row)
first_zero_row = None
break
else:
if first_zero_row is None:
first_zero_row = high
i -= 1
if i == 1:
i = self.cols
first_zero_row = None
break
def invert_pull_nodes(self):
i = 0
# first_zero_row serves as memory for how far to drop non-zero
values
first_zero_row = None
for row_list in self.transposed_grid:
while True:
# Low is on Top it is low because it is the lower
numbered row
# High is on Bottom it is high because it is the higher
numbered
low, high = row_list[i: i + 2] # Goes Down the Columns
if low.value == 0:
if high.value != 0:
if first_zero_row is None:
low.value = high.value
high.value = 0
first_zero_row = high
else:
first_zero_row.value = high.value
high.value = 0
try:
row = first_zero_row.row # Testing Here
col = first_zero_row.col + 1 # Or Here?
first_zero_row =
self.transposed_grid[col][row]
except:
i = 0
print('broke', col, row)
print(first_zero_row.col,
first_zero_row.row)
first_zero_row = None
break
else:
if first_zero_row is None:
first_zero_row = low
i += 1
if i == self.cols - 1:
i = 0
first_zero_row = None
break
grid = GameGrid(4, 8, 6)
print(grid)
grid.find_eliminations()
print('After Eliminations')
print(grid)
grid.drop_nodes()
print('After Drops')
print(grid)
grid.invert_drop_nodes()
print('Reverse Gravity aka Inverted')
print(grid)
#grid.pull_nodes()
#print('Pull Nodes')
#print(grid)
#grid.invert_pull_nodes()
#print('Invert Pull Nodes')
#print(grid)
print(grid.draw_by_id())
More information about the Tutor
mailing list