欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

原生js实现 五子棋

程序员文章站 2022-12-28 14:52:46
先初始化棋盘 HTML: CSS: JS:// 棋盘 我们先让每个棋子的value都为1,看看效果: 不要犯密集恐惧症哦, 我们用事件委托来绑定事件, 这样事件只需要绑定一次而不用绑定15 * 15次, 很大地提升了效率, 开始写点击事件: 现在我们可以下棋了: 很有成就感是不是,就差最后一步也最是 ......

先初始化棋盘

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,看看效果:

原生js实现 五子棋

不要犯密集恐惧症哦,

我们用事件委托来绑定事件, 这样事件只需要绑定一次而不用绑定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 ++ ;
}
 }

现在我们可以下棋了:

原生js实现 五子棋

很有成就感是不是,就差最后一步也最是核心的一步

判断横着, 竖着, 斜着 是否有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   

最后的效果:

原生js实现 五子棋