Misty island mine help


#1

I think I’ve already written the code correctly,but it does not work.Here is my code:

def findBestItem(friend, excludeItems):
    items = friend.findItems()
    bestItem = None
    bestItemValue = 0
    for item in items:
        if item in excludeItems:
            # Another peasant is already targeting this item
            # The continue statement skips to the beginning of the next iteration of the for-loop
            continue

        # Find the best item: value divided by distance
        distance=friend.distanceTo(item)
        rating=item.value/distance
        if rating > bestItemValue:
            bestItem=item
            bestItemValue=rating
    # Make sure to return the bestItem!
    return bestItem
loop:
    peasants = self.findByType("peasant",self.findFriends())
    claimedItems = []
    for peasant in peasants:
        nearest = peasant.findNearest(peasant.findEnemies())
        # Peasants have gold and costOf() properties, and obey the "buildXY" command.
        # If there's an enemy within 10 meters targeting this peasant, build a "decoy" if we can afford one.
        # You can get the enemy's target with nearest.target
        # Otherwise, use findBestItem to target the best coin to collect
        # Use claimedItems.append(item) to add it to the claimedItems array.
        if nearest:
            distance2=peasant.distanceTo(nearest)
            if nearest.target == peasant and distance2 <= 10:
                if peasant.gold >= peasant.costOf("decoy"):
                    self.command(peasant, "buildXY", "decoy",peasant.pos.x-2,peasant.pos.y)
        coin=findBestItem(peasant,claimedItems)
        if coin:
            claimedItems.append(coin)
            self.command(peasant, "move", coin.pos)

With these code above,the peasants won’t build anything and die immediately when ogres come

I want to know why


#2

Are you sure you are sending the right number of parameters to this function? Look at the command to move the peasant for an example. If the function requires a position object, make sure you are sending the object and not individual coordinates.


#3

can you please elaborate on what you are hinting at, I think I am having the same issue, I get no errors when I run my code, I’ve tried every combination of creating newX and newY variable, using peasant.pos, peasant.pos.x, using {x: 30, y: 36} just to test but I just can absolutely not get my peasants to build a decoy once I have collected the 25 coins worth. Pasting my code below. Again, no errors are produced, but neither are any decoys!!

// Collect gold efficiently by commanding peasants wisely!
// Peasants should collect coins and build decoys.

// The function should return the best item per target
// Use an array of ids to ensure no two peasants target the same item.
function findBestItem(friend, excludedItems) {
var items = friend.findItems();
var bestItem = null;
var bestItemValue = 0;
for(var i = 0; i < items.length; i++) {
var item = items[i];
// indexOf searches and array for a certain element:
var idx = excludedItems.indexOf(item);
// If the array doesn’t contain it, it returns -1
// In that case, skip over that item as another peasant is targeting it.
if(idx != -1) { continue; }
// Finish the function!
// Remember bestItemValue should be the highest item.value / distanceTo
if (item && (item.value / friend.distanceTo(item)) > bestItemValue) {
bestItemValue = item.value;
bestItem = item;
}
}
return bestItem;
}

while(true) {
var peasants = hero.findByType(“peasant”);
// Create a new array every loop.
var claimedItems = [];
for(var i = 0; i < peasants.length; i++) {
var peasant = peasants[i];
var enemy = peasant.findNearestEnemy();
if(enemy) {
// If the distance to enemy is < 10
// AND the hero has enough gold for a decoy
if (hero.gold >= hero.costOf(“decoy”)) {
// Command a peasant to build a “decoy”:
hero.command(peasant, “buildXY”, “decoy”, peasant.pos.x, peasant.pos.y);
}
}
var item = findBestItem(peasant, claimedItems);
if(item) {
// After an item is claimed, stick it in the claimedItems array
claimedItems.push(item);
// Command the peasant to collect the coin:
hero.command(peasant, “move”, item.pos);
}
}
}


#4

sorry, let me make that more readable

// Collect gold efficiently by commanding peasants wisely!
// Peasants should collect coins and build decoys.

// The function should return the best item per target
// Use an array of ids to ensure no two peasants target the same item.
function findBestItem(friend, excludedItems) {
    var items = friend.findItems();
    var bestItem = null;
    var bestItemValue = 0;
    for(var i = 0; i < items.length; i++) {
        var item = items[i];
        // indexOf searches and array for a certain element:
        var idx = excludedItems.indexOf(item);
        // If the array doesn't contain it, it returns -1
        // In that case, skip over that item as another peasant is targeting it.
        if(idx != -1) { continue; }
        // Finish the function!
        // Remember bestItemValue should be the highest item.value / distanceTo
        if (item && (item.value / friend.distanceTo(item)) > bestItemValue) {
            bestItemValue = item.value;
            bestItem = item;
        }
    }
    return bestItem;
}

while(true) {
    var peasants = hero.findByType("peasant");
    // Create a new array every loop.
    var claimedItems = [];
    for(var i = 0; i < peasants.length; i++) {
        var peasant = peasants[i];
        var enemy = peasant.findNearestEnemy();
        if(enemy) {
            // If the distance to enemy is < 10
            // AND the hero has enough gold for a decoy
            if (hero.gold >= hero.costOf("decoy")) {
                // Command a peasant to build a "decoy":
                hero.command(peasant, "buildXY", "decoy", peasant.pos.x, peasant.pos.y);
            }
        }
        var item = findBestItem(peasant, claimedItems);
        if(item) {
            // After an item is claimed, stick it in the claimedItems array
            claimedItems.push(item);
            // Command the peasant to collect the coin:
            hero.command(peasant, "move", item.pos);
        }
    }
}


#5

@zydm my apologies, I was thinking of a different function. You are right, the code would appear to be ok.

I did some testing and added a “continue” to the part where the decoy should be built. That fixed it on my end. The peasant was actually able to create the decoy.

if peasant.gold >= peasant.costOf("decoy"):
    self.command(peasant, "buildXY", "decoy",peasant.pos.x-2,peasant.pos.y)
    continue

Its odd though why that should be needed. It might have something to do with the way the loops are running and how much time it takes to do all of the actions in the code.