I have problem with function:
tested_zeros = [(-1, -1)]
def reveal_zeros(x, y):
board_visible[y*row+x] = board[y*row+x]
for p in range(x - 1, x + 2):
for o in range(y - 1, y + 2):
if o >= 0 and p >= 0 and o <= row and p <= col:
for zero in tested_zeros:
if zero != (p, o):
tested_zeros.append((p, o)) <--broke part in my 'super' idea xD
if board[o*row+p] == " ":
return reveal_zeros(p, o)
so what is doing is checking if in array 'board[(x, y)]' is zero and its neighbors, when it is, its copying it to 'board_visible', the problem is that it bugs in (0, 0),[and calling it endlessly] so my idea was adding list tested_zeros so he remembers which points it tested but recursive function does not works that way :), and i know i can check last by(x, y) but it will loop somewhere else.
My question is how to handle this?
Here is my whole code:
import random
import numpy as np
row = 10
col = row
mine_list = list()
board = list()
board_visible = list()
num = 0
is_over = False
def get_num_of_mines():
global num
while True:
print("Podaj liczbe min: \n(z zakresu od 1 do ", (row * col) - 1, ")")
num = int(input())
if 1 <= num <= (row * col) - 1:
return num
else:
print("Błędna liczba. Podaj poprawną z zakresu")
def deploy_mines():
global mine_list
mine_x = random.randint(0, row - 1)
mine_y = random.randint(0, col - 1)
par = mine_x, mine_y
for l in mine_list:
if par == l:
return deploy_mines()
return mine_x, mine_y
def number_of_neighboring_mines(x, y):
global mine_list
num_of_neighbors = 0
for p in range(x - 1, x + 2):
for o in range(y - 1, y + 2):
if o >= 0 and p >= 0 and o <= row and p <= col:
par = p, o
for l in mine_list:
if par == l:
num_of_neighbors += 1
if num_of_neighbors == 0:
return " "
else:
return num_of_neighbors
def add_bomb(x, y):
for l in mine_list:
if (x, y) == l:
board.append("*")
return False
return True
def create_board():
global mine_list, num, board_visible
for k in range(0, num):
mine_list.append(deploy_mines())
for i in range(0, col):
for j in range(0, row):
if add_bomb(i, j):
board.append(number_of_neighboring_mines(i, j))
for i in range(0, col):
for j in range(0, row):
board_visible.append(chr(9552))
def show_board():
for l in range(0, col+1):
print('{0:2d}'.format(l), end="\t")
print()
for l in range(0, col):
print('{0:2d}'.format(l+1), end=" ")
print(np.split(np.asarray(board), row)[l])
def print_board():
for l in range(0, col+1):
print('{0:2d}'.format(l), end="\t")
print()
for l in range(0, col):
print('{0:2d}'.format(l+1), end=" ")
print(np.split(np.asarray(board_visible), row)[l])
tested_zeros = [(-1, -1)]
def reveal_zeros(x, y):
board_visible[y*row+x] = board[y*row+x]
for p in range(x - 1, x + 2):
for o in range(y - 1, y + 2):
if o >= 0 and p >= 0 and o <= row and p <= col:
for zero in tested_zeros:
if zero != (p, o) or zero is None:
print(p, o)
tested_zeros.append((p, o))
if board[o*row+p] == " ":
return reveal_zeros(p, o)
def reveal_squares(x, y):
global is_over
if board[y*row+x] == "*":
show_board()
print("Koniec gry!")
is_over = True
elif board[y*row+x] == " ":
reveal_zeros(x, y)
else:
board_visible[y*row+x] = board[y*row+x]
def sapper():
get_num_of_mines()
create_board()
while not is_over:
print_board()
reveal_squares(int(input("Podaj współrzędną x: "))-1, int(input("Podaj
współrzędną y: "))-1)
sapper()
I came up with a working function:
def reveal_zeros(x, y, steps):
board_visible[y*row+x] = board[y*row+x]
can_return = True
for p in range(x - 1, x + 2):
for o in range(y - 1, y + 2):
if o >= 0 and p >= 0 and o < row and p < col:
for i in steps:
if (p, o) == i:
can_return = False
if board[o*row+p] == " " and can_return:
return reveal_zeros(p, o, steps + [(p, o)])
if p == x or o == y or o < 0 or p < 0 or not can_return:
can_return = True
continue
return
Here is a sapper simulation with no winning.
Related
Here is my brief: 'Nimsticks is a turn-taking zero-sum game for two players. The game state consists of one or more piles of sticks. On their turn, a player may take 1, 2 or 3 sticks from any one pile. The player who takes the last stick is the loser of the game.
The problem is my code works fine when there is only one pile ([4], 1) but if I run it with multiple piles ([2, 3], 1) the if statements maxValue < v and minValue > v aren’t triggered (which they always should be due to inf) and are causing an error. Please help!
import copy
import math
def minimax_value(state):
if (state[0] == []):
return(result(state))
else:
if (state[1] == 1):
v, path = (max_value(state))
else:
v, path = (min_value(state))
optimalPath = path
optimalPath.append(state)
optimalPath.reverse()
print('Example play: ' + str(optimalPath))
return str(v)
def terminal(state):
if (state[0] == []):
return True
else:
return False
def utility(state):
if (state[1] == 1):
return(1, [])
else:
return(-1, [])
def max_value(state):
if terminal(state):
return(utility(state))
else:
v = -1 * math.inf
for c in next_states(state):
minValue, minPath = min_value(c)
if (minValue > v):
v = minValue
bestPath = minPath.copy()
bestSucc = c
bestPath.append(bestSucc)
return(v, bestPath)
def min_value(state):
if terminal(state):
return(utility(state))
else:
v = 1 * math.inf
for c in next_states(state):
maxValue, maxPath = max_value(c)
if (maxValue < v):
v = maxValue
bestPath = maxPath.copy()
bestSucc = c
bestPath.append(bestSucc)
return(v, bestPath)
def next_states(state):
player = state[1]
piles = copy.deepcopy(state[0])
pilesSave = copy.deepcopy(piles)
temp = []
newList = []
for x in range(0, len(piles)):
for y in range(1, 4):
piles[x] = piles[x] - y
if (piles[x] >= 0):
temp = copy.deepcopy(piles)
if (piles[x] == 0):
del temp[x]
newList.append(temp)
break
newList.append(temp)
piles[x] = pilesSave[x]
newList2 = []
for item in newList:
if (player == 1):
toAdd = (item, 2)
else:
toAdd = (item, 1)
newList2.append(toAdd)
return(newList2)
print(minimax_value(([2, 3], 1)))
This question already has answers here:
Why Python recursive function returns None [duplicate]
(1 answer)
Recursive function does not return specified value
(2 answers)
Closed 1 year ago.
I have written a maze solver program. I want the PathFinder function to return True if a path is found and then print the path or else simply return False. But my program always keeps returning False even if a path is found. It would be great if you guys can help me figure this out.
def findPaths(m,path,i,j):
r,c = len(m), len(m[0])
if i == r-1 and j == c-1:
print(path)
return True
#explore
path.append(m[i][j])
# move down
if i != r-1 and m[i+1][j] == '↓ ':
findPaths(m,path,i+2,j)
#move up
if i < 0 and m[i-1][j] == '↑ ':
findPaths(m,path,i-2,j)
#move right
if j != c-1 and m[i][j+1] == '→':
findPaths(m,path,i,j+2)
#move left
if j > 0 and m[i][j-1] == '←':
findPaths(m,path,i,j-2)
path.pop()
def maze(r,c):
m = []
for i in range(r):
row = []
for j in range(1, c + (c)):
rand_num = str(randint(1, 99))
if j % 2 != 0:
if len(rand_num) == 1:
row.append(' ' + rand_num)
else:
row.append(rand_num)
else:
row.append('?')
m.append(row)
up_left_count = r * c // 3
down_right_count = r * c * 2 // 3
for v in range(r + (r - 1)):
vertical_lst = []
for each in range(1, c + c):
if each % 2 == 0:
vertical_lst.append(' ')
else:
vertical_lst.append('? ')
if v % 2 != 0:
m.insert(v, vertical_lst)
idx_i = []
idx_j = []
idx_v_i = []
idx_v_j = []
for i in range(len(m)):
for j in range(len(m[0])):
if i % 2 == 0 and j % 2 != 0:
idx_i.append(i)
idx_j.append(j)
for v_i in range(len(m)):
for v_j in range(len(m[0])):
if v_i % 2 != 0 and v_j % 2 == 0:
idx_v_i.append(v_i)
idx_v_j.append(v_j)
idx_i = list(set(idx_i))
idx_j = list(set(idx_j))
idx_v_i = list(set(idx_v_i))
idx_v_j = list(set(idx_v_j))
for count in range(up_left_count):
i_int = randint(0, len(idx_i) - 1)
j_int = randint(0, len(idx_j) - 1)
if m[i_int][j_int] != '←':
m[idx_i[i_int]][idx_j[j_int]] = '←'
for count_v in range(up_left_count):
i_v_int = randint(0, len(idx_v_i) - 1)
j_v_int = randint(0, len(idx_v_j) - 1)
if m[i_v_int][j_v_int] != '↑':
m[idx_v_i[i_v_int]][idx_v_j[j_v_int]] = '↑ '
for i in range(len(m)):
for j in range(len(m[0])):
if i % 2 == 0 and j % 2 != 0:
if m[i][j] == '?':
m[i][j] = '→'
for i in range(len(m)):
for j in range(len(m[0])):
if i % 2 != 0 and j % 2 == 0:
if m[i][j] != '↑ ':
m[i][j] = '↓ '
m[0][0] = "S"
m[-1][-1] = "D"
for i in range(len(m)):
for j in range(len(m[0])):
print(m[i][j], end=" ")
print()
path = []
return findPaths(m, path, 0,0)
if maze(5,6):
print('True')
else:
print('False')
I'm trying solve N Puzzle with Depth First Search using python 3.
With 3 x 3 puzzle it run good and fast but with 4 x 4 puzzle, it runs too slow and can't find solution with error: "MemoryError".
I also use "h(n) = depth + number of wrong tiles" to evaluate priority of each node.
I'm a newbie to python so hope you can help me with this
Here is my code:
import sys
import getopt
import random
import time
class State:
def __init__(self, parent, board, move, depth):
self.parent = parent
self.previousMove = move
self.board = board
self.map = ''.join(str(e) for e in board)
self.depth = depth
self.cost = self.calculateCost()
def calculateCost(self):
pos = 1
count = 0
for tile in self.board:
if tile == pos:
count += 1
pos += 1
return self.depth + 8 - count
class Puzzle:
def __init__(self, k, customBoard = None):
self.k = k
self.n = k*k - 1
self.sizeOfBoard = k*k
self.timeOfSolving = 0
self.timeOfGenerateSuccessors = 0
self.maxDeepSearch = 0
self.inititalState = State(None, self.createInitialBoard(customBoard), 'Start', 0)
self.goalBoard = self.createGoalBoard()
self.finalState = None
self.stateStorage = set() # Store states that have visited
self.path = [] # Store states that lead to goalstate
self.stack = []
def isSolvable(self, board):
# count invertion in puzzle's board
invCount = 0
for i in range(0, self.sizeOfBoard - 1):
if board[i] == 0:
continue
for j in range(i+1, self.sizeOfBoard):
if board[j] == 0:
continue
if board[i] > board[j]:
invCount += 1
# print(invCount)
if (invCount % 2 == 0):
return True
return False
def createInitialBoard(self, customBoard):
print("Creating initial state")
if customBoard is None:
board = []
lstAddSuccess = []
while 1:
board.clear()
lstAddSuccess.clear()
for count in range(0, self.k*self.k):
newTile = random.randint(0, self.n)
while newTile in lstAddSuccess:
newTile = random.randint(0, self.n)
lstAddSuccess += [newTile]
board += [newTile]
if self.isSolvable(board):
break
else:
board = [int(e) for e in customBoard]
if not self.isSolvable(board):
print("Cant find solution with this puzzle! Exiting...")
exit(-1)
return board
def createGoalBoard(self):
board = []
for count in range(1, self.n + 1):
board += [count]
board += [0]
return board
def printBoard(self, board):
for row in range(0, self.sizeOfBoard, self.k):
# for col in range(row, row + self.k):
print(board[row:row + self.k])
def generateSuccessors(self, currentState):
indexOfZero = currentState.board.index(0)
rowIndexOfZero = indexOfZero % self.k
colIndexOfZero = indexOfZero // self.k
lstSuccessors = []
# Slide to zero to up
if colIndexOfZero != 0:
newState = currentState.board.copy()
newState[indexOfZero] = newState[indexOfZero - self.k]
newState[indexOfZero - self.k] = 0
lstSuccessors.append(
State(currentState, newState, 'up', currentState.depth + 1))
# Slide zero to down
if colIndexOfZero != self.k - 1:
newState = currentState.board.copy()
newState[indexOfZero] = newState[indexOfZero + self.k]
newState[indexOfZero + self.k] = 0
lstSuccessors.append(
State(currentState, newState, 'down', currentState.depth + 1))
# slide zero to left
if rowIndexOfZero != 0:
newState = currentState.board.copy()
newState[indexOfZero] = newState[indexOfZero - 1]
newState[indexOfZero - 1] = 0
lstSuccessors.append(
State(currentState, newState, 'left', currentState.depth + 1))
# Slide zero to right
if rowIndexOfZero != self.k - 1:
newState = currentState.board.copy()
newState[indexOfZero] = newState[indexOfZero + 1]
newState[indexOfZero + 1] = 0
lstSuccessors.append(
State(currentState, newState, 'right', currentState.depth + 1))
lstSuccessorsCost = [ele.cost for ele in lstSuccessors]
lstSuccessorsInOrderOfCost = []
for i in range(0, len(lstSuccessorsCost)):
lstSuccessorsInOrderOfCost.append(lstSuccessors[lstSuccessorsCost.index(min(lstSuccessorsCost))])
lstSuccessorsCost[lstSuccessorsCost.index(min(lstSuccessorsCost))] = 100
return lstSuccessorsInOrderOfCost
def solvePuzzle(self, currentState):
self.stack.append(currentState)
self.stateStorage.add(currentState.map)
while len(self.stack) > 0:
currentState = self.stack.pop()
if currentState.board == self.goalBoard:
# find path
# self.printBoard(currentState.board)
self.finalState = currentState
print("Solving " + str(self.n) + " puzzle done!")
return
start_time_gen = time.time()
lstSuccessor = self.generateSuccessors(currentState)
end_time_gen = time.time()
timeOfGen = end_time_gen - start_time_gen
self.timeOfGenerateSuccessors += timeOfGen
for successor in lstSuccessor[::-1]:
if successor.map not in self.stateStorage:
self.stack.append(successor)
self.stateStorage.add(successor.map)
if successor.depth > self.maxDeepSearch:
self.maxDeepSearch += 1
print("Cant solve puzzle! Exiting...")
exit(-1)
def solve(self):
start_time = time.time()
self.solvePuzzle(self.inititalState)
end_time = time.time()
self.timeOfSolving = end_time - start_time
print("Running time: " + str(self.timeOfSolving))
print("Max Search Dept: " + str(self.maxDeepSearch))
print("Final State Dept: " + str(self.finalState.depth))
def printInitialBoard(self):
self.printBoard(self.inititalState.board)
def printPath(self):
if self.finalState is None:
print("No solution found!")
return
path = []
state = self.finalState
while (state is not None):
if state.previousMove is not None:
path.append(state.previousMove)
state = state.parent
print("path: "),
print(path[::-1])
def main(argv):
# if (len(argv) != 1 or int(argv[0]) not in range(1, 10000)):
# print("Input must be k of integer, which is k*k matrix of puzzle")
# exit()
# eight_puzzle = Puzzle(int(argv[0]))
k = int(input("Enter size of k * k puzzle, k = "))
while k not in range(2, 100):
print("k must be in range 2 - 100")
k = int(input("Enter size of k * k puzzle, k = "))
print("""
Choose:
1. Randome puzzle
2. Custome puzzle
""")
file = input()
if int(file) == 1:
puzzle = Puzzle(k)
elif int(file) == 2:
board = input("Enter puzzle: ")
puzzle = Puzzle(k ,list(board.split(" ")))
puzzle.printInitialBoard()
puzzle.solve()
puzzle.printPath()
if __name__ == "__main__":
main(sys.argv[1:])
just a small labyrinth solver. try it to on python but dont even understand why it doesnt print anything. Im just started with python and trying to actually translate my teachers code from cpp just for interest.
need to reach to the destination after visiting each cell
m = [
[2,0,0,0,0,0],
[0,0,0,0,0,0],
[0,0,0,0,0,0],
[0,0,0,0,0,0],
[0,0,0,2,0,0],
[0,0,0,0,0,0]
]
STOP = 34
r = 0
c = 0
def init( r_: int = 0, c_: int = 0) -> None:
r = 0
c = 0
def step(r,c,level):
if level==STOP-1:
if r == 3 and c == 5:
for i in range(0,level):
print("("+init(int(r),int(c))+"," + init(int(r),int(c)) + ") - ")
print("(3,5)\n")
return True
else:
return False
m[r][c]=1
if c > 0 and m[r][c - 1] == 0:
if step(r, c - 1, level + 1):
return True
if c < 5 and m[r][c + 1] == 0:
if (step(r, c + 1, level + 1)):
return True
if r > 0 and m[r - 1][c] == 0:
if (step(r - 1, c, level + 1)):
return True
if r < 5 and m[r + 1][c] == 0:
if (step(r + 1, c, level + 1)):
return True
m[r][c] = 0
return False
def main(argc, argv):
step(0, 1, 0)
Python doesn't automatically call main like c does, nor does it require a main function. Your code can just live in the top level (e.g. print('hello world') is a valid, complete program)
Change this line:
def main(argc, argv):
to this:
if __name__ == '__main__':
got it
import matplotlib.pyplot as plt
S, F, W, X = 1, 2, 0, None
FIELD = [[X,S,W,W,W,W],
[W,W,W,W,W,W],
[W,W,W,W,W,W],
[W,W,W,W,W,F],
[W,W,W,X,W,W],
[W,W,W,W,W,W]]
ROWS = len(FIELD)
COLS = len(FIELD[0])
START_POS = [(i, line.index(S)) for i, line in enumerate(FIELD) if S in line][0]
FINISH_POS = [(i, line.index(F)) for i, line in enumerate(FIELD) if F in line][0]
STEPS = sum(line.count(W) for line in FIELD) + 1
print("Start:", START_POS, "\nFinish:", FINISH_POS, "\nTotal steps:", STEPS)
def do_step(level, path, points):
global FIELD
r, c = points[-1]
if r<0 or c<0 or r>=ROWS or c>=COLS or FIELD[r][c] == X:
return
if level == STEPS and (r, c) == FINISH_POS:
print("Found path:", path)
yy, xx = zip(*points)
plt.plot(xx, yy, "-ok")
plt.gca().invert_yaxis()
plt.show()
exit()
current = FIELD[r][c]
FIELD[r][c] = X
for dr, dc, dir in ((-1,0,'^'), (0,1,'>'), (1,0,'v'), (0,-1,'<')):
do_step(level+1, path+dir, points+[(r+dr,c+dc)])
FIELD[r][c] = current
do_step(0, "", [START_POS])
print("No path's found.")
I keep getting an
IndexError: list assignment index out of range.
The error on line 78
This code is written to find motif DNA to bioinformatics
How we can solve this error or the problem ?
Here is my code:
from math import log
class MotifMedianFinding(object):
def __init__(self, input_file):
super(MotifMedianFinding, self).__init__()
self.input_lines = open("C:\\Users\\A.Khassawneh\\Desktop\\fasta.txt")
def output(self):
#main method to call both functions
sequences = {}
for line in self.input_lines:
if '>' in line:
sequences[line] = self.input_lines.next()
for label, seq in sequences.iteritems():
print "DNA:" + seq + "\n\n\n\n\n"
median = self.median_string(seq, 5,5, len(seq))
self.motif(seq, median,5,len(seq))
def median_string(self, dna, t, n, l):
#bound and search method of calulating median string
start_pos = start_pos = [1,1,1,1,1]
best_dist = 1000000000
i = 1
while i > 0:
if i < l:
prefix = str(start_pos)
opt_dist = self.hamming_score(prefix, dna)
if opt_dist > best_dist:
s,i = self.bypass(start_pos,i,l,4)
else:
s,i = self.next_vertex(start_pos,i,l,4)
else:
word = str(s)
if self.hamming_score(word, dna) < best_dist:
best_dist = self.hamming_score(word, dna)
bestword = word
s,i = self.next_vertex(start_pos,i,l,4)
print "Best Word: %s (tot_dis = %s)" % (bestword,best_dist)
return bestword
def motif(self, dna, t, n, l):
#bound and search method of calculating motif
start_pos = [1,1,1,1,1]
best_score = 0
i = 1
while 1 > 0:
if i < t:
opt_score = Score(s, i, dna) + (t-1) * l
if opt_score < best_score:
start_pos, i = self.bypass(start_pos, i, t, n-l+1)
else:
start_pos, i = self.next_vertex(start_pos, i, t, n-l+1)
else:
if self.score(start_pos, dna) > best_score:
best_score = self.score(start_pos)
best_motif = str(s)
start_pos, i = self.next_vertex(start_pos, i, t, n-l+1)
print "motif consensus string: %s (consensus_score = %s) " % (best_motif, best_score)
print "motif positions/string s=(s1..st): %s" % ', '.join(start_pos)
return best_motif
def bypass(vertex, level, l, k):
#skip uncessary calculations in the tree
j = level
for ind in xrange(j,1,-1):
if a[j] < k:
a[j] = a[j] + 1
return vertex, j
return vertex, 0
def next_vertex(self, vertex, level, L, k):
#transverse the tree of a strand of genes
if level <L:
vertex[level+1] = 1
return vertex,level+1
else:
j = L
for ind in xrange(j,1,-1):
if vertex[ind] < k:
vertex[j] = vertex[j] + 1
return vertex, j
return vertex, 0
def score(start_pos):
# biggest score of motif
total = 0
for i in start_pos:
total += i
return total
def hamming_score(self, s, dna):
pass
motif_median = MotifMedianFinding('HMP-part.fa')
motif_median.output()
xrange(x,y) goes from x to y-1 (x, x+1.... y-1). In your code, it would have been fine to do xrange(1,j), because that wouldn't have included j. But if you swap it to xrange(j,1,-1), you go (j, j-1.... 2).
Basically, you probably need to change it to xrange(j-1,0,-1) depending on your intended range.