最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Checking Surrounding Table Cells - Stack Overflow

programmeradmin0浏览0评论

I'm making the game called Dots and Boxes.

There are a bunch of dots on a grid:

<table>
    <tr>
        <td class="vLine" onclick="addLine(this)"></td>
        <td class="box" onclick="fillBox(this)"></td>
        <td class="vLine" onclick="addLine(this)"></td>
        <td class="box" onclick="fillBox(this)"></td>
        <td class="vLine" onclick="addLine(this)"></td>
        <td class="box" onclick="fillBox(this)"></td>
        <td class="vLine" onclick="addLine(this)"></td>
        <td class="box" onclick="fillBox(this)"></td>
        <td class="vLine" onclick="addLine(this)"></td>
        <td class="box" onclick="fillBox(this)"></td>
        <td class="vLine" onclick="addLine(this)"></td>
        <td class="box" onclick="fillBox(this)"></td>
        <td class="vLine" onclick="addLine(this)"></td>
    </tr>
    <tr>
        <td class="gap"></td>
        <td class="hLine" onclick="addLine(this)"></td>
        <td class="gap"></td>
        <td class="hLine" onclick="addLine(this)"></td>
        <td class="gap"></td>
        <td class="hLine" onclick="addLine(this)"></td>
        <td class="gap"></td>
        <td class="hLine" onclick="addLine(this)"></td>
        <td class="gap"></td>
        <td class="hLine" onclick="addLine(this)"></td>
        <td class="gap"></td>
        <td class="hLine" onclick="addLine(this)"></td>
        <td class="gap"></td>
    </tr>
</table>

When you click on one side of the box, it turns black:

function addLine(obj) {
            console.log("Called")

            if (obj.style.backgroundColor != "black") {
                obj.style.backgroundColor = "black";
                changeTurn()
            }

Once you click on the fourth side, closing the box, the box turns the color of the player who clicked the fourth side:

Currently, the players have to manually click the box to change its color. However, I would like it to automatically fill the box with the color when all four sides are black around the box.

How can I use a function in Javascript to check if a the line above, below, left, and right of a box is filled in black?

var playerTurn = "Blue";
            changeTurn();
            var number = 0;

            function addLine(obj) {
                console.log("Called")

                if (obj.style.backgroundColor != "black") {
                    obj.style.backgroundColor = "black";
                    changeTurn()
                }
            }
            
            function fillBox(obj) {
                if (playerTurn == "Blue") {
                    obj.style.backgroundColor = "red";
                }
                else if ( playerTurn == "Red") {
                    obj.style.backgroundColor = "blue";
                }
            }

            function changeTurn() {
                if (playerTurn == "Red") {
                    playerTurn = "Blue";
                    document.getElementById('turn').style.color = "blue";

                }
                else if (playerTurn == "Blue") {
                    playerTurn = "Red";
                    document.getElementById('turn').style.color = "red";
                };
                console.log(playerTurn);
                document.getElementById('turn').innerHTML = playerTurn + "'s Turn";
            }
h3 {
    font-family: Arial;
}
table {
    border-collapse: collapse;
}
.vLine {
    width: 10px;
    height: 60px;
}
.box {
    width: 60px;
    height: 60px;
}
.hLine {
    width: 60px;
    height: 10px;
}
.gap {
    width: 10px;
    height: 12px;
    background-color: black;
}
.vLine:hover, .hLine:hover {
    background-color: black;
}
<h3 id="turn"></h3>

<table>
    <tr>
        <td class="gap"></td>
        <td class="hLine" onclick="addLine(this)"></td>
        <td class="gap"></td>
        <td class="hLine" onclick="addLine(this)"></td>
        <td class="gap"></td>
        <td class="hLine" onclick="addLine(this)"></td>
        <td class="gap"></td>
        <td class="hLine" onclick="addLine(this)"></td>
        <td class="gap"></td>
        <td class="hLine" onclick="addLine(this)"></td>
        <td class="gap"></td>
        <td class="hLine" onclick="addLine(this)"></td>
        <td class="gap"></td>
    </tr>
    <tr>
        <td class="vLine" onclick="addLine(this)"></td>
        <td class="box" onclick="fillBox(this)"></td>
        <td class="vLine" onclick="addLine(this)"></td>
        <td class="box" onclick="fillBox(this)"></td>
        <td class="vLine" onclick="addLine(this)"></td>
        <td class="box" onclick="fillBox(this)"></td>
        <td class="vLine" onclick="addLine(this)"></td>
        <td class="box" onclick="fillBox(this)"></td>
        <td class="vLine" onclick="addLine(this)"></td>
        <td class="box" onclick="fillBox(this)"></td>
        <td class="vLine" onclick="addLine(this)"></td>
        <td class="box" onclick="fillBox(this)"></td>
        <td class="vLine" onclick="addLine(this)"></td>
    </tr>
    <tr>
        <td class="gap"></td>
        <td class="hLine" onclick="addLine(this)"></td>
        <td class="gap"></td>
        <td class="hLine" onclick="addLine(this)"></td>
        <td class="gap"></td>
        <td class="hLine" onclick="addLine(this)"></td>
        <td class="gap"></td>
        <td class="hLine" onclick="addLine(this)"></td>
        <td class="gap"></td>
        <td class="hLine" onclick="addLine(this)"></td>
        <td class="gap"></td>
        <td class="hLine" onclick="addLine(this)"></td>
        <td class="gap"></td>
    </tr>
    <tr>
        <td class="vLine" onclick="addLine(this)"></td>
        <td class="box" onclick="fillBox(this)"></td>
        <td class="vLine" onclick="addLine(this)"></td>
        <td class="box" onclick="fillBox(this)"></td>
        <td class="vLine" onclick="addLine(this)"></td>
        <td class="box" onclick="fillBox(this)"></td>
        <td class="vLine" onclick="addLine(this)"></td>
        <td class="box" onclick="fillBox(this)"></td>
        <td class="vLine" onclick="addLine(this)"></td>
        <td class="box" onclick="fillBox(this)"></td>
        <td class="vLine" onclick="addLine(this)"></td>
        <td class="box" onclick="fillBox(this)"></td>
        <td class="vLine" onclick="addLine(this)"></td>
    </tr>
    <tr>
        <td class="gap"></td>
        <td class="hLine" onclick="addLine(this)"></td>
        <td class="gap"></td>
        <td class="hLine" onclick="addLine(this)"></td>
        <td class="gap"></td>
        <td class="hLine" onclick="addLine(this)"></td>
        <td class="gap"></td>
        <td class="hLine" onclick="addLine(this)"></td>
        <td class="gap"></td>
        <td class="hLine" onclick="addLine(this)"></td>
        <td class="gap"></td>
        <td class="hLine" onclick="addLine(this)"></td>
        <td class="gap"></td>
    </tr>
    <tr>
        <td class="vLine" onclick="addLine(this)"></td>
        <td class="box" onclick="fillBox(this)"></td>
        <td class="vLine" onclick="addLine(this)"></td>
        <td class="box" onclick="fillBox(this)"></td>
        <td class="vLine" onclick="addLine(this)"></td>
        <td class="box" onclick="fillBox(this)"></td>
        <td class="vLine" onclick="addLine(this)"></td>
        <td class="box" onclick="fillBox(this)"></td>
        <td class="vLine" onclick="addLine(this)"></td>
        <td class="box" onclick="fillBox(this)"></td>
        <td class="vLine" onclick="addLine(this)"></td>
        <td class="box" onclick="fillBox(this)"></td>
        <td class="vLine" onclick="addLine(this)"></td>
    </tr>
    <tr>
        <td class="gap"></td>
        <td class="hLine" onclick="addLine(this)"></td>
        <td class="gap"></td>
        <td class="hLine" onclick="addLine(this)"></td>
        <td class="gap"></td>
        <td class="hLine" onclick="addLine(this)"></td>
        <td class="gap"></td>
        <td class="hLine" onclick="addLine(this)"></td>
        <td class="gap"></td>
        <td class="hLine" onclick="addLine(this)"></td>
        <td class="gap"></td>
        <td class="hLine" onclick="addLine(this)"></td>
        <td class="gap"></td>
    </tr>
    <tr>
        <td class="vLine" onclick="addLine(this)"></td>
        <td class="box" onclick="fillBox(this)"></td>
        <td class="vLine" onclick="addLine(this)"></td>
        <td class="box" onclick="fillBox(this)"></td>
        <td class="vLine" onclick="addLine(this)"></td>
        <td class="box" onclick="fillBox(this)"></td>
        <td class="vLine" onclick="addLine(this)"></td>
        <td class="box" onclick="fillBox(this)"></td>
        <td class="vLine" onclick="addLine(this)"></td>
        <td class="box" onclick="fillBox(this)"></td>
        <td class="vLine" onclick="addLine(this)"></td>
        <td class="box" onclick="fillBox(this)"></td>
        <td class="vLine" onclick="addLine(this)"></td>
    </tr>
    <tr>
        <td class="gap"></td>
        <td class="hLine" onclick="addLine(this)"></td>
        <td class="gap"></td>
        <td class="hLine" onclick="addLine(this)"></td>
        <td class="gap"></td>
        <td class="hLine" onclick="addLine(this)"></td>
        <td class="gap"></td>
        <td class="hLine" onclick="addLine(this)"></td>
        <td class="gap"></td>
        <td class="hLine" onclick="addLine(this)"></td>
        <td class="gap"></td>
        <td class="hLine" onclick="addLine(this)"></td>
        <td class="gap"></td>
    </tr>
    <tr>
        <td class="vLine" onclick="addLine(this)"></td>
        <td class="box" onclick="fillBox(this)"></td>
        <td class="vLine" onclick="addLine(this)"></td>
        <td class="box" onclick="fillBox(this)"></td>
        <td class="vLine" onclick="addLine(this)"></td>
        <td class="box" onclick="fillBox(this)"></td>
        <td class="vLine" onclick="addLine(this)"></td>
        <td class="box" onclick="fillBox(this)"></td>
        <td class="vLine" onclick="addLine(this)"></td>
        <td class="box" onclick="fillBox(this)"></td>
        <td class="vLine" onclick="addLine(this)"></td>
        <td class="box" onclick="fillBox(this)"></td>
        <td class="vLine" onclick="addLine(this)"></td>
    </tr>
    <tr>
        <td class="gap"></td>
        <td class="hLine" onclick="addLine(this)"></td>
        <td class="gap"></td>
        <td class="hLine" onclick="addLine(this)"></td>
        <td class="gap"></td>
        <td class="hLine" onclick="addLine(this)"></td>
        <td class="gap"></td>
        <td class="hLine" onclick="addLine(this)"></td>
        <td class="gap"></td>
        <td class="hLine" onclick="addLine(this)"></td>
        <td class="gap"></td>
        <td class="hLine" onclick="addLine(this)"></td>
        <td class="gap"></td>
    </tr>
    <tr>
        <td class="vLine" onclick="addLine(this)"></td>
        <td class="box" onclick="fillBox(this)"></td>
        <td class="vLine" onclick="addLine(this)"></td>
        <td class="box" onclick="fillBox(this)"></td>
        <td class="vLine" onclick="addLine(this)"></td>
        <td class="box" onclick="fillBox(this)"></td>
        <td class="vLine" onclick="addLine(this)"></td>
        <td class="box" onclick="fillBox(this)"></td>
        <td class="vLine" onclick="addLine(this)"></td>
        <td class="box" onclick="fillBox(this)"></td>
        <td class="vLine" onclick="addLine(this)"></td>
        <td class="box" onclick="fillBox(this)"></td>
        <td class="vLine" onclick="addLine(this)"></td>
    </tr>
    <tr>
        <td class="gap"></td>
        <td class="hLine" onclick="addLine(this)"></td>
        <td class="gap"></td>
        <td class="hLine" onclick="addLine(this)"></td>
        <td class="gap"></td>
        <td class="hLine" onclick="addLine(this)"></td>
        <td class="gap"></td>
        <td class="hLine" onclick="addLine(this)"></td>
        <td class="gap"></td>
        <td class="hLine" onclick="addLine(this)"></td>
        <td class="gap"></td>
        <td class="hLine" onclick="addLine(this)"></td>
        <td class="gap"></td>
    </tr>
</table>

I'm making the game called Dots and Boxes.

There are a bunch of dots on a grid:

<table>
    <tr>
        <td class="vLine" onclick="addLine(this)"></td>
        <td class="box" onclick="fillBox(this)"></td>
        <td class="vLine" onclick="addLine(this)"></td>
        <td class="box" onclick="fillBox(this)"></td>
        <td class="vLine" onclick="addLine(this)"></td>
        <td class="box" onclick="fillBox(this)"></td>
        <td class="vLine" onclick="addLine(this)"></td>
        <td class="box" onclick="fillBox(this)"></td>
        <td class="vLine" onclick="addLine(this)"></td>
        <td class="box" onclick="fillBox(this)"></td>
        <td class="vLine" onclick="addLine(this)"></td>
        <td class="box" onclick="fillBox(this)"></td>
        <td class="vLine" onclick="addLine(this)"></td>
    </tr>
    <tr>
        <td class="gap"></td>
        <td class="hLine" onclick="addLine(this)"></td>
        <td class="gap"></td>
        <td class="hLine" onclick="addLine(this)"></td>
        <td class="gap"></td>
        <td class="hLine" onclick="addLine(this)"></td>
        <td class="gap"></td>
        <td class="hLine" onclick="addLine(this)"></td>
        <td class="gap"></td>
        <td class="hLine" onclick="addLine(this)"></td>
        <td class="gap"></td>
        <td class="hLine" onclick="addLine(this)"></td>
        <td class="gap"></td>
    </tr>
</table>

When you click on one side of the box, it turns black:

function addLine(obj) {
            console.log("Called")

            if (obj.style.backgroundColor != "black") {
                obj.style.backgroundColor = "black";
                changeTurn()
            }

Once you click on the fourth side, closing the box, the box turns the color of the player who clicked the fourth side:

Currently, the players have to manually click the box to change its color. However, I would like it to automatically fill the box with the color when all four sides are black around the box.

How can I use a function in Javascript to check if a the line above, below, left, and right of a box is filled in black?

var playerTurn = "Blue";
            changeTurn();
            var number = 0;

            function addLine(obj) {
                console.log("Called")

                if (obj.style.backgroundColor != "black") {
                    obj.style.backgroundColor = "black";
                    changeTurn()
                }
            }
            
            function fillBox(obj) {
                if (playerTurn == "Blue") {
                    obj.style.backgroundColor = "red";
                }
                else if ( playerTurn == "Red") {
                    obj.style.backgroundColor = "blue";
                }
            }

            function changeTurn() {
                if (playerTurn == "Red") {
                    playerTurn = "Blue";
                    document.getElementById('turn').style.color = "blue";

                }
                else if (playerTurn == "Blue") {
                    playerTurn = "Red";
                    document.getElementById('turn').style.color = "red";
                };
                console.log(playerTurn);
                document.getElementById('turn').innerHTML = playerTurn + "'s Turn";
            }
h3 {
    font-family: Arial;
}
table {
    border-collapse: collapse;
}
.vLine {
    width: 10px;
    height: 60px;
}
.box {
    width: 60px;
    height: 60px;
}
.hLine {
    width: 60px;
    height: 10px;
}
.gap {
    width: 10px;
    height: 12px;
    background-color: black;
}
.vLine:hover, .hLine:hover {
    background-color: black;
}
<h3 id="turn"></h3>

<table>
    <tr>
        <td class="gap"></td>
        <td class="hLine" onclick="addLine(this)"></td>
        <td class="gap"></td>
        <td class="hLine" onclick="addLine(this)"></td>
        <td class="gap"></td>
        <td class="hLine" onclick="addLine(this)"></td>
        <td class="gap"></td>
        <td class="hLine" onclick="addLine(this)"></td>
        <td class="gap"></td>
        <td class="hLine" onclick="addLine(this)"></td>
        <td class="gap"></td>
        <td class="hLine" onclick="addLine(this)"></td>
        <td class="gap"></td>
    </tr>
    <tr>
        <td class="vLine" onclick="addLine(this)"></td>
        <td class="box" onclick="fillBox(this)"></td>
        <td class="vLine" onclick="addLine(this)"></td>
        <td class="box" onclick="fillBox(this)"></td>
        <td class="vLine" onclick="addLine(this)"></td>
        <td class="box" onclick="fillBox(this)"></td>
        <td class="vLine" onclick="addLine(this)"></td>
        <td class="box" onclick="fillBox(this)"></td>
        <td class="vLine" onclick="addLine(this)"></td>
        <td class="box" onclick="fillBox(this)"></td>
        <td class="vLine" onclick="addLine(this)"></td>
        <td class="box" onclick="fillBox(this)"></td>
        <td class="vLine" onclick="addLine(this)"></td>
    </tr>
    <tr>
        <td class="gap"></td>
        <td class="hLine" onclick="addLine(this)"></td>
        <td class="gap"></td>
        <td class="hLine" onclick="addLine(this)"></td>
        <td class="gap"></td>
        <td class="hLine" onclick="addLine(this)"></td>
        <td class="gap"></td>
        <td class="hLine" onclick="addLine(this)"></td>
        <td class="gap"></td>
        <td class="hLine" onclick="addLine(this)"></td>
        <td class="gap"></td>
        <td class="hLine" onclick="addLine(this)"></td>
        <td class="gap"></td>
    </tr>
    <tr>
        <td class="vLine" onclick="addLine(this)"></td>
        <td class="box" onclick="fillBox(this)"></td>
        <td class="vLine" onclick="addLine(this)"></td>
        <td class="box" onclick="fillBox(this)"></td>
        <td class="vLine" onclick="addLine(this)"></td>
        <td class="box" onclick="fillBox(this)"></td>
        <td class="vLine" onclick="addLine(this)"></td>
        <td class="box" onclick="fillBox(this)"></td>
        <td class="vLine" onclick="addLine(this)"></td>
        <td class="box" onclick="fillBox(this)"></td>
        <td class="vLine" onclick="addLine(this)"></td>
        <td class="box" onclick="fillBox(this)"></td>
        <td class="vLine" onclick="addLine(this)"></td>
    </tr>
    <tr>
        <td class="gap"></td>
        <td class="hLine" onclick="addLine(this)"></td>
        <td class="gap"></td>
        <td class="hLine" onclick="addLine(this)"></td>
        <td class="gap"></td>
        <td class="hLine" onclick="addLine(this)"></td>
        <td class="gap"></td>
        <td class="hLine" onclick="addLine(this)"></td>
        <td class="gap"></td>
        <td class="hLine" onclick="addLine(this)"></td>
        <td class="gap"></td>
        <td class="hLine" onclick="addLine(this)"></td>
        <td class="gap"></td>
    </tr>
    <tr>
        <td class="vLine" onclick="addLine(this)"></td>
        <td class="box" onclick="fillBox(this)"></td>
        <td class="vLine" onclick="addLine(this)"></td>
        <td class="box" onclick="fillBox(this)"></td>
        <td class="vLine" onclick="addLine(this)"></td>
        <td class="box" onclick="fillBox(this)"></td>
        <td class="vLine" onclick="addLine(this)"></td>
        <td class="box" onclick="fillBox(this)"></td>
        <td class="vLine" onclick="addLine(this)"></td>
        <td class="box" onclick="fillBox(this)"></td>
        <td class="vLine" onclick="addLine(this)"></td>
        <td class="box" onclick="fillBox(this)"></td>
        <td class="vLine" onclick="addLine(this)"></td>
    </tr>
    <tr>
        <td class="gap"></td>
        <td class="hLine" onclick="addLine(this)"></td>
        <td class="gap"></td>
        <td class="hLine" onclick="addLine(this)"></td>
        <td class="gap"></td>
        <td class="hLine" onclick="addLine(this)"></td>
        <td class="gap"></td>
        <td class="hLine" onclick="addLine(this)"></td>
        <td class="gap"></td>
        <td class="hLine" onclick="addLine(this)"></td>
        <td class="gap"></td>
        <td class="hLine" onclick="addLine(this)"></td>
        <td class="gap"></td>
    </tr>
    <tr>
        <td class="vLine" onclick="addLine(this)"></td>
        <td class="box" onclick="fillBox(this)"></td>
        <td class="vLine" onclick="addLine(this)"></td>
        <td class="box" onclick="fillBox(this)"></td>
        <td class="vLine" onclick="addLine(this)"></td>
        <td class="box" onclick="fillBox(this)"></td>
        <td class="vLine" onclick="addLine(this)"></td>
        <td class="box" onclick="fillBox(this)"></td>
        <td class="vLine" onclick="addLine(this)"></td>
        <td class="box" onclick="fillBox(this)"></td>
        <td class="vLine" onclick="addLine(this)"></td>
        <td class="box" onclick="fillBox(this)"></td>
        <td class="vLine" onclick="addLine(this)"></td>
    </tr>
    <tr>
        <td class="gap"></td>
        <td class="hLine" onclick="addLine(this)"></td>
        <td class="gap"></td>
        <td class="hLine" onclick="addLine(this)"></td>
        <td class="gap"></td>
        <td class="hLine" onclick="addLine(this)"></td>
        <td class="gap"></td>
        <td class="hLine" onclick="addLine(this)"></td>
        <td class="gap"></td>
        <td class="hLine" onclick="addLine(this)"></td>
        <td class="gap"></td>
        <td class="hLine" onclick="addLine(this)"></td>
        <td class="gap"></td>
    </tr>
    <tr>
        <td class="vLine" onclick="addLine(this)"></td>
        <td class="box" onclick="fillBox(this)"></td>
        <td class="vLine" onclick="addLine(this)"></td>
        <td class="box" onclick="fillBox(this)"></td>
        <td class="vLine" onclick="addLine(this)"></td>
        <td class="box" onclick="fillBox(this)"></td>
        <td class="vLine" onclick="addLine(this)"></td>
        <td class="box" onclick="fillBox(this)"></td>
        <td class="vLine" onclick="addLine(this)"></td>
        <td class="box" onclick="fillBox(this)"></td>
        <td class="vLine" onclick="addLine(this)"></td>
        <td class="box" onclick="fillBox(this)"></td>
        <td class="vLine" onclick="addLine(this)"></td>
    </tr>
    <tr>
        <td class="gap"></td>
        <td class="hLine" onclick="addLine(this)"></td>
        <td class="gap"></td>
        <td class="hLine" onclick="addLine(this)"></td>
        <td class="gap"></td>
        <td class="hLine" onclick="addLine(this)"></td>
        <td class="gap"></td>
        <td class="hLine" onclick="addLine(this)"></td>
        <td class="gap"></td>
        <td class="hLine" onclick="addLine(this)"></td>
        <td class="gap"></td>
        <td class="hLine" onclick="addLine(this)"></td>
        <td class="gap"></td>
    </tr>
    <tr>
        <td class="vLine" onclick="addLine(this)"></td>
        <td class="box" onclick="fillBox(this)"></td>
        <td class="vLine" onclick="addLine(this)"></td>
        <td class="box" onclick="fillBox(this)"></td>
        <td class="vLine" onclick="addLine(this)"></td>
        <td class="box" onclick="fillBox(this)"></td>
        <td class="vLine" onclick="addLine(this)"></td>
        <td class="box" onclick="fillBox(this)"></td>
        <td class="vLine" onclick="addLine(this)"></td>
        <td class="box" onclick="fillBox(this)"></td>
        <td class="vLine" onclick="addLine(this)"></td>
        <td class="box" onclick="fillBox(this)"></td>
        <td class="vLine" onclick="addLine(this)"></td>
    </tr>
    <tr>
        <td class="gap"></td>
        <td class="hLine" onclick="addLine(this)"></td>
        <td class="gap"></td>
        <td class="hLine" onclick="addLine(this)"></td>
        <td class="gap"></td>
        <td class="hLine" onclick="addLine(this)"></td>
        <td class="gap"></td>
        <td class="hLine" onclick="addLine(this)"></td>
        <td class="gap"></td>
        <td class="hLine" onclick="addLine(this)"></td>
        <td class="gap"></td>
        <td class="hLine" onclick="addLine(this)"></td>
        <td class="gap"></td>
    </tr>
</table>

Share Improve this question edited Nov 4, 2022 at 18:23 isherwood 61.2k16 gold badges122 silver badges170 bronze badges asked Jul 1, 2015 at 1:26 JoshKJoshK 4251 gold badge4 silver badges18 bronze badges 1
  • 3 No answer for you, yet, but you should really separate your logic from your markup - inline event handlers are poor form, and that many is a nightmare. You should associate the behaviour with the class, and refer to the element inside the handler. Take a look at this. – Oka Commented Jul 1, 2015 at 1:59
Add a ment  | 

4 Answers 4

Reset to default 3

This is fairly simple, though it requires some good use of DOM traversal.

When you click on a line there are only ever, at most, two possible boxes that could be filled in. For horizontal lines, those are the boxes above and below, which requires jumping rows. For vertical lines, left and right.

For each of these boxes, there are four lines we need to confirm. Again, we have to jump rows for the lines above and below.

I've actually recreated the game, for the most part, because it's a fun one and there's a lot to be learned here. So let's go through the important bits. We'll avoid bad form in this code, like inline handlers and setting styles directly on elements, and we'll let CSS classes act as controls, though a more plete option would be data-attributes.

Let's start with two essential helper functions.

The first is used to turn array-like objects into actually arrays, so we can use Array.prototype methods on them. We chiefly use this on nodeList objects.

function toArray (o) {
  return Array.prototype.slice.call(o);
}

The second utilizes the first, and gives us the position of an element in its parentNode.

function nodeIndex (node) {
  return toArray(node.parentNode.children).indexOf(node);
}

Next, our event handlers. They're fairly similar to each other. When we click on a line, we fill in that line with another helper function, fill, which adds a new class to the line called .filled. We then check the boxes that could be filled. For horizontal lines that's the vertical boxes, above and below; for vertical lines that's the horizontal boxes, left and right. We remove the event listener so lines can only be clicked once.

function addHLine (e) {
  fill(this);
  this.removeEventListener(e.type, addHLine);
  checkVerticalBoxes(this);
  updateGame();
}

function addVLine (e) {
  fill(this);
  this.removeEventListener(e.type, addVLine);
  checkHorizontalBoxes(this);
  updateGame();
}

Now let's look at checkHorizontalBoxes and checkVerticalBoxes. The horizontal boxes are in the same row, indexed +/-1 from our starting line. The vertical boxes are in rows indexed +/-1 from our starting row, and share the same index as the line. We have some if statements, because sometimes a possible row or box will be out-of-bounds.

function checkHorizontalBoxes (line) {
  var left = line.previousElementSibling,
      right = line.nextElementSibling;

  if (left) checkSurroundingLines(left);
  if (right) checkSurroundingLines(right);
}

function checkVerticalBoxes (line) {
  var index = nodeIndex(line),
      up = line.parentNode.previousElementSibling,
      down = line.parentNode.nextElementSibling;

  if (up) checkSurroundingLines(up.children[index]);
  if (down) checkSurroundingLines(down.children[index]);
}

Both those functions call checkSurroundingLines on the potential boxes. This function calls two more functions - checkVerticalLines and checkHorizontalLines. Starting to see the pattern? isFilled is similar to fill, it's a helper function we defined to test if a line has the class .filled.

function checkHorizontalLines (node, idx) {
  var left = node.previousElementSibling,
      right = node.nextElementSibling;

  return isFilled(left) && isFilled(right);
}

function checkVerticalLines (node, idx) {
  var row = node.parentNode,
      up = row.previousElementSibling.children[idx],
      down = row.nextElementSibling.children[idx];

  return isFilled(up) && isFilled(down);
}

If both those return true we fill in our box.


That's a basic run down of the logic for this kind of DOM traversal. There's some extra stuff going on with the actual code, so read all the parts.

Here's the working game:

DEMO

// Player objects

function Player (name, className, scoreBox) {
  this.name = name;
  this.className = className;
  this.scoreBox = scoreBox;
  this.score = 0;
}

// State

var players = [new Player('Blue', 'blue-mark', 'p1'),
            new Player('Red', 'red-mark', 'p2')],
    currentPlayerIdx = 0,
    currentPlayer = players[currentPlayerIdx],
    turnBox = document.getElementById('turn');

// Helpers

function toArray (o) {
  return Array.prototype.slice.call(o);
}

function nodeIndex (node) {
  return toArray(node.parentNode.children).indexOf(node);
}

function fill (el) {
  el.classList.add('filled');
}

function isFilled (el) {
  return el.classList.contains('filled');
}

// Checks

function checkHorizontalLines (node, idx) {
  var left = node.previousElementSibling,
      right = node.nextElementSibling;
  
  return isFilled(left) && isFilled(right);
}

function checkVerticalLines (node, idx) {
  var row = node.parentNode,
      up = row.previousElementSibling.children[idx],
      down = row.nextElementSibling.children[idx];
      
  return isFilled(up) && isFilled(down);
}

function checkSurroundingLines (node) {
  var idx = nodeIndex(node),
      surrounded = checkVerticalLines (node, idx) && checkHorizontalLines(node, idx);
  
  if (surrounded) {
    node.classList.add('marked');
    node.classList.add(currentPlayer.className);
    return true;
  } 
}

function checkHorizontalBoxes (line) {
  var left = line.previousElementSibling,
      right = line.nextElementSibling;
  
  if (left) checkSurroundingLines(left);
  if (right) checkSurroundingLines(right);
}

function checkVerticalBoxes (line) {
  var index = nodeIndex(line),
      up = line.parentNode.previousElementSibling,
      down = line.parentNode.nextElementSibling;
  
  if (up) checkSurroundingLines(up.children[index]);
  if (down) checkSurroundingLines(down.children[index]);
}


// State sets

function setInfo () {
  turnBox.className = currentPlayer.className;
  turnBox.innerHTML = currentPlayer.name + "'s Turn";
  
  players.forEach(function (p) {
    document.getElementById(p.scoreBox).innerHTML = p.score;
  });
}

function getScores() {
  players.forEach(function (p) {
    p.score = document.querySelectorAll('.box.marked.'+p.className).length;
  });
}

function changeTurn () {
  currentPlayerIdx = 1 - currentPlayerIdx;
  currentPlayer = players[currentPlayerIdx];
  
  setInfo();
}

function updateGame() {
  getScores();
  changeTurn();
}

// Events

function addHLine (e) {
  fill(this);
  this.removeEventListener(e.type, addHLine);
  checkVerticalBoxes(this);
  updateGame();
}

function addVLine (e) {
  fill(this);
  this.removeEventListener(e.type, addVLine);
  checkHorizontalBoxes(this);
  updateGame();
}

function assignHandler (sel, ev, fn) {
  var els = document.querySelectorAll(sel);
  toArray(els).forEach(function (el) {
    el.addEventListener(ev, fn);
  });
}

assignHandler('.hLine', 'click', addHLine);
assignHandler('.vLine', 'click', addVLine);


setInfo();
h3 {
  font-family: Arial;
}
table {
  border-collapse: collapse;
}
.vLine {
  width: 10px;
  height: 60px;
}
.box {
  width: 60px;
  height: 60px;
}
.hLine {
  width: 60px;
  height: 10px;
}
.gap {
  width: 10px;
  height: 12px;
  background-color: #333;
}
.vLine:not(.filled):hover,
.hLine:not(.filled):hover {
  background-color: #333;
}

.filled {
  background-color: grey;
}

.marked {
  background-color: green;
}

.box.blue-mark {
  background-color: #3355ff;
}

.box.red-mark {
  background-color: #ff5533;
}

#turn.blue-mark,
#p1 {
  color: #3355ff;
}

#turn.red-mark,
#p2 {
  color: #ff5533;
}
<h3 id="turn"></h3>
<p class="counts">
  <span id="p1"></span> -
  <span id="p2"></span>
</p>

<table>
  <tr>
    <td class="gap"></td>
    <td class="hLine"></td>
    <td class="gap"></td>
    <td class="hLine"></td>
    <td class="gap"></td>
    <td class="hLine"></td>
    <td class="gap"></td>
    <td class="hLine"></td>
    <td class="gap"></td>
    <td class="hLine"></td>
    <td class="gap"></td>
    <td class="hLine"></td>
    <td class="gap"></td>
  </tr>
  <tr>
    <td class="vLine"></td>
    <td class="box"></td>
    <td class="vLine"></td>
    <td class="box"></td>
    <td class="vLine"></td>
    <td class="box"></td>
    <td class="vLine"></td>
    <td class="box"></td>
    <td class="vLine"></td>
    <td class="box"></td>
    <td class="vLine"></td>
    <td class="box"></td>
    <td class="vLine"></td>
  </tr>
  <tr>
    <td class="gap"></td>
    <td class="hLine"></td>
    <td class="gap"></td>
    <td class="hLine"></td>
    <td class="gap"></td>
    <td class="hLine"></td>
    <td class="gap"></td>
    <td class="hLine"></td>
    <td class="gap"></td>
    <td class="hLine"></td>
    <td class="gap"></td>
    <td class="hLine"></td>
    <td class="gap"></td>
  </tr>
  <tr>
    <td class="vLine"></td>
    <td class="box"></td>
    <td class="vLine"></td>
    <td class="box"></td>
    <td class="vLine"></td>
    <td class="box"></td>
    <td class="vLine"></td>
    <td class="box"></td>
    <td class="vLine"></td>
    <td class="box"></td>
    <td class="vLine"></td>
    <td class="box"></td>
    <td class="vLine"></td>
  </tr>
  <tr>
    <td class="gap"></td>
    <td class="hLine"></td>
    <td class="gap"></td>
    <td class="hLine"></td>
    <td class="gap"></td>
    <td class="hLine"></td>
    <td class="gap"></td>
    <td class="hLine"></td>
    <td class="gap"></td>
    <td class="hLine"></td>
    <td class="gap"></td>
    <td class="hLine"></td>
    <td class="gap"></td>
  </tr>
  <tr>
    <td class="vLine"></td>
    <td class="box"></td>
    <td class="vLine"></td>
    <td class="box"></td>
    <td class="vLine"></td>
    <td class="box"></td>
    <td class="vLine"></td>
    <td class="box"></td>
    <td class="vLine"></td>
    <td class="box"></td>
    <td class="vLine"></td>
    <td class="box"></td>
    <td class="vLine"></td>
  </tr>
  <tr>
    <td class="gap"></td>
    <td class="hLine"></td>
    <td class="gap"></td>
    <td class="hLine"></td>
    <td class="gap"></td>
    <td class="hLine"></td>
    <td class="gap"></td>
    <td class="hLine"></td>
    <td class="gap"></td>
    <td class="hLine"></td>
    <td class="gap"></td>
    <td class="hLine"></td>
    <td class="gap"></td>
  </tr>
  <tr>
    <td class="vLine"></td>
    <td class="box"></td>
    <td class="vLine"></td>
    <td class="box"></td>
    <td class="vLine"></td>
    <td class="box"></td>
    <td class="vLine"></td>
    <td class="box"></td>
    <td class="vLine"></td>
    <td class="box"></td>
    <td class="vLine"></td>
    <td class="box"></td>
    <td class="vLine"></td>
  </tr>
  <tr>
    <td class="gap"></td>
    <td class="hLine"></td>
    <td class="gap"></td>
    <td class="hLine"></td>
    <td class="gap"></td>
    <td class="hLine"></td>
    <td class="gap"></td>
    <td class="hLine"></td>
    <td class="gap"></td>
    <td class="hLine"></td>
    <td class="gap"></td>
    <td class="hLine"></td>
    <td class="gap"></td>
  </tr>
  <tr>
    <td class="vLine"></td>
    <td class="box"></td>
    <td class="vLine"></td>
    <td class="box"></td>
    <td class="vLine"></td>
    <td class="box"></td>
    <td class="vLine"></td>
    <td class="box"></td>
    <td class="vLine"></td>
    <td class="box"></td>
    <td class="vLine"></td>
    <td class="box"></td>
    <td class="vLine"></td>
  </tr>
  <tr>
    <td class="gap"></td>
    <td class="hLine"></td>
    <td class="gap"></td>
    <td class="hLine"></td>
    <td class="gap"></td>
    <td class="hLine"></td>
    <td class="gap"></td>
    <td class="hLine"></td>
    <td class="gap"></td>
    <td class="hLine"></td>
    <td class="gap"></td>
    <td class="hLine"></td>
    <td class="gap"></td>
  </tr>
  <tr>
    <td class="vLine"></td>
    <td class="box"></td>
    <td class="vLine"></td>
    <td class="box"></td>
    <td class="vLine"></td>
    <td class="box"></td>
    <td class="vLine"></td>
    <td class="box"></td>
    <td class="vLine"></td>
    <td class="box"></td>
    <td class="vLine"></td>
    <td class="box"></td>
    <td class="vLine"></td>
  </tr>
  <tr>
    <td class="gap"></td>
    <td class="hLine"></td>
    <td class="gap"></td>
    <td class="hLine"></td>
    <td class="gap"></td>
    <td class="hLine"></td>
    <td class="gap"></td>
    <td class="hLine"></td>
    <td class="gap"></td>
    <td class="hLine"></td>
    <td class="gap"></td>
    <td class="hLine"></td>
    <td class="gap"></td>
  </tr>
</table>

You can use previousElementSibling and nextElementSibling for next and previous elements, and bined with the approach proposed here: Is it possible to get element's numerical index in its parent node without looping?, you can get above and below. Like this:

    var indexPos = Array.prototype.indexOf.call(obj.parentNode.children, obj);
    above = obj.parentNode.previousElementSibling.children[indexPos];
    below = obj.parentNode.nextElementSibling.children[indexPos]
    next = obj.nextElementSibling;
    previous = obj.previousElementSibling;

You can see here, click on a element to turn surrounding elements green.

https://jsfiddle/bvc0ta55/

It's not handling error such as if there are missings surrondings, but since your square elements are all surrounded, you shouldn't be faced with the problem.

In general, you should try to separate game logic from DOM, and handle everything in your game objects (arrays, etc.). In your case, however, for example, you can use data attributes to assign specific values to each element of interest, create arrays of elements, and then use those data attributes later to check if box is surrounded or not. This was a fun to solve, so I have modified your code by adding a few things (creating arrays and assigning data attributes, and horizontal/vertical check). Jsfiddle: https://jsfiddle/pisamce/1ws3oyfe/

And I have modified your addLine function to call check functions:

//check if box is surrounded
var row = +obj.dataset.row;
var col = +obj.dataset.col;
var type = obj.dataset.type;
if(type === 'h'){
    checkHorizontal(row, col);
}
else if(type === 'v'){
    checkVertical(row, col);
}

var bgcolor = 'black';
var hlines = document.getElementsByClassName('hLine');
for(var i=0;i<7;i++){
    for(var j=0;j<6;j++){
        hlines[j+i*6].setAttribute('data-row', i);
        hlines[j+i*6].setAttribute('data-col', j);
        hlines[j+i*6].setAttribute('data-type', 'h');
    }
}
var vlines = document.getElementsByClassName('vLine');
for(var i=0;i<6;i++){
    for(var j=0;j<7;j++){
        vlines[j+i*7].setAttribute('data-row', i);
        vlines[j+i*7].setAttribute('data-col', j);
        vlines[j+i*7].setAttribute('data-type', 'v');
    }
}
var boxes = document.getElementsByClassName('box');
for(var i=0;i<6;i++){
    for(var j=0;j<6;j++){
        boxes[j+i*6].setAttribute('data-row', i);
        boxes[j+i*6].setAttribute('data-col', j);
        boxes[j+i*6].setAttribute('data-type', 'b');
    }
}
function checkHorizontal(row, col){
    //check up
    if(row > 0
       && hlines[(row-1)*6+col].style.backgroundColor === bgcolor
       && hlines[row*6+col].style.backgroundColor === bgcolor
       && vlines[(row-1)*7+col].style.backgroundColor === bgcolor
       && vlines[(row-1)*7+col+1].style.backgroundColor === bgcolor){
           fillBox(boxes[(row-1)*6+col]);
    }
    //check down
    if(row < 6
       && hlines[(row+1)*6+col].style.backgroundColor === bgcolor
       && hlines[row*6+col].style.backgroundColor === bgcolor
       && vlines[row*7+col].style.backgroundColor === bgcolor
       && vlines[row*7+col+1].style.backgroundColor === bgcolor){
           fillBox(boxes[row*6+col]);
    }
}
function checkVertical(row, col){
    //check left
    if(col > 0
       && hlines[row*6+col-1].style.backgroundColor === bgcolor
       && hlines[(row+1)*6+col-1].style.backgroundColor === bgcolor
       && vlines[row*7+col].style.backgroundColor === bgcolor
       && vlines[row*7+col-1].style.backgroundColor === bgcolor){
           fillBox(boxes[row*6+col-1]);
    }
    //check right
    if(col < 5
       && hlines[row*6+col].style.backgroundColor === bgcolor
       && hlines[(row+1)*6+col].style.backgroundColor === bgcolor
       && vlines[row*7+col+1].style.backgroundColor === bgcolor
       && vlines[row*7+col].style.backgroundColor === bgcolor){
           fillBox(boxes[row*6+col]);
    }
}


var playerTurn = "Blue";
            changeTurn();
            var number = 0;

            function addLine(obj) {
                console.log("Called")
                
                if (obj.style.backgroundColor != "black") {
                    obj.style.backgroundColor = "black";
                    changeTurn()
                }
                
                //check if box is surrounded
                var row = +obj.dataset.row;
                var col = +obj.dataset.col;
                var type = obj.dataset.type;
                if(type === 'h'){
                    checkHorizontal(row, col);
                }
                else if(type === 'v'){
                    checkVertical(row, col);
                }
            }
            
            function fillBox(obj) {
                if (playerTurn == "Blue") {
                    obj.style.backgroundColor = "red";
                }
                else if ( playerTurn == "Red") {
                    obj.style.backgroundColor = "blue";
                }
            }

            function changeTurn() {
                if (playerTurn == "Red") {
                    playerTurn = "Blue";
                    document.getElementById('turn').style.color = "blue";

                }
                else if (playerTurn == "Blue") {
                    playerTurn = "Red";
                    document.getElementById('turn').style.color = "red";
                };
                console.log(playerTurn);
                document.getElementById('turn').innerHTML = playerTurn + "'s Turn";
            }
h3 {
    font-family: Arial;
}
table {
    border-collapse: collapse;
}
.vLine {
    width: 10px;
    height: 60px;
}
.box {
    width: 60px;
    height: 60px;
}
.hLine {
    width: 60px;
    height: 10px;
}
.gap {
    width: 10px;
    height: 12px;
    background-color: black;
}
.vLine:hover, .hLine:hover {
    background-color: black;
}
<h3 id="turn"></h3>

<table>
    <tr>
        <td class="gap"></td>
        <td class="hLine" onclick="addLine(this)"></td>
        <td class="gap"></td>
        <td class="hLine" onclick="addLine(this)"></td>
        <td class="gap"></td>
        <td class="hLine" onclick="addLine(this)"></td>
        <td class="gap"></td>
        <td class="hLine" onclick="addLine(this)"></td>
        <td class="gap"></td>
        <td class="hLine" onclick="addLine(this)"></td>
        <td class="gap"></td>
        <td class="hLine" onclick="addLine(this)"></td>
        <td class="gap"></td>
    </tr>
    <tr>
        <td class="vLine" onclick="addLine(this)"></td>
        <td class="box" onclick="fillBox(this)"></td>
        <td class="vLine" onclick="addLine(this)"></td>
        <td class="box" onclick="fillBox(this)"></td>
        <td class="vLine" onclick="addLine(this)"></td>
        <td class="box" onclick="fillBox(this)"></td>
        <td class="vLine" onclick="addLine(this)"></td>
        <td class="box" onclick="fillBox(this)"></td>
        <td class="vLine" onclick="addLine(this)"></td>
        <td class="box" onclick="fillBox(this)"></td>
        <td class="vLine" onclick="addLine(this)"></td>
        <td class="box" onclick="fillBox(this)"></td>
        <td class="vLine" onclick="addLine(this)"></td>
    </tr>
    <tr>
        <td class="gap"></td>
        <td class="hLine" onclick="addLine(this)"></td>
        <td class="gap"></td>
        <td class="hLine" onclick="addLine(this)"></td>
        <td class="gap"></td>
        <td class="hLine" onclick="addLine(this)"></td>
        <td class="gap"></td>
        <td class="hLine" onclick="addLine(this)"></td>
        <td class="gap"></td>
        <td class="hLine" onclick="addLine(this)"></td>
        <td class="gap"></td>
        <td class="hLine" onclick="addLine(this)"></td>
        <td class="gap"></td>
    </tr>
    <tr>
        <td class="vLine" onclick="addLine(this)"></td>
        <td class="box" onclick="fillBox(this)"></td>
        <td class="vLine" onclick="addLine(this)"></td>
        <td class="box" onclick="fillBox(this)"></td>
        <td class="vLine" onclick="addLine(this)"></td>
        <td class="box" onclick="fillBox(this)"></td>
        <td class="vLine" onclick="addLine(this)"></td>
        <td class="box" onclick="fillBox(this)"></td>
        <td class="vLine" onclick="addLine(this)"></td>
        <td class="box" onclick="fillBox(this)"></td>
        <td class="vLine" onclick="addLine(this)"></td>
        <td class="box" onclick="fillBox(this)"></td>
        <td class="vLine" onclick="addLine(this)"></td>
    </tr>
    <tr>
        <td class="gap"></td>
        <td class="hLine" onclick="addLine(this)"></td>
        <td class="gap"></td>
        <td class="hLine" onclick="addLine(this)"></td>
        <td class="gap"></td>
        <td class="hLine" onclick="addLine(this)"></td>
        <td class="gap"></td>
        <td class="hLine" onclick="addLine(this)"></td>
        <td class="gap"></td>
        <td class="hLine" onclick="addLine(this)"></td>
        <td class="gap"></td>
        <td class="hLine" onclick="addLine(this)"></td>
        <td class="gap"></td>
    </tr>
    <tr>
        <td class="vLine" onclick="addLine(this)"></td>
        <td class="box" onclick="fillBox(this)"></td>
        <td class="vLine" onclick="addLine(this)"></td>
        <td class="box" onclick="fillBox(this)"></td>
        <td class="vLine" onclick="addLine(this)"></td>
        <td class="box" onclick="fillBox(this)"></td>
        <td class="vLine" onclick="addLine(this)"></td>
        <td class="box" onclick="fillBox(this)"></td>
        <td class="vLine" onclick="addLine(this)"></td>
        <td class="box" onclick="fillBox(this)"></td>
        <td class="vLine" onclick="addLine(this)"></td>
        <td class="box" onclick="fillBox(this)"></td>
        <td class="vLine" onclick="addLine(this)"></td>
    </tr>
    <tr>
        <td class="gap"></td>
        <td class="hLine" onclick="addLine(this)"></td>
        <td class="gap"></td>
        <td class="hLine" onclick="addLine(this)"></td>
        <td class="gap"></td>
        <td class="hLine" onclick="addLine(this)"></td>
        <td class="gap"></td>
        <td class="hLine" onclick="addLine(this)"></td>
        <td class="gap"></td>
        <td class="hLine" onclick="addLine(this)"></td>
        <td class="gap"></td>
        <td class="hLine" onclick="addLine(this)"></td>
        <td class="gap"></td>
    </tr>
    <tr>
        <td class="vLine" onclick="addLine(this)"></td>
        <td class="box" onclick="fillBox(this)"></td>
        <td class="vLine" onclick="addLine(this)"></td>
        <td class="box" onclick="fillBox(this)"></td>
        <td class="vLine" onclick="addLine(this)"></td>
        <td class="box" onclick="fillBox(this)"></td>
        <td class="vLine" onclick="addLine(this)"></td>
        <td class="box" onclick="fillBox(this)"></td>
        <td class="vLine" onclick="addLine(this)"></td>
        <td class="box" onclick="fillBox(this)"></td>
        <td class="vLine" onclick="addLine(this)"></td>
        <td class="box" onclick="fillBox(this)"></td>
        <td class="vLine" onclick="addLine(this)"></td>
    </tr>
    <tr>
        <td class="gap"></td>
        <td class="hLine" onclick="addLine(this)"></td>
        <td class="gap"></td>
        <td class="hLine" onclick="addLine(this)"></td>
        <td class="gap"></td>
        <td class="hLine" onclick="addLine(this)"></td>
        <td class="gap"></td>
        <td class="hLine" onclick="addLine(this)"></td>
        <td class="gap"></td>
        <td class="hLine" onclick="addLine(this)"></td>
        <td class="gap"></td>
        <td class="hLine" onclick="addLine(this)"></td>
        <td class="gap"></td>
    </tr>
    <tr>
        <td class="vLine" onclick="addLine(this)"></td>
        <td class="box" onclick="fillBox(this)"></td>
        <td class="vLine" onclick="addLine(this)"></td>
        <td class="box" onclick="fillBox(this)"></td>
        <td class="vLine" onclick="addLine(this)"></td>
        <td class="box" onclick="fillBox(this)"></td>
        <td class="vLine" onclick="addLine(this)"></td>
        <td class="box" onclick="fillBox(this)"></td>
        <td class="vLine" onclick="addLine(this)"></td>
        <td class="box" onclick="fillBox(this)"></td>
        <td class="vLine" onclick="addLine(this)"></td>
        <td class="box" onclick="fillBox(this)"></td>
        <td class="vLine" onclick="addLine(this)"></td>
    </tr>
    <tr>
        <td class="gap"></td>
        <td class="hLine" onclick="addLine(this)"></td>
        <td class="gap"></td>
        <td class="hLine" onclick="addLine(this)"></td>
        <td class="gap"></td>
        <td class="hLine" onclick="addLine(this)"></td>
        <td class="gap"></td>
        <td class="hLine" onclick="addLine(this)"></td>
        <td class="gap"></td>
        <td class="hLine" onclick="addLine(this)"></td>
        <td class="gap"></td>
        <td class="hLine" onclick="addLine(this)"></td>
        <td class="gap"></td>
    </tr>
    <tr>
        <td class="vLine" onclick="addLine(this)"></td>
        <td class="box" onclick="fillBox(this)"></td>
        <td class="vLine" onclick="addLine(this)"></td>
        <td class="box" onclick="fillBox(this)"></td>
        <td class="vLine" onclick="addLine(this)"></td>
        <td class="box" onclick="fillBox(this)"></td>
        <td class="vLine" onclick="addLine(this)"></td>
        <td class="box" onclick="fillBox(this)"></td>
        <td class="vLine" onclick="addLine(this)"></td>
        <td class="box" onclick="fillBox(this)"></td>
        <td class="vLine" onclick="addLine(this)"></td>
        <td class="box" onclick="fillBox(this)"></td>
        <td class="vLine" onclick="addLine(this)"></td>
    </tr>
    <tr>
        <td class="gap"></td>
        <td class="hLine" onclick="addLine(this)"></td>
        <td class="gap"></td>
        <td class="hLine" onclick="addLine(this)"></td>
        <td class="gap"></td>
        <td class="hLine" onclick="addLine(this)"></td>
        <td class="gap"></td>
        <td class="hLine" onclick="addLine(this)"></td>
        <td class="gap"></td>
        <td class="hLine" onclick="addLine(this)"></td>
        <td class="gap"></td>
        <td class="hLine" onclick="addLine(this)"></td>
        <td class="gap"></td>
    </tr>
</table>

Work in progess

At the beginning I just wanted to try to separate the logic from the view, I didn't expect to produce such a big amount of code :-| Anyway, though it's far from being perfect, I think a beginner might find this interesting in some ways.

To ment a little about the code itself, the logic is located in the classes (first half of the javascript section) while the view is the messy bunch of functions at the bottom (second half of the javascript section). The Cell classe and its subclasses (EdgeCell and CoreCell) represent the rectangles. Edge cells are the clickable ones, core cells are the biggest ones.

var GameError = extend(Error, {
    ctor: function () {
        Error.apply(this, arguments);
    }
});

var Game = extend(Object, {
    ctor: function () {
        var size = prompt('Board size: ', 3) || 3;
        this.board = new Board(size);
        this.currentPlayer = 1;
        this.players = [
            new Player(1, '#05A'),
            new Player(2, '#A11')
        ];
    },
    getBoard: function () {
        return this.board;
    },
    getCurrentPlayer: function () {
        return this.players[this.currentPlayer - 1];
    },
    nextTurn: function () {
        this.currentPlayer = this.currentPlayer ^ 3;
    },
    select: function (edge) {
        var coreCells, player;
        edge.switchOn();
        player = this.getCurrentPlayer();
        coreCells = this.board.getCoreCells(edge);
        each(coreCells, function (i, cell) {
            if (cell) {
                cell.incr();
                if (cell.isDone()) {
                    player.incrScore();
                }
            }
        });
    }
});

var Board = extend(Object, {
    ctor: function (width) {
        this.width = width;
        this.cells = this.makeCells();
    },
    getWidth: function () {
        return this.width;
    },
    getCell: function (i, j) {
        try { return this.cells[i][j]; }
        catch (e) { return null; }
    },
    makeCells: function () {
        var l = this.width * 2 + 1;
        var rows = new Array(l);
        loop.call(this, l, function (i) {
            var min = (i % 2) * 2 + 1;
            rows[i] = new Array(l);
            loop.call(this, l, function (j) {
                rows[i][j] = this.createCell(
                    min + j % 2, [i, j]
                );
            });
        });
        return rows;
    },
    createCell: function (type, idx) {
        var ctor;
        switch (type) {
            case Cell.types.CORNER: ctor = Cell; break;
            case Cell.types.H_EDGE: ctor = EdgeCell; break;
            case Cell.types.V_EDGE: ctor = EdgeCell; break;
            case Cell.types.CORE: ctor = CoreCell; break;
            default: throw new Error('Cell type not valid.');
        }
        return new ctor(type, idx);
    },
    getCoreCells: function (edge) {
        var i, j;
        i = edge.getRow();
        j = edge.getColumn();
        return i % 2 ? [
            this.getCell(i, j - 1),
            this.getCell(i, j + 1)
        ] : [
            this.getCell(i - 1, j),
            this.getCell(i + 1, j)
        ];
    }
});

var Player = extend(Object, {
    ctor: function (num, color) {
        this.num = num;
        this.color = color;
        this.score = 0;
    },
    getNum: function () {
        return this.num;
    },
    getColor: function () {
        return this.color;
    },
    getScore: function () {
        return this.score;
    },
    incrScore: function () {
        return this.score++;
    },
    toString: function () {
        return (
            '<span style="color:' + this.color + '">' +
                'Player ' + this.num +
            '</span>'
        );
    }
});

var Cell = extend(Object, {
    ctor: function (type, index) {
        this.type = type;
        this.index = index;
    },
    getType: function () {
        return this.type;
    },
    getIndex: function () {
        return this.index;
    },
    getRow: function () {
        return this.index[0];
    },
    getColumn: function () {
        return this.index[1];
    },
    toString: function () {
        return (
            Cell.names[this.type - 1]
        ) + (
            ' (' + this.index + ')'
        );
    }
});

Cell.types = {
    CORNER: 1,
    H_EDGE: 2,
    V_EDGE: 3,
    CORE: 4
};

Cell.names = [
    'corner',
    'h-edge',
    'v-edge',
    'core'
];

var EdgeCell = extend(Cell, {
    ctor: function (type, index) {
        Cell.call(this, type, index);
        this.on = false;
    },
    isOn: function () {
        return this.on;
    },
    switchOn: function () {
        if (!this.isOn()) this.on = true;
        else throw new GameError(this + ' already on.');
    }
});

var CoreCell = extend(Cell, {
    ctor: function (type, index) {
        Cell.call(this, type, index);
        this.count = 0;
    },
    isDone: function () {
        return this.count === 4;
    },
    incr: function () {
        if (!this.isDone()) this.count++;
        else throw new GameError(this + ' already done.');
    }
});

onload = function () {
    var game = new Game();
    var boardEl = makeBoardDom(game.getBoard());
    document.body.appendChild(boardEl);
    setupListeners(game);
    refreshLog(game);
};

function makeBoardDom (board) {
    var w = board.getWidth() * 2 + 1;
    var boardEl = document.createElement('div');
    boardEl.setAttribute('id', 'board');
    loop(w, function (i) {
        var rowEl = document.createElement('div');
        rowEl.setAttribute('class', 'row');
        boardEl.appendChild(rowEl);
        loop(w, function (j) {
            var cell = board.getCell(i, j);
            var cellEl = document.createElement('div');
            cellEl.setAttribute('class', Cell.names[cell.getType() - 1]);
            rowEl.appendChild(cellEl);
        });
    });
    return boardEl;
}

function setupListeners (game) {
    document.addEventListener('click', function (ev) {
        if (ev.target.className.indexOf('edge') + 1) {
            onEdgeClicked(game, ev.target);
        }
    });
}

function onEdgeClicked (game, edgeEl) {
    var idx, edge, coreCells, board;
    idx = getIndex(edgeEl);
    board = game.getBoard();
    edge = board.getCell.apply(board, idx);
    if (!edge.isOn()) {
        game.select(edge);
        edgeEl.className += ' on';
        coreCells = board.getCoreCells(edge);
        each(coreCells, function (i, cell) {
            if (cell && cell.isDone()) {
                refreshCoreCell(game, cell);
            }
        });
        game.nextTurn();
        refreshLog(game);
    }
}

function refreshCoreCell (game, cell) {
    var boardEl, rowEl, cellEl, player;
    player = game.getCurrentPlayer();
    boardEl = document.getElementById('board');
    rowEl = boardEl.childNodes[cell.getRow()];
    cellEl = rowEl.childNodes[cell.getColumn()];
    cellEl.style.background = player.getColor();
}

function refreshLog (game) {
    var turnEl = document.getElementById('turn');
    var scoresEl = document.getElementById('scores');
    var players = game.players.slice();
    players[0] += ': ' + players[0].getScore();
    players[1] += ': ' + players[1].getScore();
    turnEl.innerHTML = 'Turn: ' + game.getCurrentPlayer();
    scoresEl.innerHTML = players.join('<br />');
}

function getIndex (el) {
    var rowEl = el.parentNode;
    var boardEl = rowEl.parentNode;
    var indexOf = Array.prototype.indexOf;
    var j = indexOf.call(rowEl.childNodes, el);
    var i = indexOf.call(boardEl.childNodes, rowEl);
    return [i, j];
}

function each (list, fn) {
    var i, n = list.length;
    for (i = 0; i < n; i++) {
        fn.call(this, i, list[i]);
    }
}

function loop (n, fn) {
    var i = 0;
    while (i < n) {
        fn.call(this, i++);
    }
}

function extend (parent, proto) {
    var ctor = proto.ctor;
    delete proto.ctor;
    ctor.prototype = Object.create(parent.prototype);
    ctor.prototype.constructor = ctor;
    for (var k in proto) ctor.prototype[k] = proto[k];
    return ctor;
}
.row div {
    float: left;
}

.row::after {
    content: " ";
    display: block;
    clear: both;
}

.corner {
    width: 20px;
    height: 20px;
    background: #333;
}

.h-edge {
    width: 50px;
    height: 20px;
}

.v-edge {
    width: 20px;
    height: 50px;
}

.v-edge:hover,
.h-edge:hover {
    cursor: pointer;
    background: #999;
}

.v-edge.on,
.h-edge.on {
    cursor: pointer;
    background: #333;
}

.core {
    width: 50px;
    height: 50px;
}

#turn, #scores {
    font: normal 16px Courier;
    margin-bottom: .5em;
}
<div id="scores"></div>
<div id="turn"></div>

发布评论

评论列表(0)

  1. 暂无评论