I am trying to write a code that solves a basic maze made up of a list of lists with '#' symbolizing walls, '.' are free spaces, S is the start and E is the end. My algorithm consists of first checking to see if the space to the right is free, if not it then checks the space up, then down, and finally to the left. I also realize that this creates a problem if there is a dead end but I'll worry about that later. So far I have code that prints the list and finds the index value of the start point which is (2,0). Basically what I am trying to do is take that starting value as the argument for my def solve function and then iterate over my algorithm while marking visited positions as 'x'... if that makes any sense. When I run the code I keep getting
if maze[r+1][c] == '.':
NameError: name 'r' is not defined
Also I can't seem to print my maze correctly on this website so
here is my maze.
def main():
print_maze()
start()
solve(start())
print_maze()
def print_maze():
for r in range(0,len(maze)):
for c in range(0,len(maze)):
print(maze[r][c], end='')
print('')
def start():
find_value = 'S'
for r in range(0,len(maze)):
for c in range (0,len(maze)):
if find_value in maze[r][c]:
return(r,c)
break
def solve(position):
if maze[r+1][c] == '.':
maze[r][c] = 'x'
return (r,c)
elif maze[r][c+1] == '.':
maze[r][c] = 'x'
return (r,c)
elif maze[r][c-1] == '.':
maze[r][c] = 'x'
return (r,c)
elif maze[r-1][c] == '.':
maze[r][c] = 'x'
return (r,c)
else:
print('Route Error')
main()
The error you are encountering occurs because main calls solve without a required argument.
def main():
print_maze()
start()
solve() # Error! Missing required arg
print_maze()
Since solve redefines start_point right away you can just remove that required argument:
def solve():
start_point = start()
Finally, you didn't provide maze so anybody trying to help you beyond this problem won't be able to
You need to pass the value returned from start() into the solve() function because you listed it as an argument. You can then remove the start_point= portion from the solve() function.
def main():
print_maze()
start = start()
solve(start)
print_maze()
Try to change the def slove format eg; == "X"
= "x²"
Related
I'm creating a python program that given any angles/sides of a triangle will solve for all other applicable sides. to do this I have a dictionary of lists with lengths a,b,c and sides aa,ba,ca. the dictionary is structured so the first item in the list is the value of the key and the second item is a 0 or a 1, depending on if it is answered or not.
The program takes the second value of the list and puts it into another dictionary i called eqdict. for eqdict the value is either a 1 or a 0, depending if the value is known or not. With this we can do Pythagorean theorem, so if a+b+c=2, then we know 1 value is missing so it starts a function to find the missing side. After this function the answer gets saved with the saveanswer function, and the equation finder function is called again. However when the program goes back through equation finder, the eqdict for whichever character it found is not set to 0, so it has a continuous loop.
import math
def main():
#creating terms in strings because I cant find an answer on how
#to make floats with a non zero no value
global terms
terms={"a":[0,0],"b":[0,0],"c":[0,0],"aa":[0,0],"ba":[0,0],"ca":[0,0]}
selectterms()
def selectterms():
"""takes user input for terms"""
doneterm=False
while not doneterm:
print("Please select the variable and then write it's value")
print("When done, please press enter with command prompt empty")
term1=input("Variable: ")
#to start program need to enter no command
if term1=="":
doneterm=True
appender()
#to end program after its finished
if doneterm ==False:
term2=float(input("Number: "))
terms[term1]=[term2]
terms[term1].append(1)
return
def addtoeqdict(term):
eqdict[term]=1
return
def saveanswer(term,num):
"""saves answer to answers dict, makes second term 1 and sends back the number"""
answers={}
print("saveanswer")
answers[term]=num
#print("answers",answers)
terms[term][1]=1
terms[term][0]=num
eqdict[term]=1
print(answers)
print(eqdict)
eqfinder(**eqdict)
def appender():
"""Append a 0 on to terms that have only 1 item in list"""
global eqdict
eqdict={}
keys=terms.keys()
for i in keys:
i = str(i)
eqdict[i]=int(terms[i][1])
eqfinder(**eqdict)
return
def eqfinder(a,b,c,aa,ba,ca):
"""runs through given terms to find any possible equations.
looks for possible equations by adding appended values"""
nomoreterms=False
while nomoreterms == False:
print(terms)
if terms["aa"][0]!=0 or terms["ba"][0]!=0 or terms["ca"][0]!=0:
if terms["aa"][0]<0 or terms["ba"][0]<0 or terms["ca"][0]<0:
posangles(terms["aa"][0],terms["ba"][0],terms["ca"][0])
print(a,b,c,aa,ba,ca)
if c+a+b==2:
cab(terms["c"][0],terms["a"][0],terms["b"][0])
else:
nomoreterms=True
def posangles(aa,ba,ca):
print("Posangles")
if aa<0:
aa=aa*(-1)
saveanswer("aa",aa)
elif ba<0:
ba=ba*(-1)
saveanswer("ba",ba)
elif ca<0:
ca=ca*(-1)
saveanswer("ca",ca)
def cab(c,a,b):
print("cab")
if c==0:
c=math.sqrt(a**2+b**2)
saveanswer("c",c)
elif a==0:
a=math.sqrt(c**2-b**2)
saveanswer("a", a)
elif b==0:
b=math.sqrt(c**2-a**2)
saveanswer("b",b)
main()
So the issue is your eqfinder function. You pass in a, b, c find the missing value using cab, and save the answer. It then gets back to eqfinder and checks if a + b + c == 2 which it does since you never updated the a, b, c variables. There are number of fixes you could do to make this break out of the for loop. Here's one (added line marked with >>>):
def eqfinder(a,b,c,aa,ba,ca):
"""runs through given terms to find any possible equations.
looks for possible equations by adding appended values"""
nomoreterms=False
while nomoreterms == False:
print(terms)
if terms["aa"][0]!=0 or terms["ba"][0]!=0 or terms["ca"][0]!=0:
if terms["aa"][0]<0 or terms["ba"][0]<0 or terms["ca"][0]<0:
posangles(terms["aa"][0],terms["ba"][0],terms["ca"][0])
print(a,b,c,aa,ba,ca)
if c+a+b==2:
cab(terms["c"][0],terms["a"][0],terms["b"][0])
>>> c, a, b = terms["c"][1],terms["a"][1],terms["b"][1]
else:
nomoreterms=True
Here is my code-
board=['','']
from IPython.display import clear_output
def display_board(board):
print(board[7]+'|'+board[8]+'|'+board[9])
print(board[4]+'|'+board[5]+'|'+board[6])
print(board[1]+'|'+board[2]+'|'+board[3])
test_board=['']*10
display_board(test_board)
def player_input():
marker=''
# keep asking ot select X or O t oplayer one
while not(marker=='X'or marker== 'O'):
marker= input('Player one, select either X or O :').upper()
if marker =='X':
return ('X', 'O')
else:
marker=='O'
return('O','X')
player_input()
test_board=['','','','','','','','','','']
def place_marker(board,marker,position):
board[position]= marker
place_marker(test_board,'$',8)
display_board(test_board)
def win_check(board, mark):
# checking who wins tic tac to base on the input X or O or marker
# check all columns, to make sure the marker is the same
# check diagonals.
return ((board[7]==board[8]==board[9]==mark) or
(board[4]==mark and board[5]==mark and board [6]==mark) or
(board[1]==board[2]==board[3]==mark) or
(board[7]==mark and board[5]==mark and board [3]==mark) or
(board[1]==mark and board[5]==mark and board [9]==mark) or
(board[7]==board[4]==board[1]==mark) or
(board[8]==board[5]==board[2]==mark) or
(board[9]==board[6]==board[3]==mark))
display_board(test_board)
win_check(test_board,'X')
#random module
import random
def choose_first():
if random.randint(0,1) == 0:
return 'player1'
else:
return 'player2'
choose_first()
def space_check(test_board,position):
return test_board[position]==' '
#Here is where I encounter the problem, based on what I have before, all the spaces are empty. Therefore, I write in my program the following condition, if all spaces are full from 1 to 9 return "true" other wise return "False", I should get a "false" since there are not values in test_board but regardless on how I am writting it I always get a true. I am not sire what I am missing?
def full_board_check(test_board):
for i in range(1,10):
if space_check==''in test_board:
return False
else:
return True
full_board_check(test_board)
$Second problem here I am using a "in range" of 1 to 10, this is to represent the spaces I have available for the users to enter their option (in Test_board) but I can put in 10 or 11> and it will take it. How can I limit this to the 9 spaces I have available?
def player_choice (test_board):
position=0
while position not in [1,2,3,4,5,6,7,8,9] or not space_check(test_board,position):
position= int(input('Select a position (1-9) ' ))
return position
This line doesn't look right: if space_check==''in test_board:, and I think the whole function is wrong, as you're returning True before checking all the values. Also space_check is actually looking for a space, but you initialize the board with empty strings, not spaces. Try this:
def space_check(test_board,position):
return test_board[position]==''
def full_board_check(test_board):
"""Returns True if all spaces are filled"""
for i in range(1,10):
if space_check(test_board, i):
return False # We found an empty slot
return True # All slots are filled
The problem is my code keeps reflecting a variable as zero and this is caused by the fact that the variable is assigned at the start of my function, so each time I call the function the value evaluates to zero. However I need this variable assignment for the code to work and placing it within the elif statements still evaluates to zero and placing the the variable outside the function causes the function not work.
The aim of the program is to count pairs of consecutive letters in a string using recursion with no for/while loops in the code.
def countpairs(s):
pairs=0
if len(s)<2:
return 0 #base case
elif s[0].lower() == s[1].lower(): #recursion
pairs=+1
return countpairs(s[1:])
else: #recursion
pairs=+0
return countpairs(s[1:])
print(countpairs('Hello Salaam'))
This code is supposed to evaluate to 2 because of "ll" and "aa".
You need to wrap your head a little around what the recursion will do: it will call the function recursively to count the pairs from that point on, then (it should) add the pair, if any, found by this instance.
So your function needs to do something with the result of the recursive call, not just return it unchanged. For example, instead of this
elif s[0].lower() == s[1].lower():
pairs = +1
return countpairs(s[1:])
you might write this:
elif s[0].lower() == s[1].lower():
return countpairs(s[1:]) + 1
Something along these lines. You'll need to do a bit more work to get it just right, but I hope you get the idea.
The problems is that the variable pairs resets every recursive call...
When using counting recursive algorithms you don't need a variable that counts, that's the beauty
Instead, try to think how to recursive call can help you count.
def countpairs(s):
if len(s)<2:
return 0
elif s[0].lower() == s[1].lower():
return countpairs(s[1:])+1
else:
return countpairs(s[1:])
print(countpairs('Hello Salaam'))
There you go, in the recursive call the "counter" gets bigger every time it should be, think of the counter as a part of the function stack (or something like that).
You need to fix the syntax: pairs=+1 should be pairs+=1, same for pairs=+0. And you can pass the total into the next level.
def countpairs(s, pairs=0):
if len(s)<2:
return pairs #base case
elif s[0].lower() == s[1].lower(): #recursion
pairs+=1
return countpairs(s[1:], pairs)
else: #recursion
pairs+=0
return countpairs(s[1:], pairs)
print(countpairs('Hello Salaam')) # 2
You can do it by creating a recursive nested function and defining pairs in the outer function. Here's what I mean (with fixes for other issues encountered):
def countpairs(s):
pairs = 0
def _countpairs(s):
nonlocal pairs # Since it's not local nor global.
if len(s) < 2: # base case
return pairs
elif s[0].lower() == s[1].lower():
pairs += 1
return _countpairs(s[1:]) # recursion
else:
return _countpairs(s[1:]) # recursion
return _countpairs(s)
print(countpairs('Hello Salaam')) # -> 2
The code will always evaluate to zero because the last recursion will always have the length of s being less than 2. Instead use the global keyword to be able to grab the value of pairs.
numberOfPairs = 0
pairsList = []
def countpairs(s):
global numberOfPairs
if len(s)<2:
print("doing nothing")
return 0 #base case
elif s[0].lower() == s[1].lower(): #recursion
numberOfPairs+=1
newString = f"{s[0]} is equal to {s[1]}"
print(newString)
pairsList.append(newString)
return countpairs(s[1:])
else:
print(f"nothing happened: {s[0]}") #recursion
return countpairs(s[1:])
print(f"\nThe returned value of countpairs is: {countpairs('Hello Salaam')}")
print(f"Number of pairs: {numberOfPairs}")
print(pairsList)
I am pretty new so I apologize if I make any errors in posting here... I did a search but didn't come up with much that would help me. I am writing a miniMax algorithm for a variation on Tic Tac Toe. This variation allows either player to put an X or an O anywhere on the board. I am having trouble with the recursion and was hoping I could get a bit of guidance.
class TicTacToeBoard:
def __init__(self, initGameBoard):
#initGameBoard is a string
self.board = initGameBoard
def getEmptySpaces(self):
return self.board.count("-")
def markX(self, index):
self.board = self.board[:index] + "x" + self.board[index+1:]
def markO(self, index):
self.board = self.board[:index] + "o" + self.board[index+1:]
def endGame(self):
#determines if someone has won
endGameStates = [[0,1,2],[3,4,5],[6,7,8],[0,3,6],[1,4,7],[2,5,8],[0,4,8],[2,4,6]]
for x in range(len(endGameStates)):
trySlice = self.board[endGameStates[x][0]] + self.board[endGameStates[x][1]] + \
self.board[endGameStates[x][2]]
if trySlice[0] == trySlice[1] == trySlice[2] and "-" not in trySlice:
return True
return False
def draw(self):
#determines if there has been a draw
if "-" not in self.board:
endGameStates = [[0,1,2],[3,4,5],[6,7,8],[0,3,6],[1,4,7],[2,5,8],[0,4,8],[2,4,6]]
for x in range(len(endGameStates)):
trySlice = self.board[endGameStates[x][0]] + self.board[endGameStates[x][1]] + \
self.board[endGameStates[x][2]]
if trySlice[0] == trySlice[1] == trySlice[2] and "-" not in trySlice:
return False
return True
else:
return False
def __str__(self):
boardStr = ""
for char in self.board:
boardStr += char
return boardStr
Above is my board class. I'm just using strings, not doing anything too fancy. I'm also using a very simple Node class that just stores data (though I suppose I might be able to just use strings too I guess...)
from tic_tac_toe_board import TicTacToeBoard
from node import Node
nodeQueue = []
def fitnessFunction(gameBoard):
#only runs if end game or if all full
if gameBoard.draw():
return 0
else:
emptySpaces = gameBoard.getEmptySpaces()
if emptySpaces %2 == 0:
#max won
return (emptySpaces + 1) *1
else:
#max lost
return (emptySpaces + 1) *-1
def miniMax(gameBoard):
if gameBoard.endGame() or if "-" not in gameBoard:
#end game checks for winner, second clause checks for full/draw
return fitnessFunction(gameBoard)
else:
emptyIndexes = [] #keeps track of which indexes are empty
count = 0
for char in gameBoard:
if char == "-":
emptyIndexes.append(count)
count +=1
if len(emptyIndexes) %2 != 0:
#max's turn
for index in emptyIndexes:
childNode = Node(gameBoard.markX(index))
nodeQueue.append(childNode)
childNode = Node(gameBoard.markO(index))
nodeQueue.append(childNode)
return miniMax()
The fitnessFunction returns a score based on the number of empty spaces left. I'm having trouble with my recursive miniMax method. What I need to do is check for the base cases (either player winning, or a draw) and if those base cases are not true, I figure out whose move it is based on the number of empty spaces left. I think I've gotten that far, but I don't know what to do next (the recursive part). I also need to be able to get the min or max of children, depending on whose turn it is. I guess I am lost with the recursion. I'm new to CS and haven't touched much on it. Any hints would be greatly appreciated! :)
If you are looking for a mini-max algorithm, you don't need an example upon which to apply it. Most games require a mini-max algorithm.
So if you want one, decide how it must behave. Then write a test for at least one example of that behavior.
Post your test. (Not a game, but just a test of the data that would result from a game.)
If your algorithm does not work, your game program can't work.
Hint: A mini-max algorithm depends only upon the evaluations of game paths, not upon the game being played.
I am currently working on a BASIC simulator in Python, as the title suggests. Here is my code for this problem:
def getBASIC():
l = []
x = 1
while x == 1:
i = input()
l.append(i)
if len(i.split()) != 3:
x = 0
return l
def findLine(prog, target):
for l in range(0, len(prog)):
progX = prog[l].split()
if progX[0] == target:
return l
def execute(prog):
location = 0
visited = [False] * len(prog)
while True:
T = prog[location].split()[2]
location = findLine(prog, T)
visited[location] = True
if visited[len(visited)-1] == False:
return "infinite loop"
else:
return "success"
The first function does what it is intended to do -- convert input of BASIC code into a list. The second function, findLine also does what it is intended to do, in that it finds the item which contains the string equal to the input. The last function, however, I cannot get to work. I know what I have to do, and that is to check whether or not a part of it has been visited twice. I cannot figure out how to do this, due to the existence of the while loop. As a result of this, the second half of that function is just placeholder. If you could help me figure out how to solve this, it would be greatly appreciated. Thanks.
You keep a list of places that have been visited (you already do this) and then when you encounter a goto, you check if it does to a line that already have been visited, and if it has been visited, you exit.
One mistake right now is that you make a list that is as long as the program is. That's pretty pointless. Just keep a list of the visited line numbers instead, and check with
if current_line in visited:
Try adding an if statement declaring a line in the visited list to be true when it is encountered in the loop. This is my solution:
def execute(prog):
location = 0
visited=[False]*len(prog)
while True:
if location==len(prog)-1:
return "success"
if visited[location]==True:
return "infinite loop"
if visited[location]==False:
visited[location]=True
line2strings=prog[location].split()
T=line2strings[-1]
location=findLine(prog, T)