Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Getting an infinite loop and can't see why - Javascript

I'm writing a simple little Connect 4 game and I'm running into an infinite loop on one of my functions:

var reds = 0;
var greens = 0;

function checkEmpty(div) {
    var empty = false;
    var clicked = $(div).attr('id');
    console.log(clicked);
    var idnum = parseInt(clicked.substr(6));
    while (idnum < 43) {
        idnum = idnum + 7;
    }
    console.log("idnum=" + idnum);
    while (empty == false) {
        for (var i = idnum; i > 0; i - 7) {
            idnumStr = idnum.toString();
            var checking = $('#square' + idnumStr);
            var str = checking.attr('class');
            empty = str.includes('empty');
            console.log(empty);
            var divToFill = checking;
        }
    }

    return divToFill;
}

function addDisc(div) {
    if (reds > greens) {
        $(div).addClass('green');
        greens++;
        console.log("greens=" + greens);
    } else {
        $(div).addClass('red');
        reds++;
        console.log("reds=" + reds);
    };
    $(div).removeClass('empty');
}

$(function() {
    var i = 1;
    //add a numbered id to every game square
    $('.game-square').each(function() {
        $(this).attr('id', 'square' + i);
        i++;
        //add an on click event handler to every game square

        //onclick functions
        $(this).on('click', function() {
            var divToFill = checkEmpty(this);
            addDisc(divToFill);
        })
    })
})

Here is a link to the codepen http://codepen.io/Gobias___/pen/xOwNOd

If you click on one of the circles and watch the browser's console, you'll see that it returns true over 3000 times. I can't figure out what I've done that makes it do that. I want the code to stop as soon as it returns empty = true. empty starts out false because I only want the code to run on divs that do not already have class .green or .red.

Where am I going wrong here?

like image 892
David Nugent Avatar asked Jun 15 '26 12:06

David Nugent


2 Answers

for (var i = idnum; i > 0; i - 7);

You do not change the i.

Do you want to decrement it by 7?

Change your for loop to the one shown below:

for (var i = idnum; i > 0; i -= 7) {
  // ...
}

You also do not use loop variable in the loop body. Instead, you use idnum, I think this can be issue.

while (empty == false) {
    for (var i = idnum; i > 0; i -= 7) {
        idnumStr = i.toString(); // changed to i
        var checking = $('#square' + idnumStr);
        var str = checking.attr('class');
        empty = str.includes('empty');
        console.log(empty);
        var divToFill = checking;
        // and don't forget to stop, when found empty
        if (empty) break;
    }
}

I add break if empty found, because if we go to next iteration we will override empty variable with smallest i related value.

You can also wrap empty assignment with if (!empty) {empty = ...;} to prevent this override, but I assume you can just break, because:

I want the code to stop as soon as it returns empty = true


Offtop hint:

while (idnum < 43) {
    idnum = idnum + 7;
}

can be easy replaced with: idnum = 42 + (idnum%7 || 7)

like image 135
vp_arth Avatar answered Jun 18 '26 00:06

vp_arth


Change to this:

for (var i = idnum; i > 0; i = i - 7) {

You are not decrementing the i in your for loop

like image 23
wot Avatar answered Jun 18 '26 01:06

wot



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!