来简单做个五子棋

3 篇文章 0 订阅
3 篇文章 0 订阅

简易五子棋判断及棋盘制作


由于本人对五子棋不是特别熟悉,就勉强自己做了个。
有什么做错了就请多包含或在评论区指正

© BaiG 2022. All rights reserved.

这个项目我做了快一个下午,脑细胞估计死的七七八八了!
项目使用 GitHub Copilot 加快进度
点赞加关注!!
先写的代码有点小问题看到最后

整体思路:

首先先使用 JavaScript 生成 15*15 棋盘
按下后生成棋子
每次生成棋子后判断:棋子是否连续5颗

代码+制作过程:

var ended = false;
// 用来判断是否可以继续放下棋子
var zi = 0;
// 棋盘上有的棋子数量
var color = 'black';
// 当前下棋方颜色 ['black' / 'white;]
var colorNum = 1;
// 颜色号码 [1 / 2]
var qipan = $('#qipan');
// 获取要生成棋盘的 div

HTML
<div class="center" id="qipan">
</div>
<div class="infor">
    <h1 id="xiaqifang">当前下棋方:黑子</h1>
    <h1 id="dinkezi">第0颗子</h1>
</div>

生成 15*15 棋盘
// make 15*button.col_btn 15 * div.raw
for (var i = 0; i < 15; i++) { // 15 横行
    var raw = $('<div class="raw"></div>');
    for (var j = 0; j < 15; j++) { // 15 纵行
        var col_btn = $('<button class="col_btn"></button>');
        col_btn.attr('id', i + '-' + j);
        col_btn.attr('onclick', 'chess(this)');
        raw.append(col_btn);
        /* 在每个纵行上生成按钮
           class 是 col_btn
           id 是 y坐标-x坐标
           同时生成 onclick 事件
           按下时触发函数:chess 并将元素作为参数传入
           ( chess(element) )
        */
    }
    qipan.append(raw);
}
创建一个 array 以便之后判断胜利用
var chess_arr = [
    [
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
    ],
    [
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
    ],
    [
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
    ],
    [
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
    ],
    [
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
    ],
    [
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
    ],
    [
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
    ],
    [
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
    ],
    [
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
    ],
    [
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
    ],
    [
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
    ],
    [
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
    ],
    [
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
    ],
    [
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
    ],
    [
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
    ]
];

使用自动化函数制作:

arr = [];
// make arr = [[0*15]*15]
for(var i = 0; i < 15; i++){
    arr[i] = [];
    for(var j = 0; j < 15; j++){
        arr[i][j] = 0;
    }
}

美化

使用 css 对棋盘进行美化

加入style前:
Image
加入style后:
Image

CSS:

 :root {
    --qizi-width: 40px; /*棋子的大小*/
}

.col_btn {
    height: 45px; /*每一格大小*/
    width: 45px;
    margin: 0;
    border-radius: none;
    border: 1px solid black;
    background: burlywood;
}

.col_btn:hover {
    background: url(chess_tips.png); 
    /*当用户鼠标悬停在格子上时显示图片 chess_tips.png (箭头) */
    background-size: cover;
    /*保证图片不会超出大小而无法显示*/
}

.raw {
    display: flex;
    /*让每一格之间没有空隙*/
}

.center { /*置中*/
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    border: 1px solid black;
}

.circle_black { /*黑棋*/
    position: relative;
    top: 60%; /* 放置在交点 */
    left: 60%;
    height: var(--qizi-width);
    width: var(--qizi-width);
    margin: 0;
    border-radius: 50%;
    background: black;
    box-shadow: white 0 0 10px;
}

.circle_white { /*白棋*/
    position: relative;
    top: 60%;
    left: 60%;
    height: var(--qizi-width);
    width: var(--qizi-width);
    margin: 0;
    border-radius: 50%;
    background: white;
    box-shadow: black 0 0 10px;
}

.cover { /*当某方胜利后
会生成一个 div.cover 挡住用户不让其鼠标触碰棋盘*/
    position: absolute;
    top: 0;
    left: 0;
    height: 100%;
    width: 100%;
    background: rgba(255, 255, 255, 0.5);
}

.infor {
    z-index: 99;
    position: absolute;
}

通知用户:

<script src="https://xchuangc.github.io/messagejs/message.js"></script>
<script>
    startXmessage();
</script>

这个项目里我用小插件效果自己看吧 MessageJS

Image

Image


当格子被按下:
var chess = function(element) {
    if (!ended) { // 没有完结的时候
        if (document.getElementById(element.id).innerHTML == '') {
        	// 如果该格子是空的
            $(`#${element.id}`).append(`<div class="circle_${color}"></div>`);
            // 创建棋子
            chess_arr[element.id.split('-')[0]][element.id.split('-')[1]] = colorNum;
			// 向 chess_arr 添加类似坐标的东西
			
			// 黑子走完变白子,很正常吧
            if (color === 'black') {
                color = 'white';
                colorNum = 2;
            } else {
                color = 'black';
                colorNum = 1;
            }
            zi++;
            // 添加已经走了的棋子个数
            $('#xiaqifang').html(`当前下棋方:${color === 'black' ? '黑子' : '白子'}`);
            // 设置为:当前下棋方:黑/白
            $('#dinkezi').html(`第${zi}颗子`);
            if (win(chess_arr)) {
                return;
            }
            // 判断输赢
        } else {
            message('该位置已有棋子!');
            // 如果该格子不是空的,那么就弹出信息
        }
    }
}

结束对局:

先不说胜利条件判断,我会先写对局结束后的代码

function end(m) {
    message(m);
    ended = true;
    $('#qipan').append(`<div class="cover">当前胜利方:${m.split('子赢了')[0]}<br>下子数:${zi}颗子</div>`);
}

当某方胜利后,会执行 end() 函数


输赢判断:

1. 判断横向是否连续连成5颗

思路:

找到 xy 轴中第一颗黑子的坐标
如果第一颗黑子的 x+1 也是黑子,那么count_black++;
如果第一颗白子的 x+1 也是白子,那么count_white++;
当count_black 或者 count_white 是等于四
执行 end(‘x子赢了’);
如果没有子是横向连着的,那就将 count_xxxxx 设为零。

function win(arr){ // 传入棋盘:chess_arr 为参数
	var count_black = 0;
    var count_white = 0;
    // 初始化
}
// 横向
for (var i = 0; i < 15; i++) {
    for (var j = 0; j < 15; j++) {
        if ((arr[i][j] == 1) && (arr[i][j] == arr[i][j + 1])) {
        	// 寻找连着的黑子
            count_black++;
        } else if ((arr[i][j] == 2) && (arr[i][j] == arr[i][j + 1])) {
	        // 寻找连着的白子
            count_white++;
        }
        if (count_black == 4) {
            end('黑子赢了');
            return true;
        } else if (count_white == 4) {
            end('白子赢了');
            return true;
        }
        //判断
    }
}
count_black = 0;
count_white = 0;

颜色代码:0 = 空气;1 = 黑子;2 = 白子

来看核心判断代码:

(arr[i][j] == 1) && (arr[i][j] == arr[i][j + 1])

arr[i][j] == 1 判断是否是黑子
arr[i][j] == arr[i][j + 1] 判断下一格和自己是不是一样的

连在一起就是如果第一颗子是黑子并且下一颗子也是黑子的话:
count_black++;

白子也一样,只不过颜色代码换成了 2


1. 判断纵向是否连续连成5颗

思路:

找到 xy 轴中第一颗黑子的坐标
如果第一颗黑子的 y+1 也是黑子,那么count_black++;
如果第一颗白子的 y+1 也是白子,那么count_white++;
当count_black 或者 count_white 是等于四
执行 end(‘x子赢了’);
如果没有子是纵向连着的,那就将 count_xxxxx 设为零。

思路基本一样,只不过 x+1 变成了 y+1

// 纵向
for (var i = 0; i < 15; i++) {
    for (var j = 0; j < 15; j++) {
        if ((arr[i][j] == 1) && (arr[i][j] == arr[i + 1][j])) {
            count_black++;
        } else if ((arr[i][j] == 2) && (arr[i][j] == arr[i + 1][j])) {
            count_white++;
        }
        if (count_black == 4) {
            end('黑子赢了');
            return true;
        } else if (count_white == 4) {
            end('白子赢了');
            return true;
        }
    }
}
count_black = 0;
count_white = 0;

思路一样我就不写备注了哈


1. 判断斜向是否连续连成5颗

思路:

找到 xy 轴中第一颗黑子的坐标
如果第一颗黑子的 y+1 x+1 或者 y-1 x+1 也是黑子,那么count_black++;
如果第一颗白子的 y+1 x+1 或者 y-1 x+1 也是白子,那么count_white++;
当count_black 或者 count_white 是等于四
执行 end(‘x子赢了’);
如果没有子是斜向连着的,那就将 count_xxxxx 设为零。

这个要写两个for,分别判断从左上到右下,和从右上到左下。

// 斜向
for (var i = 0; i < 15; i++) {
    for (var j = 0; j < 15; j++) {
        if ((arr[i][j] == 1) && (arr[i][j] == arr[i + 1][j + 1])) {
            count_black++;
        } else if ((arr[i][j] == 2) && (arr[i][j] == arr[i + 1][j + 1])) {
            count_white++;
        }
        if (count_black == 4) {
            end('黑子赢了');
            return true;
        } else if (count_white == 4) {
            end('白子赢了');
            return true;
        }
    }
}
for (var i = 0; i < 15; i++) {
    for (var j = 0; j < 15; j++) {
        if ((arr[i][j] == 1) && (arr[i][j] == arr[i - 1][j + 1])) {
            count_black++;
            console.log(count_black);
        } else if ((arr[i][j] == 2) && (arr[i][j] == arr[i - 1][j + 1])) {
            count_white++;
        }
        if (count_black == 4) {
            end('黑子赢了');
            return true;
        } else if (count_white == 4) {
            end('白子赢了');
            return true;
        }
    }
}
count_black = 0;
count_white = 0;

Image
Image
Image
Image
Image
Image
Image

Bug 解决

Image
这样算赢。。。

每两颗子连在一起,就 +1。但是我们要 5 颗子连着。

(arr[i][j] == 1) && (arr[i][j] == arr[i][j + 1]) 变成:

(arr[i][j] == 1) && (arr[i][j] == arr[i][j + 1]) && (arr[i][j] == arr[i][j + 2]) && (arr[i][j] == arr[i][j + 3]) && (arr[i][j] == arr[i][j + 4])

这样的话就不会发生刚刚的情况了

Image
其他几个也是一样的改改

改完之后的 win() 函数。

function win(arr) {
    var count_black = 0;
    var count_white = 0;
    // 横向
    for (var i = 0; i < 15; i++) {
        for (var j = 0; j < 15; j++) {
            if ((arr[i][j] == 1) && (arr[i][j] == arr[i][j + 1]) && (arr[i][j] == arr[i][j + 2]) && (arr[i][j] == arr[i][j + 3]) && (arr[i][j] == arr[i][j + 4])) {
                count_black++;
            } else if ((arr[i][j] == 2) && (arr[i][j] == arr[i][j + 1]) && (arr[i][j] == arr[i][j + 2]) && (arr[i][j] == arr[i][j + 3]) && (arr[i][j] == arr[i][j + 4])) {
                count_white++;
            }
            if (count_black == 4) {
                end('黑子赢了');
                return true;
            } else if (count_white == 4) {
                end('白子赢了');
                return true;
            }
        }
    }
    count_black = 0;
    count_white = 0;
    // 纵向
    for (var i = 0; i < 15; i++) {
        for (var j = 0; j < 15; j++) {
            if ((arr[i][j] == 1) && (arr[i][j] == arr[i + 1][j]) && (arr[i][j] == arr[i + 2][j]) && (arr[i][j] == arr[i + 3][j]) && (arr[i][j] == arr[i + 4][j])) {
                count_black++;
            } else if ((arr[i][j] == 2) && (arr[i][j] == arr[i + 1][j]) && (arr[i][j] == arr[i + 2][j]) && (arr[i][j] == arr[i + 3][j]) && (arr[i][j] == arr[i + 4][j])) {
                count_white++;
            }
            if (count_black == 4) {
                end('黑子赢了');
                return true;
            } else if (count_white == 4) {
                end('白子赢了');
                return true;
            }
        }
    }
    count_black = 0;
    count_white = 0;
    // 斜向
    for (var i = 0; i < 15; i++) {
        for (var j = 0; j < 15; j++) {
            if ((arr[i][j] == 1) && (arr[i][j] == arr[i + 1][j + 1]) && (arr[i][j] == arr[i + 2][j + 2]) && (arr[i][j] == arr[i + 3][j + 3]) && (arr[i][j] == arr[i + 4][j + 4])) {
                count_black++;
            } else if ((arr[i][j] == 2) && (arr[i][j] == arr[i + 1][j + 1]) && (arr[i][j] == arr[i + 2][j + 2]) && (arr[i][j] == arr[i + 3][j + 3]) && (arr[i][j] == arr[i + 4][j + 4])) {
                count_white++;
            }
            if (count_black == 4) {
                end('黑子赢了');
                return true;
            } else if (count_white == 4) {
                end('白子赢了');
                return true;
            }
        }
    }
    for (var i = 0; i < 15; i++) {
        for (var j = 0; j < 15; j++) {
            if ((arr[i][j] == 1) && (arr[i][j] == arr[i - 1][j + 1])) {
                count_black++;
                console.log(count_black);
            } else if ((arr[i][j] == 2) && (arr[i][j] == arr[i - 1][j + 1])) {
                count_white++;
            }
            if (count_black == 4) {
                end('黑子赢了');
                return true;
            } else if (count_white == 4) {
                end('白子赢了');
                return true;
            }
        }
    }
    count_black = 0;
    count_white = 0;
}

这就变正常了

由于我很懒,就没做手机的适配


整个project我放在github上了:
https://github.com/wbaigei/JavaScript-WuZiQi


MIT license

使用此开源程序时,请 标明 作者信息:
作者:BaiG,出处:https://blog.csdn.net/yenoxin

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值