[SOLVED] Seek-and-hide: Battle with the brawler

I have been play testing the level seek-and-hide. I have collected all the lightstones, but when I return to the camp to "defeat the brawler’, I am not nearly strong enough to beat him. I am level 28, my character is Anya and I have 1700 HP but a crappy weapon. I was wondering if my character is just not strong enough, or whether I am failing to trigger some kind of event to make the brawler weaker (when you collect all the stones).

I would post my code but I am afraid it is a “correct solution” and I was told I should not post those.

If you aren’t winning with your code, maybe it isn’t the winning code after all!

Post it, and we’ll figure out what might be going wrong.

Ehm, a little bit weird level. Understand your astonishment, @jacobakkerboom. Didn’t manage to pass it now for 5 minutes. I’ll try it tomorrow with fresh look, now sleeeepy)

@jacobakkerboom I Just completed it. Your approach might need tweaking :sunglasses: I do not see where brawn is needed at all.

Ok. Maybe we need to remove that goal “Defeat”. Try to continue play “seek-and-hide”. That level is simple need some additional instructions in the sample code.

Yes, “move here and look for the item, then hide in the centre, and then search for the stone there” - it’s simple. If it works in the manner the level’s author supposed it to work. But seems like it doesn’t))
May I ask you guys, who beat the level, to be so kind and try this code and say, worked it or no? Just interesting)

# Gather 4 lightstones to defeat the Brawler.
# Move along the outside of the camp, gathering the lightstones.


# The function should check for the item and move to hide.
# Complete the function:
def checkTakeHide(item):
    if item:
        # The item is here, take it.
        hero.moveXY(item.pos.x, item.pos.y)
        # Then hide. Move to the center of the camp.
    hero.moveXY(40, 34)

# Move to the right mark, then to the left one.
while True:
    # Move to the top right mark.
    hero.moveXY(68, 56)
    # Search for a stone there.
    stone = hero.findNearestItem()
    # Call the function 'checkTakeHide' with the argument 'stone'.
    checkTakeHide(stone)
    
    # Move to the top left mark, search for a stone, and call the function.
    hero.moveXY(12, 56)
    
    stone = hero.findNearestItem()
    
    checkTakeHide(stone)

You code is wrong. You are trying to hide each time, but you need to hide only if an item here.
"# Then hide. Move to the center of the camp." – that comment is placed with an indent.
Also in the intro doc it’s written too.

Ok I finished the level. Perhaps timings were off because I have the ring of speed. I had to add a delay in checkTakeItem which was quite unnatural. This is the javascript code for checkTakeItem.

function checkTakeHide(item) {
    if (item) {
        // The item is here, take it.
        hero.moveXY(item.pos.x, item.pos.y);
        // Hide after you take the item. Move to the center of the camp.
        hero.moveXY(40, 33);
    } else{
        hero.say("waiting");
        var stone = hero.findNearest(hero.findItems());
        checkTakeHide(stone);
    }
}

Here is some rather overcomplicated javascript code with continuous movement, to illustrate the problem that the brawler is not always struck by lightning. The event is not triggered when we set fightOgre = true. Also note the lack of a checkAndHide function.

// Gather 4 lightstones to defeat the Brawler.
// Move along the outside of the camp, gathering the lightstones.

var topRightPos = {"x":68, "y":56};
var topLeftPos = {"x":12, "y":56};
// var hideLeftPos = {"x":12 , "y": 20 };
// var hideRightPos = {"x":68 , "y": 20 };

var fightOgre = true;

var campPos = {"x": 40, "y":34};
var hideLeftPos = campPos;
var hideRightPos = campPos;

var nLightStones = 0;
var hideUnlessStone = false;
var firstTimeHiding = false;
var goingRight = true;
// Move to the right mark, then to the left one.

while (true) {

    // Search for a stone there.
    var stone = hero.findNearest(hero.findItems());

    if(nLightStones >= 4 && fightOgre){
        var enemies = hero.findEnemies();
        var enemy = hero.findNearest(enemies);
        if(hero.distanceTo(campPos) < 10 && hero.gold >= 20){
            hero.summon("soldier");
        }
        
        else if (enemy){

            var friends = hero.findFriends();
            var nFriends = friends.length;
            var i;
            for(i = 0; i < nFriends; i++)
            {
                var friend = friends[i];
                if(friend.type == "soldier"){
                    hero.command(friend, "attack", enemy);
                }
            }
            hero.attack(enemy);
        } 
        else{
                hero.move(campPos);
        }
  
    }
    if(stone){
        hero.move(stone.pos);
        if(hero.distanceTo(stone) < 5){
            hideUnlessStone = true;
            firstTimeHiding = true;
        }
    }
    else if(hideUnlessStone){
        if(firstTimeHiding){
            nLightStones++;
            goingRight = !goingRight;
            firstTimeHiding = false;
        }
        if( hero.pos.x < 50){
            hero.move(hideLeftPos);
        }
        else{
            hero.move(hideRightPos);
        }
        if(hero.distanceTo(hideLeftPos) < 2 || 
            hero.distanceTo(hideRightPos) < 2
        ){
            hideUnlessStone = false;
            // hero.say("I have " + nLightStones+ " stones");
        }
    }
    else {
        if(goingRight){
            hero.move(topRightPos);
        } else{
            hero.move(topLeftPos);
        }
    }
}

Another small issue is that in the sample code the line var stone = hero.findNearestItem(); does not work for me, as I can only do var stone = hero.findNearest(hero.findItems()); because of the items that I have.

The speed should be constant. Are you sure about it. Also you code looks too complex. Why are you using recursion?

The brawler is stuck by the lightning only if it’s in the center of the camp.

It’s a begin forest level and you have equipment higher than it should be for that level

I suppose the speed is indeed constant, because I get the same behaviour when I remove the ring of speed from my equipment.

The code that does not work for me, where is seems the timings don’t work well, is

// Gather 4 lightstones to defeat the Brawler.
// Move along the outside of the camp, gathering the lightstones.


// The function should check for the item and move to hide.
// Complete the function:
function checkTakeHide(item) {
    if (item) {
        // The item is here, take it.
        hero.moveXY(item.pos.x, item.pos.y);
        // Hide after you take the item. Move to the center of the camp.
        hero.moveXY(40, 33);
    }
}

// Move to the right mark, then to the left one.
while (true) {
    // Move to the top right mark.
    hero.moveXY(68, 56);
    // Search for a stone there.
    var stone = hero.findNearest(hero.findItems());
    // Call the function 'checkTakeHide' with the argument 'stone'.
    checkTakeHide(stone);
    
    // Move to the top left mark, search for a stone, and call the function.
    
    hero.moveXY(12, 56);
    // Search for a stone there.
    var stone = hero.findNearest(hero.findItems());
    // Call the function 'checkTakeHide' with the argument 'stone'.
    checkTakeHide(stone);
    
}

It does work if we change checkTakeHide to the version with recursion in my previous comment.

Illustrations of bad timing

The ogre sees me

A few seconds later, the ogre doesn’t die

Ok I see now that the position inside the camp should be {"x":40, "y": 34}, instead of my {"x":40, "y": 33}. Then it works without tacky hacks.

Yeah, {40, 34} is the center of the map (80x68 is the most common size for levels).

Thanks a lot! My mistakes. Assigning stone = hero.findNearestItem() once per loop like this:

while True:
    # Move to the top right mark.
    hero.moveXY(68, 56)
    # Search for a stone there.
    stone = hero.findNearestItem()
    # Call the function 'checkTakeHide' with the argument 'stone'.
    checkTakeHide(stone)
    
    # Move to the top left mark, search for a stone, and call the function.
    hero.moveXY(12, 56)
    
    #stone = hero.findNearestItem()
    
    checkTakeHide(stone)

causes Brawlers to hunt Anya to death (https://youtu.be/DEql_sDg89o). With several tries I misplaced this part on purpose. And after placing stone = hero.findNearestItem() for the second time I didn’t correct indents in

 if item:
        # The item is here, take it.
        hero.moveXY(item.pos.x, item.pos.y)
        # Then hide. Move to the center of the camp.
    hero.moveXY(40, 34)

I must apologize to the level’s author, it’s brilliant!

No, thank you for the feedback. I think the comment above the function “check and hide” was a little confusing and I extended it.

2 Likes

@Bryukh This might be a fun level to have a damage high score board attached to it. Since being able to attack the enemies would have to be something you did later, it could add a bit of replay to the level as you later try to defeat some of the ogre brawlers with high level equipment before time ran out.

Nice idea, but it’s quite hard because of time limitation in this level variant) While first attempt to pass the level I tested a few ways to cheat: invisibility, chain-lightning, building fences, even fire-traps!)) It didn’t work. It’s impossible to make a lot of additional movements and manage to complete collecting 4 lightstones needed simultaneously. Besides, it seemed to me, that in case of making additional movements the frequency of lightstones’ respawning slows down (maybe I’m wrong though). I just have made about 250 damage points and win, but it rather evoke smile, than respect)
Time increase needed or enemies’ health decrease for completing all goals with damage doing, I suppose.
Again, maybe professional programmers could do it without changes in level, dunno.

That level has “damage-dealt” sccore board

you can try a different option, like this:

def checkTakeHide():
lightstone = hero.findNearestItem()
if lightstone:
# The item is here, so take it.
hero.moveXY(lightstone.pos.x, lightstone.pos.y)
# Then move to the center of the camp (40, 34)
hero.moveXY(40,34)

while True:
# Move to the top right X mark.
hero.moveXY(68, 56)
# Call checkTakeHide with the argument
checkTakeHide()
# Move to the top left mark.
hero.moveXY(12,56)
# Call the checkTakeHide function.
checkTakeHide()