Hello and welcome to our community! Is this your first visit?
Register
Enjoy an ad free experience by logging in. Not a member yet? Register.
Results 1 to 8 of 8
  1. #1
    New to the CF scene
    Join Date
    May 2012
    Posts
    8
    Thanks
    2
    Thanked 0 Times in 0 Posts

    Checking 2D array line lengths of equal content

    Hello,
    I'm sorry about the vague title, here's the full synopsis of the bug:

    This is for Connect4 program in Javascript that keeps track of the board in a 2D array: 'r' for red pieces, 'b' for blue/black pieces. I had originally written it in C++, and copy+pasted much of the base code here. The LineLength() function takes in the current location, color, and direction, and returns how many pieces there are extending in that direction of the same color, starting at and including the first one. For example:
    Code:
    [r][r][b]
    Run on the first [r] with direction to the right, it will return 2; run on any other direction, it will return 1. This worked just fine in C++, but apparently in Javascript, the function returns the correct amount for all directions except to the right. I've re-copied it over a few times from different source versions, and spell-checked as best as I could, but it still has the same problem.

    If anybody could show me what I'm doing wrong here (or a superior way to code Connect4) I'd be hugely grateful. The code for a function that calls all the directions statically, HasVictory(), and the LineLength() itself, is below, while the C++ source files, main and SuperBoard, and the JavaScript file engine are attached as .txt for reference.

    Thank you very much!

    Edit: By the way, location (0,0) is the upper left corner of the grid. That might be helpful ;) Also, most of the clumps of lines of code are just variations on each other.

    Code:
    function HasVictory(me) {
        var lol = "";
        // directions: 0 for up, 1 for left/up, 2 for left, 3 for left/down, etc.
        var leftdown = LineLength(me, placed, peaks[placed], 0, 5, 4) - 1;
        var rightup = LineLength(me, placed, peaks[placed], 0, 1, 4) - 1;
        var left = LineLength(me, placed, peaks[placed], 0, 6, 4) - 1;
        var right = LineLength(me, placed, peaks[placed], 0, 2, 4) - 1;
        var leftup = LineLength(me, placed, peaks[placed], 0, 7, 4) - 1;
        var rightdown = LineLength(me, placed, peaks[placed], 0, 3, 4) - 1;
        var down = LineLength(me, placed, peaks[placed], 0, 4, 4) - 1;
    
        lol += "rightup: " + rightup + "<br />";
        lol += "leftdown: " + leftdown + "<br />";
        lol += "right: " + right + "<br />";
        lol += "left: " + left + "<br />";
        lol += "rightdown: " + rightdown + "<br />";
        lol += "leftup: " + leftup + "<br />";
        lol += "down: " + down + "<br />";
    
        document.getElementById("extra").innerHTML = lol;
    
        if (down >= 3) return true;
        if (rightdown + leftup >= 3) return true;
        if (right + left >= 3) return true;
        if (rightup + leftdown >= 3) return true;
        return false;
    }
    
    // color, width location, height location, current length, direction, max length (4)
    function LineLength(me, w, h, length, dir, cap) {
        if (w < 0 || h < 0 || h > HEIGHT - 1 || w > WIDTH - 1)
            return length;
        if (board[h][w] != me || board[h][w] == '.')
            return length;
    
        ++length;
        if (length == cap)
            return length;
    
        if (dir == 0)
            return LineLength(me, w, h - 1, length, dir, cap);
        if (dir == 1)
            return LineLength(me, w + 1, h - 1, length, dir, cap);
        if (dir == 2)
            return LineLength(me, w + 1, h, length, dir, cap);
        if (dir == 3) 
            return LineLength(me, w + 1, h + 1, length, dir, cap);
        if (dir == 4)
            return LineLength(me, w, h + 1, length, dir, cap);
        if (dir == 5)
            return LineLength(me, w - 1, h + 1, length, dir, cap);
        if (dir == 6)
            return LineLength(me, w - 1, h, length, dir, cap);
        if (dir == 7)
            return LineLength(me, w - 1, h - 1, length, dir, cap);
    
        return -96; // This will never be reached in the actual game.
    }
    Attached Files Attached Files
    Last edited by Diogenes; 05-23-2012 at 12:36 AM.

  • #2
    Supreme Master coder! Old Pedant's Avatar
    Join Date
    Feb 2009
    Posts
    26,185
    Thanks
    80
    Thanked 4,453 Times in 4,418 Posts
    Can you show it live? So we don't have to duplicate your web page?
    An optimist sees the glass as half full.
    A pessimist sees the glass as half empty.
    A realist drinks it no matter how much there is.

  • #3
    New to the CF scene
    Join Date
    May 2012
    Posts
    8
    Thanks
    2
    Thanked 0 Times in 0 Posts
    Sure, sorry about that - here.

  • #4
    Supreme Master coder! Old Pedant's Avatar
    Join Date
    Feb 2009
    Posts
    26,185
    Thanks
    80
    Thanked 4,453 Times in 4,418 Posts
    Ahhh...just a little debugging reveals the problem!

    You are doing buttonPress('0')

    So you are passing a *STRING* to the function!

    Which in turn becomes the place argument which then becomes w.

    And when you do w = w + 1 you get (for example) "11"!!!

    REMOVE the apostrophes!

    buttonPress(0)

    ***********

    I hope you won't mind too much if I say it could all be written in a *lot* less code.
    An optimist sees the glass as half full.
    A pessimist sees the glass as half empty.
    A realist drinks it no matter how much there is.

  • Users who have thanked Old Pedant for this post:

    Diogenes (05-23-2012)

  • #5
    New to the CF scene
    Join Date
    May 2012
    Posts
    8
    Thanks
    2
    Thanked 0 Times in 0 Posts
    Quote Originally Posted by Old Pedant View Post
    Ahhh...just a little debugging reveals the problem!

    You are doing buttonPress('0')

    So you are passing a *STRING* to the function!

    Which in turn becomes the place argument which then becomes w.

    And when you do w = w + 1 you get (for example) "11"!!!

    REMOVE the apostrophes!

    buttonPress(0)

    ***********

    I hope you won't mind too much if I say it could all be written in a *lot* less code.

    Haha not at all, thank you very much for the help! If you'd be kind enough to give me some pointers, that'd be great - I normally don't do this type of coding in Javascript (or at all). I could probably use arrays for directional stuff and automate the table printing, but haven't done it yet for debugging purposes.
    Just wondering, why was this working for some directions and not others?
    Last edited by Diogenes; 05-23-2012 at 03:54 AM. Reason: Re-looked through the code

  • #6
    Supreme Master coder! Old Pedant's Avatar
    Join Date
    Feb 2009
    Posts
    26,185
    Thanks
    80
    Thanked 4,453 Times in 4,418 Posts
    It worked for any MINUS direction, because JS *will* convert a string to a number to do subtraction. But any PLUS direction it would blow up on. RIGHT UP wasen't working, either. You didn't test thoroughly enough. LEFT DOWN also didn't work.

    Here's a *POSSIBLE* set of changes for your code. UNTESTED. Just typed in with Notepad.
    Code:
    function HasVictory(me) {
        var lol = "";
        var leftdown = LineLength(me, "ld");
        var rightup = LineLength(me, "ru");
        var left = LineLength(me, "l");
        var right = LineLength(me, "r");
        var leftup = LineLength(me, "lu");
        var rightdown = LineLength(me, "rd");
        var down = LineLength(me, "d");
    
        lol += "rightup: " + rightup + "<br />";
        lol += "leftdown: " + leftdown + "<br />";
        lol += "right: " + right + "<br />";
        lol += "left: " + left + "<br />";
        lol += "rightdown: " + rightdown + "<br />";
        lol += "leftup: " + leftup + "<br />";
        lol += "down: " + down + "<br />";
    
        document.getElementById("extra").innerHTML = lol;
    
        return (    (down >= 4) || (rightdown + leftup >= 4) 
                 || (right + left >= 4) || (rightup + leftdown >= 3) );
    }
    
    function LineLength(me, dir) 
    {
        var w = placed;
        var h = peaks[placed];
        var dw = 0;
        var dh = 0;
        switch ( dir )
        {
            case "r": dw = +1; break;
            case "l": dw = -1; break;
            case "d": dh = -1; break;
            case "ru": dw = +1; dh = -1; break;
            case "rd": dw = +1; dh = +1; break;
            case "lu": dw = -1; dh = -1; break;
            case "ld": dw = -1; dh = +1; break;
        }
        var length = 1;
        while ( length <= 4 )
        {
            h += dh;
            w += dw;
            if ( w < 0 || h < 0 || h > HEIGHT - 1 || w > WIDTH - 1 ) return length;
            if ( board[h][w] != me || board[h][w] == '.') return length;
            ++length;
        }
        return 4;
    }
    An optimist sees the glass as half full.
    A pessimist sees the glass as half empty.
    A realist drinks it no matter how much there is.

  • Users who have thanked Old Pedant for this post:

    Diogenes (05-23-2012)

  • #7
    Supreme Master coder! Old Pedant's Avatar
    Join Date
    Feb 2009
    Posts
    26,185
    Thanks
    80
    Thanked 4,453 Times in 4,418 Posts
    You could pass dh and dw into LineLength instead of dir and save even more.
    An optimist sees the glass as half full.
    A pessimist sees the glass as half empty.
    A realist drinks it no matter how much there is.

  • #8
    New to the CF scene
    Join Date
    May 2012
    Posts
    8
    Thanks
    2
    Thanked 0 Times in 0 Posts
    Ha, that is way more elegant than what I had. I'll be sure to test WAY more thoroughly. Thanks again!


  •  

    Posting Permissions

    • You may not post new threads
    • You may not post replies
    • You may not post attachments
    • You may not edit your posts
    •