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()
本想把生活活成一首诗, 时而优雅 , 时而豪放 , 结果活成了一首歌 , 时而不靠谱 , 时而不着调