# Sarven Treasure - Please find my error

I have been trying to make this work for hours. I was stuck at always getting 143/150 coins and scratched it and tried a new method. Currently, my guy just runs to the top, mid-right of the map OR he teleports once and then runs to the top, mid-right. I have NO idea why he is going to (x=48, y=62). I want him to just run around picking up silver/gold coins and running into a teleporter if an ogre gets too close or no coins are near him.

``````loop:
minDistance = 20
coinIndex = 0
coins = self.findItems()
ogres = self.findEnemies()
ogre = self.findNearest(ogres)
closestCoin = self.findNearest(coins)

while coinIndex < len(coins):
target = coins[coinIndex]
coinIndex += 1
distance = self.distanceTo(target)

if distance < minDistance and target.value >= 2:
minDistance = distance
closestCoin = target

if minDistance < 30 and closestCoin and not ogre:
self.moveXY(closestCoin.pos.x, closestCoin.pos.y)

if minDistance < 30 and closestCoin and ogre:
ogreDistance = self.distanceTo(ogre)

if ogreDistance >= 10 and closestCoin:
self.moveXY(closestCoin.pos.x, closestCoin.pos.y)

elif closestCoin:

if self.pos.x > 43 and self.pos.y > 38:
self.moveXY(75, 50)
if self.pos.x > 43 and self.pos.y <= 38:
self.moveXY(75, 20)
if self.pos.x <= 43 and self.pos.y > 38:
self.moveXY(5, 50)
if self.pos.x <= 43 and self.pos.y <= 38:
self.moveXY(5, 20)
self.moveXY(closestCoin.pos.x, closestCoin.pos.y)
pass

``````

I canâ€™t get the self.moveXY(variable, variable) to work at all. It always says I need to put an integer in. But if I need to move to an integer, Iâ€™ll have no way of getting him to move to the coins?

Nice approach. Basically, you donâ€™t have enough `elif` and `else` statements, so instead of moving towards one coin in the loop, you are moving towards the coin, then moving over here, and then moving over there, and then moving back to that coin (which you already picked up).

This one is a bit tricky to debug, but I can tell you how to make it really easy to debug: only take one action per iteration of your `loop`. So only one `move` or `attack` or `powerUp` or whatever. Donâ€™t let an `if` containing an action follow another `if` with an actionâ€“make sure itâ€™s `elif` or `else`. Otherwise, your data (what coins there are, what ogres are where, what are the distances and values and such) will be stale when you take the second action, since you havenâ€™t iterated up to the top of the loop again to refresh it.

This is a good strategy for most levels, by the way. Your job on each loop iteration is just to decide what to do next, not what to do after that.

Hope this helps!

I copied & pasted your code and it works for meâ€¦

What glasses are you wearing? (This determines how far you can see)

your code has no â€śIf I canâ€™t see a coinâ€¦â€ť put in an:

``````    else:
self.say("Ack, pbht. I don't see any coins")
``````

and see if that is what is happening. If so then either get better glasses or give him some where to go to look for more coins.

(Edit: sneaky nick poking save right before me.)

A general tip for this level is simplify it a bit. One general strategy, for example:

``````if enemy is close:  # but how close?
escape to portal  # but which portal?
else:
pickup a coin
``````

Maybe you can improve on that, but try to not have it be more complicated than that to begin with. You can add more details later, of course.

Also, when you find yourself repeating similar lines, try to recode:

``````if minDistance < 30 and closestCoin and not ogre:
do stuff
if minDistance < 30 and closestCoin and ogre:
do stuff
``````

could be

``````if minDistance < 30 and closestCoin:
if ogre:
do stuff
else:
do stuff
``````

Just some ideas, hope it helps.

Thank you everyone for the replies! I was able to fix the bugs in it using your advice (though I still canâ€™t pick up the 150 coins in time!). This is a really great community. Here is my fixed code, in case anyone stumbles upon this post due to a similar problem:

``````loop:
minDistance = 20
coinIndex = 0
coins = self.findItems()
ogres = self.findEnemies()
ogre = self.findNearest(ogres)
closestCoin = self.findNearest(coins)

while coinIndex < len(coins):
target = coins[coinIndex]
coinIndex += 1
distance = self.distanceTo(target)

if distance < minDistance and target.value >= 2:
minDistance = distance
closestCoin = target

# If no ogre and a coin nearby, get it.
if minDistance < 30 and closestCoin and not ogre:
self.moveXY(closestCoin.pos.x, closestCoin.pos.y)

#If an ogre and a nearby coin, get the coin unless the ogre is close. If the ogre is close, teleport.
elif minDistance < 30 and closestCoin and ogre:
ogreDistance = self.distanceTo(ogre)

if ogreDistance >= 10 and closestCoin:
self.moveXY(closestCoin.pos.x, closestCoin.pos.y)

elif closestCoin:

if self.pos.x > 43 and self.pos.y > 38:
self.moveXY(75, 50)
if self.pos.x > 43 and self.pos.y <= 38:
self.moveXY(75, 20)
if self.pos.x <= 43 and self.pos.y > 38:
self.moveXY(5, 50)
if self.pos.x <= 43 and self.pos.y <= 38:
self.moveXY(5, 20)
pass

#Otherwise, say "no coin!".
else:
self.say("no coin!")
``````

Hmm, your â€śdefaultâ€ť minDistance (20) is less than your â€śif minDistance < 30â€ť so it can never be â€ś>= 30â€ť

You set closestCoin to the nearest coin â€śclosestCoin = findNearest(coins)â€ť then you loop through all the coins to find the nearest closer than 20â€¦ then check to see if the nearest is < 30â€¦

SO, if the closest coin is >= 20 away you will still go to it (regardless of value).
the loop over all coins will find none so, minDistance will still be 20, and closestCoin will still be the one returned by findNearestâ€¦(no matter how far away)

I have tinkered with my code, hoping to get my guy to pick up the coins faster. Sadly, I broke it again! This level is my curse. I get â€śFix Your Code: Itâ€™s either really slow or has an infinite loop.â€ť I want to understand my mistake so that I can get better. I have been modify it for hours and itâ€™s been all over the place. I canâ€™t find which part of my code is infinitely looping or using up all of the memory.

``````# Create my variables and indices.
loop:
coinIndex = 0
coins = self.findItems()
ogres = self.findEnemies()
ogre = self.findNearest(ogres)
bestCoin = None
bestRating = 0

#Cycle through my array of coins and choose the best one based on coin
# value and it's dstance from me. Give it the name "bestCoin" and a
# rating of "bestRating"
while coinIndex < len(coins):
currentCoin = coins[coinIndex]
coinIndex += 1
coinDistance = self.distanceTo(currentCoin)
currentRating = 100 * currentCoin.value / coinDistance
if currentRating > bestRating:
bestRating = currentRating
bestCoin = currentCoin
else:
pass

# If I have a "bestCoin" and the rating is decent, we will do things.
if bestCoin and bestRating > 10:
# First let's see if there is an ogre.
if ogre:
ogreDistance = self.distanceTo(ogre)
# The ogre is far away. Let's grab that coin!
if ogreDistance > 15:
self.move({"x": bestCoin.pos.x, "y": bestCoin.pos.y})

# The ogre is too close. Let's run to a teleporter.
else:
if self.pos.x > 43 and self.pos.y > 38:
self.moveXY(77, 51)
elif self.pos.x > 43 and self.pos.y <= 38:
self.moveXY(77, 19)
elif self.pos.x <= 43 and self.pos.y > 38:
self.moveXY(5, 50)
elif self.pos.x <= 43 and self.pos.y <= 38:
self.moveXY(5, 20)
bestCoin = None
else:
pass
# Ok, there was no ogre. Let's grab that coin!
else:
self.move({"x": bestCoin.pos.x, "y": bestCoin.pos.y})
# The closest "bestCoin" seems to be pretty far away. Let's use a
# teleporter.
else:
if self.pos.x > 43 and self.pos.y > 38:
self.moveXY(77, 51)
elif self.pos.x > 43 and self.pos.y <= 38:
self.moveXY(77, 19)
elif self.pos.x <= 43 and self.pos.y > 38:
self.moveXY(5, 50)
elif self.pos.x <= 43 and self.pos.y <= 38:
self.moveXY(5, 20)
bestCoin = None
else:
pass
``````

IT ACTUALLY WORKED ONCE! And then the next game my guy just stood in the corner and was beaten to death :â€™(

Honestly, the code doesnâ€™t have to be this complicated. Try just grabbing the nearest coin (as long as nearest enemy is some distance away) and see how that works. I think you will be pleasantly surprisedâ€¦

The â€śDevourerâ€ť is the hunt for bestCoin. it runs EVERY time you take a step. This is the achilles heel of â€śmove()â€ť (nick is working on it). The only thing that can be done about it is to not do it . . . either at all (as Eiler13 suggests) or less often (by some means, say? time passage, move distance, need new best coin, etc).

I tried the suggestion of eiler13, but this doesnâ€™t work at all. I never come close to 150 gold. I think the most I got was 122. Grabbing the nearest coin without additional smarts just isnâ€™t fast enough. I thought of trying what Elthran was doing (it was actually my first thought of what to do), but I actually got fewer coins.
What do I try next? I donâ€™t have slow boots or anything, but I kill the ogres first because it takes two hits and then theyâ€™re dead.

``````loop {
var enemy = this.findNearest(this.findEnemies());
if (enemy) {
while (enemy.health > 0) {
this.attack(enemy);
}
}
var item = this.findNearest(this.findItems());
if (item) {
var goldDistance = this.distanceTo(item);
if (goldDistance > 15) {
var x; var y;
if (this.pos.x > 40) {x = 75;}
else {x = 5;}
if (this.pos.y > 35) {y = 50;}
else {y = 20;}
this.moveXY(x, y);
}
else {this.moveXY(item.pos.x, item.pos.y);}
}
}
``````

It might make sense to use a while-loop to kill the ogres first instead of killing one at a time and fetching coins in between.

there is no time =\

``````x = self.pos.x
y = self.pos.y
a = (5,48)
b = (5,19)
c = (75,51)
d = (75,20)
lista = [a,b,c,d]
def distancia(x1,y1,x2,y2):
return (((x1-x2)**2 + (y1-y2)**2 )**(1/2))
loop:
item = self.findNearest(self.findItems())
enemy = self.findNearest(self.findEnemies())
if enemy:
if self.distanceTo(enemy)<=5:
self.shield()
menor = 9999
vez = a
for lugar in lista:
dist = distancia(lugar[0],lugar[1],self.pos.x,self.pos.y)
if dist < menor:
menor = dist
vez = lugar
x = vez[0]
y = vez[1]
elif item:
x = item.pos.x
y = item.pos.y
elif item:
x = item.pos.x
y = item.pos.y
self.moveXY(x, y)
``````

Iâ€™m afraid Iâ€™m having a hard time understanding your variables. Could you please explain what they are?

It doesnâ€™t have to be that complicated. Here is how i did it:

[redacted, we donâ€™t post correct code]
This is my first post so i canâ€™t figure out how to get the indentation right sorry.

You realize that there is a topic that says â€śFAQ â€“ read before postingâ€ť. If you had read it, then you would know how to format your code. Also we donâ€™t post correct code to begin with. It provides easy answer without providing the learning experience.

1 Like

sorry about that! I havenâ€™t been on here much i didnâ€™t realize that. Wonâ€™t happen again. And iâ€™ll read the FAQ.

1 Like

doesnâ€™t work???

@Tailin.Chen

If you click on D0rm1nd0â€™s name from his post, youâ€™ll see that the person you are replying to hasnâ€™t been logged into this board for over two years. If youâ€™re having problems with a level, itâ€™s best to start a new post or at least post your code here so we can assist you.