Re: [Tutor] Improving My Simple Game Code for Speed, Memory and Learning

2015-01-12 Thread WolfRage
So I was write as I suspected; the grid is not actually being built like 
I thought it was. Sure the ID's print fine but when the grid positions 
are procedurally accessed the program fails with IndexError.


python3 test1.py
| 19 |  5 |  5 |  5 |
| 11 |  6 | 19 | 11 |
|  6 |  6 | 11 | 19 |
| 11 | 20 |  6 |  5 |
| 11 |  5 | 20 |  5 |
| 20 | 20 | 11 | 11 |
| 19 | 19 |  5 |  5 |
| 11 | 19 | 19 |  5 |
After Eliminations
|  0 |  0 |  0 |  5 |
| 11 |  0 | 19 | 11 |
|  0 |  0 | 11 |  0 |
|  0 | 20 |  6 |  0 |
|  0 |  5 | 20 |  0 |
|  0 |  0 |  0 |  0 |
| 19 |  0 |  0 |  0 |
|  0 |  0 |  0 |  0 |
broke 0 5
0 6
broke 1 6
1 7
broke 2 6
2 7
broke 3 6
3 7
After Drops
|  0 |  0 |  0 |  5 |
|  0 |  0 | 19 |  0 |
|  0 |  0 | 11 |  0 |
|  0 | 20 |  6 |  0 |
|  0 |  0 |  0 |  0 |
|  0 |  0 |  0 |  0 |
| 11 |  0 |  0 |  0 |
| 19 |  5 | 20 | 11 |
Normal
| 0,0 | 1,0 | 2,0 | 3,0 |
| 0,1 | 1,1 | 2,1 | 3,1 |
| 0,2 | 1,2 | 2,2 | 3,2 |
| 0,3 | 1,3 | 2,3 | 3,3 |
| 0,4 | 1,4 | 2,4 | 3,4 |
| 0,5 | 1,5 | 2,5 | 3,5 |
| 0,6 | 1,6 | 2,6 | 3,6 |
| 0,7 | 1,7 | 2,7 | 3,7 |
Procedurally
# The first printed pair is the id, the second pair in parentheses is
# the procedurally accessed id, which should be all ordered as (column,
# row)
| 0,0 (0,0) | 1,0 (0,1) | 2,0 (0,2) | 3,0 (0,3) | Traceback (most recent 
call last):

  File "test1.py", line 186, in 
grid.draw_by_id_proc()
  File "test1.py", line 75, in draw_by_id_proc
print(self.grid[col_num][row_num].id, '(' + str(col_num) + ',' + 
str(row_num) + ')', end=' | ')

IndexError: list index out of range


I am attempting to fix it now. Any help is appreciated.

#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, **kwargs):
if cols < 3 or rows < 3:
raise ValueError("Minimum board size is 3x3! %sx%s is too 
small."

 % (cols, rows))
self.cols = cols
self.rows = rows
self.values = [5, 6, 11, 19, 20]
self.make_grid()

def make_grid(self):
# grid is 2d array as x, y ie [x][y].
self.grid = []
for row_num in range(self.rows):
# Do you still think this needs to be broken into a smaller 
method?

row = [GameTile(col_num, row_num, self.values)
   for col_num in range(self.cols)]
self.grid.append(row)
self.transposed_grid = list(zip(*self.grid))

def draw(self):
for col in self.grid:
print(end='| ')
for node in col:
print(node, end=' | ')
print()

def draw_by_id(self):
for col in self.grid:
print(end='| ')
for node in col:
print(node.id, end=' | ')
print()

def draw_by_id_trans(self):
for col in self.transposed_grid:
print(end='| ')
for node in col:
print(node.id, end=' | ')
print()

def draw_by_id_proc(self):
# Draw Procedurally
for col_num in range(self.cols):
print(end='| ')
for row_num in range(self.rows):
print(self.grid[col_num][row_num].id, '(' + 
str(col_num) + ',' + str(row_num) + ')', end=' | ')

print()

def find_eliminations(self):
#First Down the columns.
i = 0
for col_list in self.transposed_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.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.grid:

Re: [Tutor] Improving My Simple Game Code for Speed, Memory and Learning

2015-01-12 Thread WolfRage
Now I have the output that I expect and procedurally they output matches 
the id of the Node/Tile. But I am thoroughly confused as to why my by_id 
functions use the opposite grid to get the correct output?


# Output
python3 test1.py
|  6 | 20 | 19 | 11 | 11 | 20 |  5 | 11 |
| 20 | 19 | 20 | 11 | 11 | 19 | 19 | 20 |
|  6 | 19 | 19 |  6 |  5 | 20 |  5 | 11 |
| 11 |  5 |  5 | 11 | 11 |  6 |  6 |  5 |
By ID
| 0,0 | 1,0 | 2,0 | 3,0 |
| 0,1 | 1,1 | 2,1 | 3,1 |
| 0,2 | 1,2 | 2,2 | 3,2 |
| 0,3 | 1,3 | 2,3 | 3,3 |
| 0,4 | 1,4 | 2,4 | 3,4 |
| 0,5 | 1,5 | 2,5 | 3,5 |
| 0,6 | 1,6 | 2,6 | 3,6 |
| 0,7 | 1,7 | 2,7 | 3,7 |
Procedurally
| 0,0 (0,0) | 1,0 (1,0) | 2,0 (2,0) | 3,0 (3,0) |
| 0,1 (0,1) | 1,1 (1,1) | 2,1 (2,1) | 3,1 (3,1) |
| 0,2 (0,2) | 1,2 (1,2) | 2,2 (2,2) | 3,2 (3,2) |
| 0,3 (0,3) | 1,3 (1,3) | 2,3 (2,3) | 3,3 (3,3) |
| 0,4 (0,4) | 1,4 (1,4) | 2,4 (2,4) | 3,4 (3,4) |
| 0,5 (0,5) | 1,5 (1,5) | 2,5 (2,5) | 3,5 (3,5) |
| 0,6 (0,6) | 1,6 (1,6) | 2,6 (2,6) | 3,6 (3,6) |
| 0,7 (0,7) | 1,7 (1,7) | 2,7 (2,7) | 3,7 (3,7) |
Tansposed
| 0,0 | 0,1 | 0,2 | 0,3 | 0,4 | 0,5 | 0,6 | 0,7 |
| 1,0 | 1,1 | 1,2 | 1,3 | 1,4 | 1,5 | 1,6 | 1,7 |
| 2,0 | 2,1 | 2,2 | 2,3 | 2,4 | 2,5 | 2,6 | 2,7 |
| 3,0 | 3,1 | 3,2 | 3,3 | 3,4 | 3,5 | 3,6 | 3,7 |
Transposed & Procedurally
| 0,0 (0,0) | 0,1 (0,1) | 0,2 (0,2) | 0,3 (0,3) | 0,4 (0,4) | 0,5 (0,5) 
| 0,6 (0,6) | 0,7 (0,7) |
| 1,0 (1,0) | 1,1 (1,1) | 1,2 (1,2) | 1,3 (1,3) | 1,4 (1,4) | 1,5 (1,5) 
| 1,6 (1,6) | 1,7 (1,7) |
| 2,0 (2,0) | 2,1 (2,1) | 2,2 (2,2) | 2,3 (2,3) | 2,4 (2,4) | 2,5 (2,5) 
| 2,6 (2,6) | 2,7 (2,7) |
| 3,0 (3,0) | 3,1 (3,1) | 3,2 (3,2) | 3,3 (3,3) | 3,4 (3,4) | 3,5 (3,5) 
| 3,6 (3,6) | 3,7 (3,7) |


# 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, **kwargs):
if cols < 3 or rows < 3:
raise ValueError("Minimum board size is 3x3! %sx%s is too 
small."

 % (cols, rows))
self.cols = cols
self.rows = rows
self.values = [5, 6, 11, 19, 20]
self.make_grid()

def make_grid(self):
# grid is 2d array as x, y ie [x][y].
self.transposed_grid = []
for row_num in range(self.rows):
# Do you still think this needs to be broken into a smaller 
method?

row = [GameTile(col_num, row_num, self.values)
   for col_num in range(self.cols)]
self.transposed_grid.append(row)
self.grid = list(zip(*self.transposed_grid))

def draw(self):
for row in self.grid:
print(end='| ')
for node in row:
print(node, end=' | ')
print()

def draw_by_id(self):
# Why does this one use self.transposed_grid instead of self.grid ?
for row in self.transposed_grid:
print(end='| ')
for node in row:
print(node.id, end=' | ')
print()

def draw_by_id_proc(self):
# Draw Procedurally
for row_num in range(self.rows):
print(end='| ')
for col_num in range(self.cols):
print(self.grid[col_num][row_num].id, '(' + 
str(col_num) + ',' + str(row_num) + ')', end=' | ')

print()

def draw_by_id_trans(self):
# Why does this one use self.grid instead of self.transposed_grid ?
for col in self.grid:
print(end='| ')
for node in col:
print(node.id, end=' | ')
print()

def draw_by_id_proc_trans(self):
# Draw Procedurally & Transposed
for col_num in range(self.cols):
print(end='| ')
for row_num in range(self.rows):
print(self.transposed_grid[row_num][col_num].id, '(' + 
str(col_num) + ',' + str(row_num) + ')', end=' | ')

print()

def find_eliminations(self):
#First Down the columns.
i = 0
for col_list in self.transposed_grid:
while True:
try:
if self.check_total(col_list[i: i + 3]):
self.eliminate(co

Re: [Tutor] Improving My Simple Game Code for Speed, Memory and Learning

2015-01-12 Thread WolfRage
I fixed the other functions to again work as expected. But the 
procedural access of the self.grid and self.transposed_grid also 
function correctly. That is good because now I can again do lookups if I 
need to. Although I do not have a need to at this time.


Can anyone see anything wrong with the logic as it is at this time? If 
anyone has any improvements or things to think about, I would love to 
hear it. I am going to work on some tests that will specifically involve 
the procedural code to verify that the id's are arranged in the grid as 
I expect them to be.


I would also appreciate an explanation of why my by_id functions use the 
opposite grid to get the correct output?


#Output Below
python3 test1.py
| 19 | 11 |  5 | 19 |
| 11 | 19 | 19 |  5 |
| 20 | 19 | 20 |  6 |
| 11 | 19 | 11 |  5 |
| 11 |  6 |  5 | 20 |
|  6 |  5 | 19 | 19 |
| 20 | 19 | 20 | 20 |
|  6 | 20 | 19 | 20 |
After Eliminations
| 19 |  0 |  5 | 19 |
|  0 |  0 |  0 |  5 |
|  0 |  0 | 20 |  6 |
|  0 | 19 | 11 |  5 |
|  0 |  6 |  5 | 20 |
|  0 |  5 | 19 | 19 |
| 20 | 19 | 20 | 20 |
|  6 | 20 | 19 | 20 |

After Drops
|  0 |  0 |  0 | 19 |
|  0 |  0 |  5 |  5 |
|  0 |  0 | 20 |  6 |
|  0 | 19 | 11 |  5 |
|  0 |  6 |  5 | 20 |
| 19 |  5 | 19 | 19 |
| 20 | 19 | 20 | 20 |
|  6 | 20 | 19 | 20 |
By ID
| 0,0 | 1,0 | 2,0 | 3,0 |
| 0,1 | 1,1 | 2,1 | 3,1 |
| 0,2 | 1,2 | 2,2 | 3,2 |
| 0,3 | 1,3 | 2,3 | 3,3 |
| 0,4 | 1,4 | 2,4 | 3,4 |
| 0,5 | 1,5 | 2,5 | 3,5 |
| 0,6 | 1,6 | 2,6 | 3,6 |
| 0,7 | 1,7 | 2,7 | 3,7 |
Procedurally
| 0,0 (0,0) | 1,0 (1,0) | 2,0 (2,0) | 3,0 (3,0) |
| 0,1 (0,1) | 1,1 (1,1) | 2,1 (2,1) | 3,1 (3,1) |
| 0,2 (0,2) | 1,2 (1,2) | 2,2 (2,2) | 3,2 (3,2) |
| 0,3 (0,3) | 1,3 (1,3) | 2,3 (2,3) | 3,3 (3,3) |
| 0,4 (0,4) | 1,4 (1,4) | 2,4 (2,4) | 3,4 (3,4) |
| 0,5 (0,5) | 1,5 (1,5) | 2,5 (2,5) | 3,5 (3,5) |
| 0,6 (0,6) | 1,6 (1,6) | 2,6 (2,6) | 3,6 (3,6) |
| 0,7 (0,7) | 1,7 (1,7) | 2,7 (2,7) | 3,7 (3,7) |
Tansposed
| 0,0 | 0,1 | 0,2 | 0,3 | 0,4 | 0,5 | 0,6 | 0,7 |
| 1,0 | 1,1 | 1,2 | 1,3 | 1,4 | 1,5 | 1,6 | 1,7 |
| 2,0 | 2,1 | 2,2 | 2,3 | 2,4 | 2,5 | 2,6 | 2,7 |
| 3,0 | 3,1 | 3,2 | 3,3 | 3,4 | 3,5 | 3,6 | 3,7 |
Transposed & Procedurally
| 0,0 (0,0) | 0,1 (0,1) | 0,2 (0,2) | 0,3 (0,3) | 0,4 (0,4) | 0,5 (0,5) 
| 0,6 (0,6) | 0,7 (0,7) |
| 1,0 (1,0) | 1,1 (1,1) | 1,2 (1,2) | 1,3 (1,3) | 1,4 (1,4) | 1,5 (1,5) 
| 1,6 (1,6) | 1,7 (1,7) |
| 2,0 (2,0) | 2,1 (2,1) | 2,2 (2,2) | 2,3 (2,3) | 2,4 (2,4) | 2,5 (2,5) 
| 2,6 (2,6) | 2,7 (2,7) |
| 3,0 (3,0) | 3,1 (3,1) | 3,2 (3,2) | 3,3 (3,3) | 3,4 (3,4) | 3,5 (3,5) 
| 3,6 (3,6) | 3,7 (3,7) |


# 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, **kwargs):
if cols < 3 or rows < 3:
raise ValueError("Minimum board size is 3x3! %sx%s is too 
small."

 % (cols, rows))
self.cols = cols
self.rows = rows
self.values = [5, 6, 11, 19, 20]
self.make_grid()

def make_grid(self):
# grid is 2d array as x, y ie [x][y].
self.transposed_grid = []
for row_num in range(self.rows):
# Do you still think this needs to be broken into a smaller 
method?

row = [GameTile(col_num, row_num, self.values)
   for col_num in range(self.cols)]
self.transposed_grid.append(row)
self.grid = list(zip(*self.transposed_grid))

def draw(self):
for row in self.transposed_grid:
print(end='| ')
for node in row:
print(node, end=' | ')
print()

def draw_by_id(self):
# Why does this one use self.transposed_grid instead of self.grid ?
for row in self.transposed_grid:
print(end='| ')
for node in row:
print(node.id, end=' | ')
print()

def draw_by_id_proc(self):
# Draw Procedurally
for row_num in range(self.rows):
print(end='| ')
for col_num in range(self.cols):
print(self.grid[col_num][row_num].id, '(' + 
str(col_num) + ',' + str(row_num) + ')', end=' | ')

Re: [Tutor] Improving My Simple Game Code for Speed, Memory and Learning

2015-01-12 Thread Mark Lawrence

On 12/01/2015 19:35, WolfRage wrote:

So I was write as I suspected; the grid is not actually being built like
I thought it was. Sure the ID's print fine but when the grid positions
are procedurally accessed the program fails with IndexError.

python3 test1.py
| 19 |  5 |  5 |  5 |
| 11 |  6 | 19 | 11 |
|  6 |  6 | 11 | 19 |
| 11 | 20 |  6 |  5 |
| 11 |  5 | 20 |  5 |
| 20 | 20 | 11 | 11 |
| 19 | 19 |  5 |  5 |
| 11 | 19 | 19 |  5 |
After Eliminations
|  0 |  0 |  0 |  5 |
| 11 |  0 | 19 | 11 |
|  0 |  0 | 11 |  0 |
|  0 | 20 |  6 |  0 |
|  0 |  5 | 20 |  0 |
|  0 |  0 |  0 |  0 |
| 19 |  0 |  0 |  0 |
|  0 |  0 |  0 |  0 |
broke 0 5
0 6
broke 1 6
1 7
broke 2 6
2 7
broke 3 6
3 7
After Drops
|  0 |  0 |  0 |  5 |
|  0 |  0 | 19 |  0 |
|  0 |  0 | 11 |  0 |
|  0 | 20 |  6 |  0 |
|  0 |  0 |  0 |  0 |
|  0 |  0 |  0 |  0 |
| 11 |  0 |  0 |  0 |
| 19 |  5 | 20 | 11 |
Normal
| 0,0 | 1,0 | 2,0 | 3,0 |
| 0,1 | 1,1 | 2,1 | 3,1 |
| 0,2 | 1,2 | 2,2 | 3,2 |
| 0,3 | 1,3 | 2,3 | 3,3 |
| 0,4 | 1,4 | 2,4 | 3,4 |
| 0,5 | 1,5 | 2,5 | 3,5 |
| 0,6 | 1,6 | 2,6 | 3,6 |
| 0,7 | 1,7 | 2,7 | 3,7 |
Procedurally
# The first printed pair is the id, the second pair in parentheses is
# the procedurally accessed id, which should be all ordered as (column,
# row)
| 0,0 (0,0) | 1,0 (0,1) | 2,0 (0,2) | 3,0 (0,3) | Traceback (most recent
call last):
   File "test1.py", line 186, in 
 grid.draw_by_id_proc()
   File "test1.py", line 75, in draw_by_id_proc
 print(self.grid[col_num][row_num].id, '(' + str(col_num) + ',' +
str(row_num) + ')', end=' | ')
IndexError: list index out of range



I haven't looked carefully at your code but there's always a smell in 
Python when you see structure[x][y].  Can you change the grid so you 
always write something like:-


for row in grid:
for cell in row:
process(cell)

I say this as I'm all for short term pain, long term gain, especially 
when it's guaranteed to eliminate "list index out of range" errors.


--
My fellow Pythonistas, ask not what our language can do for you, ask
what you can do for our language.

Mark Lawrence

___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Improving My Simple Game Code for Speed, Memory and Learning

2015-01-12 Thread Alan Gauld

On 12/01/15 20:28, WolfRage wrote:


anyone has any improvements or things to think about, I would love to
hear it.


Sorry, no time to read the detail, but one thing I thought might be 
handy is to convert the draw method to return a string and make it the 
__str__methodf of the grid.

Then the draw method becomes print(self)

And you can also just use print(aGrid) etc.

Something like (untested):

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 draw(self): print (self)


Just a thought.

--
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.amazon.com/author/alan_gauld
Follow my photo-blog on Flickr at:
http://www.flickr.com/photos/alangauldphotos


___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Improving My Simple Game Code for Speed, Memory and Learning

2015-01-12 Thread WolfRage




I haven't looked carefully at your code but there's always a smell in
Python when you see structure[x][y].  Can you change the grid so you
always write something like:-

for row in grid:
 for cell in row:
 process(cell)

I say this as I'm all for short term pain, long term gain, especially
when it's guaranteed to eliminate "list index out of range" errors.

I think in this case I have to say no. I purposely wrote those "proc" or 
"procedurally" style functions to ensure that access to the grid in this 
way would result in the correct output from id, and to test that it 
worked as expected.
However there are other places in my code where I think I can eliminate 
this smell such as the new function that drops the non-zero values.

___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Improving My Simple Game Code for Speed, Memory and Learning

2015-01-12 Thread WolfRage

On 01/12/2015 05:00 PM, Alan Gauld wrote:


Sorry, no time to read the detail, but one thing I thought might be
handy is to convert the draw method to return a string and make it the
__str__methodf of the grid.
Then the draw method becomes print(self)

And you can also just use print(aGrid) etc.

Something like (untested):

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 draw(self): print (self)


Just a thought.

OK. I will implement this, thanks. It goes well with the __str__ method 
of the tiles/nodes.


___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Improving My Simple Game Code for Speed, Memory and Learning

2015-01-12 Thread WolfRage

On 01/12/2015 05:00 PM, Alan Gauld wrote:


__str__methodf of the grid.
Then the draw method becomes print(self)

And you can also just use print(aGrid) etc.



Implemented with some other improvements using the same idea but applied 
to several of the other functions, that provide output.


Now I am going to try and add the ability to have the table generated 
but with a set number of rows empty or pre-set to zero.


#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, **kwargs):
if cols < 3 or rows < 3:
raise ValueError("Minimum board size is 3x3! %sx%s is too 
small."

 % (cols, rows))
self.cols = cols
self.rows = rows
self.values = [5, 6, 11, 19, 20]
self.make_grid()

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):
# 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):
row = [GameTile(col_num, row_num, self.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.

Re: [Tutor] Improving My Simple Game Code for Speed, Memory and Learning

2015-01-12 Thread WolfRage
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(ro