先初始化棋盘
HTML:
<!--棋盘--> <div class="grid"></div>
CSS:
/*棋盘*/ .grid{ position: relative; width: 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; width: 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
最后的效果: