js五子棋效果

飞奔的龟龟發表於2024-10-24

任務分解

一、繪製棋盤

二、繫結事件

1、先計算出需要繪製棋子的座標 即將來繪製的棋子在哪個單元格內

2、繪製棋子 首先判斷棋子是否存在 應該新增到哪個單元格內,分四種情況:

1.1 正常情況

1.2 最右側 超出邊界只能放在最後一個單元格內

1.3 左下側 超出邊界只能放在最後一個單元格內

1.4 右下側 超出邊界只能放在最後一個單元格內

3、當5個連續的棋子一樣就算贏了 遊戲結束 處理結束的邏輯 五個連續的需要處理四種情況:

1.1 橫向的5個連續相同的棋子

1.2 豎著的5個連續相同的棋子

1.3 二個斜著的5個連續相同的棋子

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <link rel="stylesheet" href="./css/index.css">
</head>
<body>
    <div class="container">
        <table class="chessboard"></table>
    </div>
    <script src="./js/index.js"></script>
</body>
</html>
*{
    /* margin: 0;
    padding: 0; */
}
.container{
    width: 500px;
    height: 500px;
    border: 1px solid #ccc;
    background-color: bisque;
    margin: 30px auto;
    display: flex;
    justify-content: center;
    align-items: center;
}
.chessboard{
    border-collapse: collapse;
    border-spacing: 0;
    width: 94%;
    height: 94%;
}
.chessboard td{
    border: 1px solid #000;
    position: relative;
}
.chess{
    position: absolute;
    top: -50%;
    left: -50%;
    width: 80%;
    height: 80%;
    background-color: lightgrey;
    border-radius: 50%;
    color: lightgrey;
    font-size: 12px;
    font-weight: bold;

    /* 彈性盒文字居中 */
    display: flex;
    align-items: center;
    justify-content: center;
}
.white{
    background: #fff;
}
.blackc{
    background-color: #000;
}
.win{
    border: 1px solid red;
    box-shadow: 0 0 3px 2px red;
}
function $(selector) {
    return document.querySelector(selector);
}

function $$(selector) {
    return document.querySelectorAll(selector);
}
var chessboard = document.querySelector('.chessboard');
var whichOne = "white";
//生成的最大範圍區間
var sectionNum = 14;
//是否結束
var isGameOver = false;
var chessArr = [];
function initChessboard() {
    var tableContent = '';
    for (var i = 0; i < sectionNum; i++) {
        var row = `<tr>`;
        for (var j = 0; j < sectionNum; j++) {
            row += `<td data-row="${i}" data-line="${j}"></td>`;
        }
        row += '</tr>';
        tableContent += row;
    }
    chessboard.innerHTML = tableContent;
}
//offsetLeft 一個元素相對於父元素的的水平偏移量
function bindEvent() {
    chessboard.addEventListener('click', function (e) {
        console.log(e);
        if (!isGameOver) {
            var temp = Object.assign({}, e.target.dataset);
            if (e.target.nodeName === 'TD') {
                //首先判斷點選的td 所處的座標  (從而計算出 棋子在哪個單元格)
                //比較滑鼠點選的位置 與單元格的一半哪個大哪個小 從而計算出棋子是在當前單元格還是在下一個單元格內

                //求出單元格的寬高
                var tdw = chessboard.clientWidth * 0.94 / sectionNum;
                //比一半小則保留當前在當前單元格內
                //比一半大則保留在下一個單元格內
                var positionX = e.offsetX > tdw / 2;
                var positionY = e.offsetY > tdw / 2;
                //計算出棋子的座標 也就是在哪個單元格內
                var chessPoint = {
                    x: positionX ? parseInt(temp.line) + 1 : parseInt(temp.line),
                    y: positionY ? parseInt(temp.row) + 1 : parseInt(temp.row),
                    c: whichOne
                }

                //繪製棋子
                chessMove(chessPoint);
            }
        } else {
            //結束了是否要重新開始
            if (window.confirm('恭喜你贏了,是否要重新開始?')) {
                //重新開始 重新繪製 陣列置空
                isGameOver = false;
                initChessboard();
                chessArr = [];
            }
        }
    })
}

function chessMove(chessPoint) {
    //檢測棋子已經繪製 在點選到當前範圍內不在繪製棋子
    //判斷棋子是否已經存在
    if (exist(chessPoint) && !isGameOver) {
        //繪製棋子 就是將div新增到單元格內

        var newDiv = `<div class="chess ${chessPoint.c}" data-row="${chessPoint.y}" data-line="${chessPoint.x}">`;
        chessArr.push(chessPoint);
        //新增到哪個單元格內分四種情況 (處理邊界條件)

        //正常情況
        if (chessPoint.x < 14 && chessPoint.y < 14) {
            var tdP = $(`td[data-row='${chessPoint.y}'][data-line='${chessPoint.x}']`);
            console.log(tdP)
            tdP.innerHTML += newDiv;
        }

        //最右側 超出邊界只能放在最後一個單元格內
        if (chessPoint.x === 14 && chessPoint.y < 14) {
            var tdP = $(`td[data-row='${chessPoint.y}'][data-line='${chessPoint.x - 1}']`);
            tdP.innerHTML += newDiv;
            tdP.lastChild.style.left = '50%';
        }

        //左下側 超出邊界只能放在最後一個單元格內
        if (chessPoint.x < 14 && chessPoint.y === 14) {
            var tdP = $(`td[data-row='${chessPoint.y - 1}'][data-line='${chessPoint.x}']`);
            tdP.innerHTML += newDiv;
            tdP.lastChild.style.top = '50%';
        }

        //右下側 超出邊界只能放在最後一個單元格內
        if (chessPoint.x === 14 && chessPoint.y === 14) {
            var tdP = $(`td[data-row='${chessPoint.y - 1}'][data-line='${chessPoint.x - 1}']`);
            tdP.innerHTML += newDiv;
            tdP.lastChild.style.left = '50%';
            tdP.lastChild.style.top = '50%';
        }

        whichOne = whichOne === 'white' ? 'blackc' : 'white';
    }

    //判斷遊戲是否結束
    checker()
}

function exist(chessPoint) {
    var res = chessArr.find(function (item) {
        return item.x === chessPoint.x && item.y === chessPoint.y && item.c === chessPoint.c
    })
    return res === undefined ? true : false;
}

function checker() {
    console.log(chessArr);
    for (var i = 0; i < chessArr.length; i++) {
        var chess = chessArr[i];
        var chess2, chess3, chess4, chess5;

        //處理邊界條件  5個連續的 分四種情況

        //連續橫著的
        chess2 = chessArr.find(function (item) {
            return chess.x === item.x + 1 && chess.y === item.y && chess.c === item.c;
        });
        chess3 = chessArr.find(function (item) {
            return chess.x === item.x + 2 && chess.y === item.y && chess.c === item.c;
        });
        chess4 = chessArr.find(function (item) {
            return chess.x === item.x + 3 && chess.y === item.y && chess.c === item.c;
        });
        chess5 = chessArr.find(function (item) {
            return chess.x === item.x + 4 && chess.y === item.y && chess.c === item.c;
        });
        if (chess2 && chess3 && chess4 && chess5) {
            end(chess, chess2, chess3, chess4, chess5);
        }

        //連續豎著的
        chess2 = chessArr.find(function (item) {
            return chess.y === item.y + 1 && chess.x === item.x && chess.c === item.c;
        })
        chess3 = chessArr.find(function (item) {
            return chess.y === item.y + 2 && chess.x === item.x && chess.c === item.c;
        })
        chess4 = chessArr.find(function (item) {
            return chess.y === item.y + 3 && chess.x === item.x && chess.c === item.c;
        })
        chess5 = chessArr.find(function (item) {
            return chess.y === item.y + 4 && chess.x === item.x && chess.c === item.c;
        })
        if (chess2 && chess3 && chess4 && chess5) {
            end(chess, chess2, chess3, chess4, chess5);
        }

        //連續斜著的
        chess2 = chessArr.find(function (item) {
            return chess.x === item.x + 1 && chess.y === item.y + 1 && chess.c === item.c;
        });
        chess3 = chessArr.find(function (item) {
            return chess.x === item.x + 2 && chess.y === item.y + 2 && chess.c === item.c;
        });
        chess4 = chessArr.find(function (item) {
            return chess.x === item.x + 3 && chess.y === item.y + 3 && chess.c === item.c;
        });
        chess5 = chessArr.find(function (item) {
            return chess.x === item.x + 4 && chess.y === item.y + 4 && chess.c === item.c;
        });
        if (chess2 && chess3 && chess4 && chess5) {
            end(chess, chess2, chess3, chess4, chess5);
        }

        //反斜著的
        chess2 = chessArr.find(function (item) {
            return chess.x === item.x - 1 && chess.y === item.y + 1 && chess.c === item.c;
        });
        chess3 = chessArr.find(function (item) {
            return chess.x === item.x - 2 && chess.y === item.y + 2 && chess.c === item.c;
        });
        chess4 = chessArr.find(function (item) {
            return chess.x === item.x - 3 && chess.y === item.y + 3 && chess.c === item.c;
        });
        chess5 = chessArr.find(function (item) {
            return chess.x === item.x - 4 && chess.y === item.y + 4 && chess.c === item.c;
        });
        if (chess2 && chess3 && chess4 && chess5) {
            end(chess, chess2, chess3, chess4, chess5);
        }
    }
}

function end() {
    if (!isGameOver) {
        isGameOver = true;
        //結束之後顯示棋子的順序
        for (var i = 0; i < chessArr.length; i++) {
            $(`div[data-row='${chessArr[i].y}'][data-line='${chessArr[i].x}']`).innerHTML = i + 1;
        }

        //給勝利的棋子加高亮顯示
        for (var j = 0; j < arguments.length; j++) {
            console.dir($(`div[data-row='${arguments[j].y}'][data-line='${arguments[j].x}']`))
            $(`div[data-row='${arguments[j].y}'][data-line='${arguments[j].x}']`).classList.add('win');
        }
    }
}

function main() {
    //初始化棋盤
    initChessboard();

    //繫結監聽事件
    bindEvent();
}
main();

相關文章