This is impossible: Munchkin Swarm - Javascript


#1

I can’t figure out why I can’t pass this level. It looks like everything is working fine, until right after the second “cleave” when another mob immediately descends and kills me within a half second. I don’t know what else I’m supposed to do to survive, because there is not enough time to cleave again and there are too many to kill using “attack”. Please help! Here is my code:

var enemy = this.findNearest(this.findEnemies());

loop {   
if(this.isReady("cleave")){
    if(this.distanceTo(enemy)<10){
        this.cleave(enemy);
    }
    else{
        this.attack("Chest");
            }
    }
else{
    this.attack("Chest");
        }  
}

#2

You set enemy outside the loop . . . . only gets set once…


#4

I tried it your way and put it inside the loop and it did the exact same thing.
I thought in Javascript declaring a variable like that makes it have a global scope, so it can be accessed by anything. It shouldn’t matter whether I put it in the loop or not, I think. If that’s not the case please explain, I’m no expert.


#5

It can be used anywhere/anytime . . . but it never gets set again, so it always contains that first enemy you saw when it ran the first time.

I copied and pasted your code and moved the "var enemy = " between “loop{” and “if(” and it worked fine…

loop {   
    var enemy = this.findNearest(this.findEnemies());
    if(this.isReady("cleave")){
// etc...

this would also work just fine:

var enemy;
loop {
    enemy = this.findNearest(this.findEnemies());
    if(this.isReady("cleave")){
// etc...

it is the setting it equal to “find…” that needs to happen over and over.


#6

I don’t know what you mean. But I did this code, and it did the same thing: The issue was never that it stopped working, I just get attacked by a second group immediately after the second cleave before the dude has even a half second to do anything else. Maybe it’s a bug.

loop {
var enemy = this.findNearest(this.findEnemies());    
if(this.isReady("cleave")){
    if(this.distanceTo(enemy)<10){
        this.cleave(enemy);
    }
    else{
        this.attack("Chest");
            }
    }
else{
    this.attack("Chest");
        }  
}

#7

It isn’t working for me. In fact, even though that was the only thing I changed, now it stops attacking the chest after the first cleave.


#8

The original code would “work”, as soon as cleave was ready you should cleave, regardlass off how close the other enemies were because the first guy (Brack"?) is at your feet, dead.

For fun put a “this.say(enemy);” right after the “var enemy =”

I just copied and pasted your second set of code and it works fine. try exiting the level and reloading it.


#9

She just stands there and an error message pops up saying “Say what?”

var enemy = this.say(enemy);


#10

Sorry, I, OH, That was REALLY bad wording on my part.

var enemy = this.findNearest(this.findEnemies());
this.say(enemy);

is what I meant.

Anyway, try reloading the level.


#11

Sigh. No it still doesn’t work. However, adding the “say” part enabled her to get a third cleave in before the hoard descended, before that happened right at the second cleave. I think it’s set up for me to never pass it, haha.


#12

It should go like this: (with no “say”)
attack chest…
first hoard descends, CLEAVE
attack chest…
second hoard descends, CLEAVE
attack chest…POP!!! yeah!!

Did you reload the level?


#13

Yup. I’m going to try on a different computer just for fun, since it seems to be my browser specifically and is working for you.


#14

Chrome? Firefox? IE? Safari? ??


#15

Chrome, and so far it’s doing the same thing on my other computer. I have weird issues sometimes when using Chrome on this computer, so I thought it might be it but apparently not. Let me try Firefox.


#16

AGGHH. I can’t get to it from Firefox. It says website is down, can’t connect to servers, etc. I did manage to get into the log in page, but when I input my info and hit log in, it stopped working. I give up. This level hates me and will never allow me to pass it. It’s alive.


#17

Sounds like the relationship I have with hardware.

The code you posted:

loop {
    var enemy = this.findNearest(this.findEnemies());    
    if(this.isReady("cleave")){
        if(this.distanceTo(enemy)<10){
            this.cleave(enemy);
        }
        else{
            this.attack("Chest");
        }
    }
    else{
        this.attack("Chest");
    }  
}

Works fine.
(I moved it over 4 spaces to make it prettier. doesn’t effect how it works in javascript)


#18

Got Firefox to work, and my code still did not. As long as you say the code was correct that’s all that matters. It will bother me forever if I leave ONE level incomplete, but OHWELL. Thanks for your help though!


#19

I am sorry to bring this up, but there is a glaring misperception that will be critical to your success in JavaScript. I did think it better to address immediately.

This is not true, in almost any circumstance. If you use a variable without declaring it (no var), it will be first search all scopes up to the global scope. If it is not found, it is created into the nearest accessible global scope. However, this is a bad idea… always. When you declare a variable (using var), it gets created in the scope it is currently in.


global = value;    //  <-- This will be created globally because it wasn't declared
                   //      before it was used.

var local;         //  <-- Even though it is not assigned, this is local to this scope
                   //      and is accessible to most (not all) scopes contained within

function myFunc() {
    local = 5;     //  <-- not declared, so it climbs up each scope to find if it is
                   //      defined. It finds it one scope up.
}

It might not seem like a big deal, but in JavaScript in particular, knowing how scopes work is critical to success.

Hope you find this useful!


#20

Thank you for your explanation. I understand what you mean by global and not using “var”, and I had actually forgotten about that because it’s been so long since I had studied it. But what I meant by declaring a variable “like that” was declaring it outside of a function, or in other words just by itself in the code. This is the lesson I had done that referred to it as having global scope:

Let’s talk about an important concept: scope. Scope can be global or local.

Variables defined outside a function are accessible anywhere once they have been declared. They are called global variables and their scope is global.

For example:

var globalVar = “hello”;

var foo = function() {
console.log(globalVar); // prints “hello”
}
The variable globalVar can be accessed anywhere, even inside the function foo.

So I still don’t quite understand why in this case it needed to be in the loop and wouldn’t work outside of the loop like Vlevo was saying. Isn’t it stored in memory because it was already declared at the top and would work in the loop regardless of being declared outside of it?


#21

Bad explaining on my part, Is the reason.

var enemy = findBlah(findBleck);        // :)  finds an enemy who will soon die.
// This is "global", you can use it "anywhere below.
//     It has been set to something, but if never changed . . . well it won't change.
//         No matter where that enemy goes, alive or dead.
//             "enemy" will still be that one enemy.

loop{
    // time passes, the "enemy" dies, his lifeless body lies at your feet.
    //     new enemies come to harass you . . . but "enemy" never changes,
    //         it is still set to the lifeless body at your feet.
    //         distanceTo enemy body is now always <10,
    //             so as soon as cleave is ready SWISH you cleave the air.
}
// ---- ---- ---- ---- 
// Let's start over
// ---- ---- ---- ---- 

var enemy = findBlahBlah();  // "global" enemy variable

loop{
    if(isReady("Kill'm dead.")){
        // He's dead, Jim.
    enemy = findNewEnemy(toKill);    // ...must change the contents of "enemy"...
}
// I put it at the bottom, only for mental order, kill enemy, need new enemy.
// The next statement is the one right after "loop{" so it doesn't matter
//     if "enemy = .." is at the top or bottom of the loop, either way,
//     it happens -before- the next time the "if" is checked.
// ---- ---- ---- 
// Nothing wrong with this next way, some people like it better
// ---- ---- ---- 

var enemy;
loop{
    enemy = find....
    if(){
        etc
    }
}
// enemy is global, but you only have the "setting it code" once and it is inside
//     the loop so it happens over and over, therefore it gets set to the nearest enemy
//     every time, and when the first set dies it gets set to enemies in the second
//     set, etc.
// ---- ---- ---- 
// A lot of people write it this way
// ---- ---- ---- 
loop{
    var enemy = ...
    if(){
    }
}
// "enemy" is never used outside the loop. So, doesn't -need- to exist there.
//     This version, like the previous, only has the "Setting it code" once.
//         (Less copies to change if you made a mistake.)

(If you read this post in your email. Please read it again it, I have changed/added to it.)