10

I've searching and trying other suggestions in StackOverflow. Unfortunately the answers are not working for me. They are suggesting to use 'foreach' instead of 'for', but how could I... if I want to iterate just 50 times? :<

Well, I'll just paste the code and let's see if some good folk can help me.

JSLint was unable to finish.

Unexpected 'for'. for (var i=1;i<=50;i+=1){
line 6 column 8

Unexpected 'var'. for (var i=1;i<=50;i+=1){
line 6 column 13

    "use strict";

    var campo = [];
    var ronda = 0;

    // Llenamos el campo de 50 humanos/maquinas/extraterrestres = 150 jugadores
    for (var i=1;i<=50;i+=1){
        campo.push(new Human("h"+i));
        campo.push(new Machine("m"+i));
        campo.push(new Alien("e"+i));
    }

    // Array.prototype.suffle para barajar el Array
    Array.prototype.shuffle = function() {
        var input = this;

        for (var i=input.length-1;i>=0;i-=1){
            var randomIndex = Math.floor(Math.random()*(i+1));
            var itemAtIndex = input[randomIndex];

            input[randomIndex]=input[i];
            input[i] = itemAtIndex;
        }
    };

    // Barajamos el Array campo
    campo.shuffle();

    // Comprobamos que quedan más de 1 jugador por ronda
    while (campo.length>1) {
        console.log("Iniciando ronda: " + ++ronda);
        console.log(campo.length + " jugadores luchando.");
        // Recorremos el campo, y luchamos

        var muertos = 0;

        for (var i=0; i<campo.length-1; i+=2){
            // Caso de numero impar de jugadores:
            // Por ejemplo cuando solo quedan 3 jugadores. Pelean 1 vs 2. El 3 se libra.
            // - Si siguen vivos y aguantan otra ronda, se barajan las posiciones otra vez y
            //  vuelven a pelear dos. Y el nuevo tercero no pelea.
            // - Si uno de los dos muere, en la siguiente ronda ya solo quedan 2, y pelean normal.

            campo[i].fight(campo[(i+1)]);
            // # descomentar solo la siguiente linea para hacer comprobaciones #
            // console.log("["+ campo[i].username + "] VS ["+ campo[(i+1)].username + "]");
            if (campo[i].health<=0) {
                console.log("El " + campo[i].constructor.name + " llamado " + campo[i].showName() + " ha sido asesinado :<");
                var fallecido = campo.splice(i, 1);

                // # descomentar solo la siguiente linea para hacer comprobaciones #
                //console.log(fallecido[0]);
                i--; // como el array se hace pequeño, hay que corregir el error para que no se salte jugadores
                muertos++;
            } else {
                if (campo[(i+1)].health<=0) {
                    console.log("El " + campo[(i+1)].constructor.name + " llamado " + campo[(i+1)].showName() + " ha sido asesinado :<");
                    var fallecido = campo.splice((i+1), 1);

                    // # descomentar solo la siguiente linea para hacer comprobaciones #
                    // console.log(fallecido[0]);
                    i--; // como el array se hace pequeño, hay que corregir el error para que no se salte jugadores
                    muertos++;
                }
                else {
                    // # descomentar solo la siguiente linea para hacer comprobaciones #
                    // console.log("Siguen vivos");
                }
            }
        }

        console.log("Fin de ronda!")
        if (muertos === 1) {
            console.log("Ha muerto " + muertos + " jugador.");
        } else {
            console.log("Han muerto " + muertos + " jugadores.");
        }

        // Al final de la ronda barajamos de nuevo
        campo.shuffle();
   }

    if (campo.length === 1) {
        console.log("Vaya!! Ha sido una memorable batalla!");
        console.log("Después de tantos bits derramados y de " + ronda + " rondas... el jugador '" + campo[0].constructor.name + "' llamado '" + campo[0].showName() + "' se ha alzado con la victoria!!");
    }

There are some other for in the code, but It seems to stop at the first one. Thank you in advance! Forgot to say, the code works PERFECT. But I was just validating it with JSLint, also 'tolerating' for warnings in JSLint doesn't work.

Jose Serodio
  • 1,390
  • 3
  • 17
  • 31
  • 7
    This is just Crockford being stupid, again, telling you `for` loops should never ever be used. I would just ignore it. – adeneo Feb 10 '16 at 22:46
  • This question indicates there is an option to ignore this warning 'tolerate for'. http://stackoverflow.com/questions/30518554/jslint-unexpected-for – miltonb Feb 10 '16 at 22:48
  • Yeah, ignoring it should be the best... but I just want to really learn how to deal with this. I know there are a lot of threads with this "for" problem but no one worked for me. Thank you anyways! – Jose Serodio Feb 10 '16 at 22:50
  • @miltonb yeah, (I edited it at the bottom) that I've tried to check "Tolerate For Statement" warnings in JSLint but it is still giving me the warning. – Jose Serodio Feb 10 '16 at 22:53

2 Answers2

7

When you choose to tolerate for, the next thing it's warning you about is the global declaration of the var i. Since you've got the for-loop at the top-level, i becomes available everywhere in your program.

I'd just tolerate for and wrap it up an in IIFE. That way, i is only available inside this function, and doesn't leak out to the global scope.

(function() {
    var i = 0;
    for (i=1;i<=50;i+=1) {
        campo.push(new Human("h"+i));
        campo.push(new Machine("m"+i));
        campo.push(new Alien("e"+i));
    }
})();

You could also, barring using an existing implementation out there, create a function that generalizes the "repeat n times" definition.

function repeat(fn, n) {
  var i = 0;
  for (;i < n; i += 1) {
    fn();
  }
}

Use in your case would look like:

function initialize() { 
    campo.push(new Human("h"+i));
    campo.push(new Machine("m"+i));
    campo.push(new Alien("e"+i));
}

// then later
repeat(initialize, 50);
jdphenix
  • 15,022
  • 3
  • 41
  • 74
  • Awesome, that did the trick. Thank you so much. Is there any other solutions? It makes the code a bit messy :-) I know maybe I am asking too much! – Jose Serodio Feb 10 '16 at 23:06
  • Well, this function is specialized to your code. There's nothing stopping you from creating a function `repeat()` that takes a function and number of times, and calls the function the given number of times. This is infact what lodash does: https://lodash.com/docs#times – jdphenix Feb 10 '16 at 23:11
  • Also, there's plenty of other folks with JavaScript chops out there that may very well have something more idiomatic or better - that checkmark often discourages more answers. If after a couple (few?) days this remains the best solution for you, then it may be appropriate then. – jdphenix Feb 10 '16 at 23:13
  • Great. I will check this library and again, thank you so much for your help. – Jose Serodio Feb 10 '16 at 23:16
  • Or you can just push *all* your code into a closure and immediately invoke the function, if you wanted. That's a little ugly, but does have the jQuery document ready feel to it, and isn't precisely anti-pattern. I've started wondering if I shouldn't do that by default for precisely the reason jdphenix suggests -- so you guarantee you don't pollute global scope. – ruffin Feb 11 '16 at 13:49
5

jslint is being overzealous (some would say), it expects all var statements to be at the top of a function.

You can tell jslint that you don't care about that rule by adding an instruction comment on the line above where you are declaring the variable.

// Llenamos el campo de 50 humanos/maquinas/extraterrestres = 150 jugadores
/*jslint for:true */
for (var i=1;i<=50;i+=1){

Or you can move all your var i; to the top of the file/function

Ruan Mendes
  • 90,375
  • 31
  • 153
  • 217
  • I put that code in the first line but didn't do anything. So I tried this other solution, I moved the for (var=i.... and declared var=i; at the top. But now it's saying: Unexpected 'for' at top level. for (i=1;i<=50;i+=1){ – Jose Serodio Feb 10 '16 at 23:02
  • 1
    @JoseSerodio Not in the first line, you add that comment right above the for loop – Ruan Mendes Feb 21 '17 at 12:49