Im having trouble converting the functions from dictionary/lists to numpy/pandas
ID: 3818280 • Letter: I
Question
Im having trouble converting the functions from dictionary/lists to numpy/pandas. The first function can be done with field=np.zeros((n,n)), where n=4 or n=3. But the remaining are a bit tough to understand. Any suggestions? (Python query)
import random
import copy
def create_field(n):
field = []
for i in range(n):
field.append([0] * n)
return field
def check_result(field, sign, n, m):
# check if there are _m_ entries of _sign_ in a line
# check rows
for i in range(n):
cnt = 0
for j in range(n):
if field[i][j] == sign:
cnt = cnt + 1
if cnt >= m:
return [sign, "Horiz", i, j]
else:
cnt = 0
# check columns
for i in range(n):
cnt = 0
for j in range(n):
if field[j][i] == sign:
cnt = cnt + 1
if cnt >= m:
return [sign, "Vert", j, i]
else:
cnt = 0
# check diag left
for i in range(m-n, n-m+1):
cnt = 0
for j in range(n):
if j+i >= 0 and j+i < n:
if field[i+j][j] == sign:
cnt = cnt + 1
if cnt >= m:
return [sign, "Diag Left", i+j, j]
else:
cnt = 0
# check diag right
for i in range(m-n, n-m+1):
cnt = 0
for j in range(n):
if j+i >= 0 and j+i < n:
if field[j+i][n-j-1] == sign:
cnt = cnt + 1
if cnt >= m:
return [sign, "Diag Right", j+i, n-j-1]
else:
cnt = 0
return True
#### Next step for given field and playing strategy
def next_step(field, sign, palyer_function):
next_step = palyer_function(field, sign)
if len(next_step) > 0:
field[next_step[0]][next_step[1]] = sign
return True
else:
return False
#### Random player
def play_random(field, sign):
# return list [row, column] or empty list []
possible_steps = []
for i in range(n):
if field[i].count(0) > 0:
temp = []
for j in range(n):
if field[i][j] == 0:
temp.append(j)
possible_steps.append((i,temp))
if len(possible_steps):
temp = random.sample(possible_steps, 1)[0]
next_step = (temp[0], random.sample(temp[1], 1)[0])
return next_step
else:
return []
#### Function to create
def play_smart(field, sign):
# return list [row, column] or empty list []
possible_steps = []
for i in range(n):
if field[i].count(0) > 0:
for j in range(n):
if field[i][j] == 0:
possible_steps.append([i, j])
my_next_step = []
if len(possible_steps):
for s in possible_steps:
field_temp = copy.deepcopy(field)
field_temp[s[0]][s[1]] = sign
temp = check_result(field_temp, sign, n, m)
if temp != True:
my_next_step = s
break
# if len(my_next_step) == 0:
# random.shuffle(possible_steps)
# for s in possible_steps:
# field_temp = copy.deepcopy(field)
# field_temp[s[0]][s[1]] = sign
# temp = check_result(field_temp, sign, n, m-1)
# if temp != True:
# my_next_step = s
# break
if len(my_next_step) == 0:
my_next_step = random.sample(possible_steps, 1)[0]
return my_next_step
#### Main code
n = 3 # size of the field
m = 3 # length of a line to win
k = random.sample([1,2], 2) # select who is first and who is second
field = create_field(n)
fun =[play_random, play_smart]
res = True
while res == True:
if next_step(field, k[0], fun[k[0]-1]):
res = check_result(field, k[0], n, m)
if res == True and next_step(field, k[1], fun[k[1]-1]):
res = check_result(field, k[1], n, m)
else:
res = [0, "Draw - no winner"]
else:
print("=#=#=#=#=")
for i in field:
print(i)
print(res)
### Multiple runs
report = []
for i in range(1000):
k = random.sample([1,2], 2) # select who is first and who is second
field = create_field(n)
fun =[play_random, play_smart]
res = True
while res == True:
if next_step(field, k[0], fun[k[0]-1]):
res = check_result(field, k[0], n, m)
if res == True and next_step(field, k[1], fun[k[1]-1]):
res = check_result(field, k[1], n, m)
else:
res = [0, "Draw - no winner"]
else:
report.append(res[0])
print("=#=#=#=#=")
print(report.count(1) / len(report))
print(report.count(2) / len(report))
print(report.count(0) / len(report))
Explanation / Answer
Hi,
As you've asked for suggestions, here are mine:
An example to be thought about could be this:
You see, how the dictionary here has been converted to a numpy array?
That must do your job. But, over that, I'd suggest you to take a look at numpy.fromiter() which saves you from the use of the intermediate tuples, and that is why it is more memory-friendly.
I believe the above suggestions should be sufficient for you.