Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

algorithm connect four javascript

Hy, I am trying to implement an Connect Four Game in javascript / jQuery. First off this is no homework or any other duty. I'm just trying to push my abilities.

My "playground" is a simple html table which has 7 rows and 6 columns.
But now I have reached my ken. I'm stuck with the main functionality of checking whether there are 4 same td's around. I am adding a class to determine which color it should represent in the game. First I thought I could handle this with .nextAll() and .prevAll() but this does not work for me because there is no detection between.
Because I was searching for siblings, when adding a new Item and just looked up the length of siblings which were found and if they matched 4 in the end I supposed this was right, but no its not :D Is there maybe any kind of directNext() which provides all next with a css selector until something different comes up ?

I will put all of my code into this jsfiddle: http://jsfiddle.net/LcUVf/5/

Maybe somebody has ever tried the same or someone comes up with a good idea I'm not asking anybody to do or finish my code. I just want to get hints for implementing such an algorithm or examples how it could be solved !

Thanks in anyway !

like image 534
mas-designs Avatar asked Feb 17 '12 15:02

mas-designs


People also ask

Is there an algorithm for Connect 4?

The connect 4 playing program uses a minmax algorithm. Every time the computer decides what move to make next, it considers all of its possible moves: The computer then pretends that each of the moves it has considered has actually taken place.

How many possible combinations are there in Connect 4?

The number of possible Connect-Four game situations after n plies (n turns) is tabulated at OEISA212693. The total is 4531985219092.


1 Answers

I released a fully working version of the game on Github.

It implements an optimised variation on the algorythm Sirko mentioned.

To avoid any unnecessary redunancy, the algorythm directly checks the DOM rather than a JS table. As that algorythm requires a minimum amount of checks, the performance overhead for accessing the DOM is neglectable.

The current player and a flag for keeping track of whether the game has ended are basicly the only statuses stored in the JS itself.

I even used the DOM to store strings. It has no external dependencies and is supported by all versions of IE from IE6 upwards as well as modern browsers.

Code is optimised for filesize and performance. The latest version also includes animation, even though the total JS code of the game is still only 1.216 bytes after minification.


The Code :

Here's the full, un-minified JS code :

(function (doc, win, onclick, gid, classname, content, showMessage) {
    var
        a, b, c, colorLabel, cid, players, current, finished, newgameLabel, wonLabel, laststart = 1,
        cellAt = function (i, j) {
            return doc[gid](cid + i + j);
        },
        isCurrentColor = function (i, j) {
            return cellAt(i, j)[classname] === players[current];
        },
        start = function () {
            current = laststart = (laststart + 1) % 2;
            finished = 0;
            colorLabel[content] = colorLabel[classname] = players[current = (current + 1) % 2];
            for (a = 1; a < 7; a++)
                for (b = 1; b < 8; b++)
                    cellAt(a, b)[classname] = '';
        },
        makeMove = function (i, j, s) {
            s > 0 && (cellAt(s, j)[classname] = '');
            cellAt(s + 1, j)[classname] = players[current];
            s === i - 1 ? function (i, j) {
                return function (i, j) {
                    for (a = j - 1; 0 < a && isCurrentColor(i, a); a--) {
                    }
                    for (b = j + 1; 8 > b && isCurrentColor(i, b); b++) {
                    }
                    return 4 < b - a;
                }(i, j) || function (i, j) {
                    for (c = i + 1; 7 > c && isCurrentColor(c, j); c++) {
                    }
                    return 3 < c - i;
                }(i, j) || function (i, j) {
                    for (a = i - 1, b = j - 1; 0 < a && !(1 > b) && isCurrentColor(a, b); a--)
                        b--;
                    for (c = i + 1, b = j + 1; 7 > c && !(7 < b) && isCurrentColor(c, b); c++)
                        b++;
                    return 4 < c - a
                }(i, j) || function (i, j) {
                    for (a = i - 1, b = j + 1; 0 < a && !(7 < b) && isCurrentColor(a, b); a--)
                        b++;
                    for (c = i + 1, b = j - 1; 7 > c && !(1 > b) && isCurrentColor(c, b); c++)
                        b--;
                    return 4 < c - a;
                }(i, j);
            }(i, j)
                    ? finished = 1 && win[showMessage](doc[gid](wonLabel)[content].replace("%s", players[current].toLowerCase())) && start()
                    : colorLabel[content] = colorLabel[classname] = players[current = (current + 1) % 2]
                    : setTimeout(function () {
                        makeMove(i, j, s + 1)
                    }, 20);

        };

    return function (n, w, c, h, p1, p2) {
        cid = c;
        newgameLabel = n;
        wonLabel = w;
        colorLabel = doc[gid](c);
        players = [doc[gid](p1)[content], doc[gid](p2)[content]];
        for (a = 1; a < 7; a++)
            for (b = 1; b < 8; b++)
                cellAt(a, b)[onclick] = function (b, a) {
                    return function () {
                        if (!finished)
                            for (a = 6; a > 0; a--)
                                if (!cellAt(a, b)[classname]) {
                                    makeMove(a, b, 0);
                                    break;
                                }
                    };
                }(b);
        ;
        doc[gid](h)[onclick] = function () {
            win[showMessage](doc[gid](newgameLabel)[content]) && start()
        };
        start();
    };
})(document, window, "onclick", "getElementById", "className", "innerHTML", "confirm")("newgame", "won", "color", "restart", "p1", "p2");

A screenshot :

enter image description here

like image 56
John Slegers Avatar answered Oct 07 '22 07:10

John Slegers