简易五子棋判断及棋盘制作
由于本人对五子棋不是特别熟悉,就勉强自己做了个。
有什么做错了就请多包含或在评论区指正
© 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前:
加入style后:
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
当格子被按下:
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;
Bug 解决
这样算赢。。。
每两颗子连在一起,就 +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])
这样的话就不会发生刚刚的情况了
其他几个也是一样的改改
改完之后的 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