Reputation: 25
My teacher set me the task to make a Python version of "The Game of Life", So after I got most of the code working. I got stuck on what I suspect would be a rather common problem: The corners and edges don't have 8 neighbors. So using the following code would give me an index out of range exception:
neighbors = (a[x-1][y-1]+a[x-1][y]+a[x-1][y+1]+a[x][y-1]+a[x][y+1]
+a[x+1][y-1]+a[x+1][y]+a[x+1][y+1])
So instead of using a lot of if
statements, I wanted to catch the indexes that are out of range and pass the value 0 instead.
How would I attempt to do that?
Upvotes: 0
Views: 9982
Reputation: 123501
I'd replace your long expression with a single function call to something like this:
def neighbors(a, x, y):
total = 0
for dx, dy in [(-1, -1), (-1, 0), (-1, 1),
( 0, -1), ( 0, 1),
( 1, -1), ( 1, 0), ( 1, 1)]:
try:
total += a[x+dx][y+dy]
except IndexError:
pass
return total
Since there are only eight possible neighbors, for maximum speed you might want to consider unwinding the loop in the above for the following:
def neighbors(a, x, y):
xm1, xp1, ym1, yp1 = x-1, x+1, y-1, y+1
total = 0
try:
total += a[xm1][ym1]
except IndexError:
pass
try:
total += a[xm1][y]
except IndexError:
pass
try:
total += a[xm1][yp1]
except IndexError:
pass
try:
total += a[x][ym1]
except IndexError:
pass
try:
total += a[x][yp1]
except IndexError:
pass
try:
total += a[xp1][ym1]
except IndexError:
pass
try:
total += a[xp1][y]
except IndexError:
pass
try:
total += a[xp1][yp1]
except IndexError:
pass
return total
The alternative of creating a function to check each x, y of each location will require nine function calls to compute the same value (and the evaluation of a non-trivial conditional expression each time).
Upvotes: 0
Reputation: 528
I would write a helper function that you could call that would either return a value or zero (pseudocode):
def getValue(x, y)
if x < 0 or y < 0 or x > xbound or y > ybound:
return 0
return a[x][y]
Then you can call getValue
a bunch of times with different parameters
Upvotes: 0
Reputation: 18371
Make you actual board wider and longer by 2 cells, pad the margins with zeros, and work with indices from 1
to length (or width)-2
.
Upvotes: 2