Maybe the problem can be solved by deleting all those functions, can’t it?
However, i really don’t know what to do to get the source work.
By the way, it just simulates a horse in a chesstable, going around and around, randomly, trying to visit each square once; and I get a recursion depth exceeded error.
import random
def main():
global tries,moves
tries,moves=0,0
restart()
def restart():
global a,indexes,x,y
a=[[0 for y in range(8)] for x in range(8)] #Costrutto chic
indexes=[x for x in range(8)]
#Random part
x=random.randint(0,7)
y=random.randint(0,7)
a[x][y]=1
start()
def start():
global i,indexes,moves,tries
i=0
random.shuffle(indexes) #List filled with random numbers that i'll use as indexes
while i<=7:
if indexes[i]==0:
move(-2,-1)
elif indexes[i]==1:
move(-2,1)
elif indexes[i]==2:
move(-1,-2)
elif indexes[i]==3:
move(-1,2)
elif indexes[i]==4:
move(1,-2)
elif indexes[i]==5:
move(1,2)
elif indexes[i]==6:
move(2,-1)
elif indexes[i]==7:
move(2,1)
i+=1
for _ in a:
if 0 in _:
print "Wasted moves: %d"%(moves)
tries+=1
moves=0
restart()
print "Success obtained in %d tries"%(tries)
def move(column,row):
global x,y,a,moves
try: b=a[x+row][y+column]
except IndexError: return 0
if b==0 and 0<=x+row<=7 and 0<=y+column<=7:
x=x+row
y=y+column
a[x][y]=1
moves+=1
start()
else: return 0
try :main()
#except: print "I couldn't handle it" <-Row added to prevent python from returning a huge amount of errors
EDIT: This is the modified version, which still does not works, but at least it’s an improvement:
import random
def move((column,row),x,y):
try: cell=squares_visited[x+row][y+column]
except IndexError: return x,y ## NONE TYPE OBJECT
if cell==0 and 0<=x+row<=7 and 0<=y+column<=7:
x+=row
y+=column
squares_visited[x][y]=1
return x,y ## NONE TYPE OBJECT
squares_visited=[[0] * 8 for _ in range(8)]
x=random.randint(0,7)
y=random.randint(0,7)
squares_visited[x][y]=1
moves=[(-2,-1),(-2,1),(-1,-2),(-1,2),(1,-2),(1,2),(2,-1),(2,1)]
indexes=list(range(8))
tries=0
print "The horse starts in position %d,%d"%(x,y)
while True:
random.shuffle(indexes)
for _ in indexes:
cells=move(moves[indexes[_]],x,y) ##Passing as arguments x and y looks weird
x=cells[0]
y=cells[1]
#If you out this for cicle, there are no legal moves anymore(due to full completion with 1, or to lack of legit moves)
for _ in squares_visited:
if 0 in _:
squares_visited=[[0] * 8 for _ in range(8)]
tries+=1
else:
print "You managed to do it in %d tries."%(tries)
This code has a lot of problems — enough that it’s worth going over in full:
The first of many examples of over-use of global variables. When possible, pass parameters; or create a class. This is a general strategy that will help you construct more comprehensible (and thus more debuggable) algorithms; and in a general sense, this is part of why your code fails — not because of any particular bug, but because the complexity of your code makes it hard to find bugs.
Why do you name your board
a? That’s a terrible name! Use something descriptive likesquares_visited.Minor: in python 2,
[x for x in range(8)] == range(8)— they do exactly the same thing, so the list comprehension is unnecessary. In 3, it works a little differently, but if you want a list (rather than arangeobject) just pass it tolistas in (list(range(8))).So my understanding of the code so far is that
ais the board,xandyare the starting coordinates, and you’ve marked the first spot visited with a1. So far so good. But then things start to get hairy, because you callstartat the end ofrestartinstead of calling it from a top-level control function. That’s theoretically OK, but it makes the recursion more complicated than necessary; this is another part of your problem.Argh more globals…
Ok, so what you’re trying to do is go through each index in
indexesin sequence. Why are you usingwhilethough? And why isiglobal?? I don’t see it being used anywhere else. This is way overcomplicated. Just use aforloop to iterate overindexesdirectly, as inOk, now for the specific problems…
I don’t understand what you’re trying to do here. It seems like you’re calling
restartevery time you find a0(i.e. an unvisited spot) on your board. Butrestartresets all board values to0, so unless there’s some other way to fill the board with1s before hitting this point, this will result in an infinite recursion. In fact, the mutual recursion betweenmoveandstartmight be able to achieve that in principle, but as it is, it’s way too complex! The problem is that there’s no clear recursion termination condition.Here, in principle, the idea seems to be that if your move hits a
1or goes off the board, then the current branch of the recursion terminates. But becauseiandindexesare global above instart, whenstartis re-called, it re-shufflesindexesand resetsito 0! The result is sheer chaos! I can’t even begin to comprehend how that will effect the recursion; it seems likely that becauseigets reset at the beginning ofstartevery time, and because every successful call ofmoveresults in a call ofstart, thewhileloop in start will never terminate!I suppose it’s possible that eventually this process will manage to visit every square, at which point things might work as expected, but as it is, this is too complex even to predict.
Not sure what you mean by that last line, but it doesn’t sound like a good sign — you’re papering over an error instead of finding the root cause.
I’m going to play with this code a bit and see if I can get it to behave marginally better by de-globalizing some of its state… will report back soon.
Update:
Ok I de-globalized
indexesas described above. I then replaced thestart/restartrecursion with an infinite loop inrestart, areturnstatement instartwhere the call torestartused to be, and asys.exit()at the end ofstart(to break out of the infinite loop on success). The result behaves more as expected. This is still poor design but it works now, in the sense that it recursively tries a bunch of random paths until every local position has been visited.Of course it still doesn’t ever succeed; it just keeps looping. Actually finding a solution will probably require a lot more rethinking of this algorithm! But following my above suggestions should help some, at least.