先初始化棋盘
HTML:
<!--棋盘--> <div class="grid"></div>
CSS:
/*棋盘*/ .grid{ position: relative; 762px; height: 762px; background-image: url('./image/timg.jpg'); -webkit-background-size: 100% 100%; background-size: 100% 100%; background-position: center center; margin: 100px auto; } /*每个棋子落点区域*/ .per-zone{ position: absolute; 50px; height: 50px; padding: 10px; background-origin: content-box; box-sizing: border-box; background-position: center center; background-size: 100% 100%; background-repeat: no-repeat; }
JS:// 棋盘
const grid = document.getElementsByClassName('grid')[0];
// 棋盘有15列, 15行
const column = 15 , line = 15;
// 装棋子的二维数组
let gridArr = [];
// 初始化二维数组
function init() {
// 文档碎片用来装棋子优化效率
const fragment = document.createDocumentFragment();
gridArr = new Array(line);
for(let i = 0; i < gridArr.length; i ++) {
gridArr[i] = new Array(column);
for(let j = 0; j < gridArr[i].length; j ++) {
// 创建每个棋子落点区域
fragment.appendChild(createZone(j, i));
}
}
grid.appendChild(fragment);
// 事件委托, 性能优化
grid.addEventListener('click', (e) => {
begin(e);
}, false)
}
init();
function createZone(x, y) {
// 创建棋子
const div = document.createElement('div');
div.classList.add('per-zone');
div.style.left = x * 50 + 7 + 'px';
div.style.top = y * 50 + 7 + 'px';
// 标记棋子的类型,黑子为1, 白子为2, 初始化为0
div.value = 1;
div.style.backgroundImage = `url(${'./image/' + div.value + '.png' })`;
return div
}
我们先让每个棋子的value都为1,看看效果:

不要犯密集恐惧症哦,
我们用事件委托来绑定事件, 这样事件只需要绑定一次而不用绑定15 * 15次,
很大地提升了效率,
开始写点击事件:
// 计数, 用来判定落黑子还是落白子 let count = 0; // 黑:value =1 ; 白: value = 2 function begin(target) {
// 判断value为0 才能下子
if (!target.value) {
target.value = count%2 + 1 ;
target.style.backgroundImage = `url(${'./image/' + target.value + '.png' })`;
// 判断是否结束
judgeFinish();
count ++ ;
}
}
现在我们可以下棋了:

很有成就感是不是,就差最后一步也最是核心的一步
判断横着, 竖着, 斜着 是否有5个以上相同颜色的棋子
function judgeFinish() { for (let i = 0; i < gridArr.length; i ++) { for(let j = 0; j < gridArr[i].length; j ++) { // value 为 0 跳过 if (gridArr[i][j].value === 0) { continue; } // 判断是否五子连珠 const result = judgeLine(i, j); if (result === 1) { alert('黑棋胜利'); replay(); return } else if (result === 2) { alert('白棋胜利'); replay(); return } } } } // 判断向下, 向右, 向斜上, 向斜下四个方向 function judgeLine(x, y) { // 黑1, 白2 let result1 = 3, result2 = 3, result3 =3, result4 =3; for (let i = 0; i < 5; i ++) { // 向下 result1 &= y + i < 14 ? gridArr[x][y + i].value : 0; // 向右 result2 &= x + i < 14 ? gridArr[x + i][y].value : 0; // 斜上 result3 &= (x + i > 14 || y - i < 0) ? 0 : gridArr[x + i][y - i].value; // 斜下 result4 &= (x + i > 14 || y + i > 14) ? 0 : gridArr[x + i][y + i].value; } // 只要有一个方向不为0 游戏结束 return result1 | result2 | result3 | result4 } function replay() { // 装棋子的二维数组 gridArr = []; // 计数, 用来判定落黑子还是落白子 count = 0; grid.innerHTML = ''; init(); }
核心: 使用& 运算符 来 判断 是否 5 子 的 value 相同
1& 1& 1& 1& 1 = 1
2 & 2 &2 &2 &2 = 2
为什么初始值设成3 呢, 因为任何数 & 3 都不会变
先转化成2进制 再运算 3 =》 11
最后的效果:
