html

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <link rel="stylesheet" href="./game.css">
</head>

<body>
    <div id="container">
        <div class="qipan"></div>
        <div class="qizi"></div>
    </div>
    <script src="./game.js">
    </script>
</body>

</html>

css

* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}

/* 15 * 60 */
#container {
    position: relative;
    height: 900px;
    width: 900px;
    background-color: #d2b965;
    margin: 0 auto;
    display: flex;
    align-items: center;
    justify-content: center;
}

.qipan {
    width: 842px;
    height: 842px;
    display: flex;
    flex-wrap: wrap;
    border: 1px solid #372406;
}

.qipan div {
    flex: 0 0 60px;
    height: 60px;
    border: 1px solid #372406;
}

.qizi {
    position: absolute;
    top: 0;
    left: 0;
    z-index: 1;
    width: 900px;
    height: 900px;
    display: flex;
    flex-wrap: wrap;
}

.qizi div {
    position: relative;
    flex: 0 0 60px;
    height: 60px;
    cursor: pointer;
}

.qizi .bai::after {
    content: '';
    position: absolute;
    top: 50%;
    left: 50%;
    z-index: 2;
    transform: translate(-50%, -50%);
    width: 48px;
    height: 48px;
    background-color: #fff;
    border-radius: 50%;
    cursor: not-allowed;
}

.qizi .hei::after {
    content: '';
    position: absolute;
    top: 50%;
    left: 50%;
    z-index: 2;
    transform: translate(-50%, -50%);
    width: 48px;
    height: 48px;
    background-color: #222;
    border-radius: 50%;
    cursor: not-allowed;
}

Javascript

// 1 黑子 2白子
class Game {
    constructor() {
        this.list = new Array(225).fill(0)
        this.qizi = document.querySelector('.qizi')
        this.isOver = false
        // 计数, 1黑 2白
        this.startIndex = 1
        this.renderQiPan()
        this.renderQizi()
        this.bindEvevt()
    }

    // 渲染棋盘
    renderQiPan() {
        for (let i = 0; i < 196; i++) {
            const div = document.createElement('div')
            document.querySelector('.qipan').appendChild(div)
        }
    }

    // 渲染棋子
    renderQizi() {
        const className = (state) => {
            switch (state) {
                case 1:
                    return 'hei'
                case 2:
                    return 'bai'
                default:
                    return ''
            }
        }
        this.qizi.innerHTML = ''
        this.list.map((i, index) => {
            const div = document.createElement('div')
            div.setAttribute('class', className(i))
            div.setAttribute('data-index', index)
            this.qizi.appendChild(div)
        })
    }

    // 绑定事件
    bindEvevt() {
        // 绑定下子
        this.qizi.addEventListener('click', ev => {
            if (this.isOver) {
                this.list = new Array(225).fill(0);
                this.isOver = false
                this.startIndex = 1
                this.renderQizi()
                return
            }
            const index = parseInt(ev.target.getAttribute('data-index'))
            console.log(`点击了${index}`);
            const current = this.list[index]
            if (current) return
            this.list[index] = this.startIndex
            this.startIndex = 3 - this.startIndex
            this.renderQizi()
            this.checkIsOver()
        })
    }

    // 处理result
    handleResult(result) {
        const c1 = result.count
        const l1 = result.lastColor
        if (c1 > 4) {
            this.isOver = true
            setTimeout(() => {
                alert(`${l1 === 1 ? '黑子' : '白子'}玩家胜利`)
            })
            return true
        }
        return false
    }

    // 校验是否结束
    checkIsOver() {
        // c 计数 l 颜色 当 c >= 5 时, l颜色用户胜利
        // 横向校验
        const result1 = this.checkLeft2Right()
        const flag1 = this.handleResult(result1)
        if (flag1) return
        // 纵向校验
        const result2 = this.checkTop2Bottom()
        const flag2 = this.handleResult(result2)
        if (flag2) return
        // 左上到右下
        const result3 = this.checkLeftTop2RightBottom()
        const flag3 = this.handleResult(result3)
        if (flag3) return
        // 右上到坐下
        const result4 = this.checkRightTop2LeftBottom()
        this.handleResult(result4)
    }

    // 断定颜色 list:二维数组
    checkColor(list) {
        let count = 0
        let lastColor = 0
        for (let i = 0; i < list.length; i++) {
            for (let j = 0; j < list[i].length; j++) {
                const c = list[i][j]
                if (c) {
                    if (c === lastColor) {
                        count++
                        if (count >= 5) {
                            return { count, lastColor }
                        }
                    } else {
                        count = 1
                        lastColor = c
                    }
                } else {
                    count = 0
                    lastColor = 0
                }
            }
        }
        return { count, lastColor }
    }

    // 校验横向是否胜利
    checkLeft2Right() {
        const list = [...this.list]
        const list2 = []
        let temp = []
        list.map(i => {
            temp.push(i)
            if (temp.length >= 15) {
                list2.push([...temp])
                temp = []
            }
        })
        return this.checkColor(list2)
    }

    // 校验上下是否胜利
    checkTop2Bottom() {
        const list = [...this.list]
        const list2 = [[], [], [], [], [], [], [], [], [], [], [], [], [], [], []]
        list.map((i, idx) => {
            const index = idx % 15
            list2[index].push(i)
        })
        return this.checkColor(list2)
    }

    // 获取左上到右下45°∠的子
    getRightPointer(p) {
        const ret = [p]
        let num = p
        let num2 = p + 16
        while (num % 15 < num2 % 15 && num2 < 225) {
            ret.push(num2)
            num = num2
            num2 += 16
        }
        return ret
    }

    // 校验右上到坐下
    checkLeftTop2RightBottom() {
        const base = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 15, 30, 45, 60, 75, 90, 105, 120, 135, 150]
        // 生成对比地图
        const list = []
        base.map(i => {
            const ret = this.getRightPointer(i)
            list.push(ret)
        })
        const list2 = []
        list.map(i => {
            const temp = []
            i.map(j => {
                temp.push(this.list[j])
            })
            list2.push(temp)
        })
        return this.checkColor(list2)
    }

    // 获取右上到左下45°∠的子
    getLeftPointer(p) {
        const ret = [p]
        let num = p
        let num2 = p + 14
        while (num % 15 > num2 % 15 && num2 < 225) {
            ret.push(num2)
            num = num2
            num2 += 14
        }
        return ret
    }

    checkRightTop2LeftBottom() {
        const base = [4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 29, 44, 59, 74, 89, 104, 119, 134, 149, 164]
        const list = []
        this.getLeftPointer(4)
        base.map(i => {
            const ret = this.getLeftPointer(i)
            list.push(ret)
        })
        const list2 = []
        list.map(i => {
            let temp = []
            i.map(j => {
                temp.push(this.list[j])
            })
            list2.push(temp)
        })
        return this.checkColor(list2)
    }
}

new Game()

 

 

posted on 2022-12-11 20:46  深海里的星星i  阅读(146)  评论(0编辑  收藏  举报