# Is this Python pathfinder efficient enough?

I'd like to see if my code follows common practice, or is already efficient or fast enough.

from random import randint
w=[[2,0,0,0,0],[0,0,2,0,0],[0,0,1,0,0],[0,0,0,0,0],[0,0,0,0,0]] #1 represent Mr.Pacman, #2 represent food.
for y in xrange(len(w)): #Finding the coordinate of Mr.Pacman
for x in xrange(len(w[0])):
if (w[y])[x]==1:
hor=x
ver=y
break

horbound=len(w[0])
verbound=len(w)
def letsCout(xCurrent,yCurrent,xTarget,yTarget,xBoundary,yBoundary,checkedSquare):
if (xCurrent+1==xTarget and yCurrent==yTarget) or (xCurrent-1==xTarget and yCurrent==yTarget) or (xCurrent==xTarget and yCurrent+1==yTarget) or (xCurrent==xTarget and yCurrent-1==yTarget):
return 1
else:
battle=[9999,9999,9999,9999]
d=[]
d.extend(checkedSquare)
d.append([xCurrent,yCurrent])
if xCurrent-1>-1 and [xCurrent-1,yCurrent] not in d: #going left
battle[0]=letsCout(xCurrent-1,yCurrent,xTarget,yTarget,xBoundary,yBoundary,d)+1
if xCurrent+1<xBoundary and [xCurrent+1,yCurrent] not in d: #going righ
battle[1]=letsCout(xCurrent+1,yCurrent,xTarget,yTarget,xBoundary,yBoundary,d)+1
if yCurrent-1>-1 and [xCurrent,yCurrent-1] not in d: #going up
battle[2]=letsCout(xCurrent,yCurrent-1,xTarget,yTarget,xBoundary,yBoundary,d)+1
if yCurrent+1<yBoundary and [xCurrent,yCurrent+1] not in d: #going down
battle[3]=letsCout(xCurrent,yCurrent+1,xTarget,yTarget,xBoundary,yBoundary,d)+1
battle.sort()
return battle[0]
#
happy=[9999,9999,9999,9999]
for y in xrange(len(w)): #Checking the coordinate of a food. If multiple food exist, the method will find the food with the smallest cost.
for x in xrange(len(w[0])):
if (w[y])[x]==2:
if hor-1>-1: #going left
if (w[ver])[hor-1]==2:
happy[0]=1
else:
candidate=[happy[0],letsCout(hor-1,ver,x,y,horbound,verbound,[[hor,ver]])+1]
candidate.sort()
happy[0]=candidate[0]
if hor+1<horbound: #going right
if (w[ver])[hor+1]==2:
happy[1]=1
else:
candidate=[happy[1],letsCout(hor+1,ver,x,y,horbound,verbound,[[hor,ver]])+1]
candidate.sort()
happy[1]=candidate[0]
if ver-1>-1: #going up
if (w[ver-1])[hor]==2:
happy[2]=1
else:
candidate=[happy[2],letsCout(hor,ver-1,x,y,horbound,verbound,[[hor,ver]])+1]
candidate.sort()
happy[2]=candidate[0]
if ver+1<verbound: #going down
if (w[ver+1])[hor]==2:
happy[3]=1
else:
candidate=[happy[3],letsCout(hor,ver+1,x,y,horbound,verbound,[[hor,ver]])+1]
candidate.sort()
happy[3]=candidate[0]

wow=["left","right","up","down"]
while True: #The decision. The lowest cost direction for next move will be picked. If there is tie for lowest cost, I want to pick it randomly
poop=randint(0,3)
for x in xrange(4):
if happy[poop]>happy[x]+1:
break
else:
print wow[poop]
break


I honestly see this project as a dynamic programming task. Is this code good enough?

• How efficient is "efficient enough"? And it certainly doesn't follow common practice. – jonrsharpe Jul 14 '14 at 15:53
• Faster and takes less memory can be a good point to start as efficient enough =) – Realdeo Jul 14 '14 at 15:59
• Whatever you want to improve, you will get more reviews if people can read your code. A good start would be lines short enough that reviewers don't have to scroll right, and variable names long enough that the meaning is clear. If you then post the readable code in a new question you will see how many more reviews you get. – trichoplax Jul 21 '14 at 14:20

You have far too many lines with more than 80 characters, you even have a line with 180+ characters: Does not fit my screen.

You may, as PEP8 states, put spaces around binary operators.

You also have an undocumented function with a name that does not helps me.

Seems you have copy/pasted some code many times, that's not DRY, and that may be bad, you may win some readability by using a function.

You should not use this kind of control flow:

for y in xrange(len(w)):
for x in xrange(len(w[0])):
if (w[y])[x]==2:
if hor-1>-1: #going left
if (w[ver])[hor-1]==2:


That's freaking unreadable, and I'll NOT read it. Avoid imbricate so many control flow.