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.
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);}
}
}
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)
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.
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.