Reputation: 163
This is my second question post on StackOverflow relating to coding in Python/Numpy.
I feel like there is definitely some sort of function which does the pseudocode:
np.random.choice([a[i-1,j],a[i+1,j],a[i,j-1],a[i,j+1]])==0 = 9
Essentially, I would like the random function to select a cell adjacent to mine (up, down, left, right) with the value 0, and replace said cell with a 9
Unforunately, I know why the code I typed is illegal. The first half of the statement returns a True/False boolean as I have used a comparison/checking operator. I can't set this into a value 9.
If I split the code-load into two codes and used an if statement with the random.choice (looking at an adjacent element that equalled zero), then following this, I would need some sort of function or definition to recall which cell (up down left or right) did the random generator originally select, to which I can then set it to 9.
Kind Regards,
EDIT: I may as well attach a sample code, so you can simply just run this (I am including my error)
a = np.empty((6,6,))
a[:] = 0
a[2,3]=a[3,3]=a[2,4] = 1
for (i,j), value in np.ndenumerate(a):
if a[i,j]==1:
np.random.choice([a[i-1,j],a[i+1,j],a[i,j-1],a[i,j+1]])==0 = 9
Upvotes: 1
Views: 350
Reputation: 1727
This is the most "basic" way of getting what you need (Adding a try/except
statement provides error checking, so you can prevent any unwanted errors):
import random,numpy
a = numpy.empty((6,6,))
a[:] = 0
a[2,3]=a[3,3]=a[5,5] = 1
for (i,j), value in numpy.ndenumerate(a):
var = 0
if a[i,j]==1:
while var==0:
x=random.randrange(0,4) #Generate a random number
try:
if x==0 and a[i-1,j]==0:
a[i-1,j] =9 #Do this if x = 0
elif x==1 and a[i+1,j]==0:
a[i+1,j] =9 #Do this if x = 1
elif x==2 and a[i,j-1]==0:
a[i,j-1] =9 #Do this if x = 2
elif x==3 and a[i,j+1]==0:
a[i,j+1] =9 #Do this if x = 3
var=1
except:
var=0
print a
Upvotes: 0
Reputation: 13459
You could select from a range of directions (up, down, left, right) that map to specific coordinate movements in the 2D array, like this:
# generate a dataset
a = np.zeros((6,6))
a[2,3]=a[3,3]=a[2,4] = 1
# map directions to coordinate movements
nesw_map = {'left': [-1, 0], 'top': [0, 1], 'right': [1,0], 'bottom': [0,-1]}
directions = nesw_map.keys()
# select only those places where a == 1
for col_ind, row_ind in zip(*np.where(a == 1)): # more efficient than iterating over the entire array
x = np.random.choice(directions)
elm_coords = col_ind + nesw_map[x][0], row_ind + nesw_map[x][1]
if a[elm_coords] == 0:
a[elm_coords] = 9
Note that this does not do any type of bounds checking (so if a 1
appears at the edge, you might select an item "off the grid" which will result in an error).
Upvotes: 1