先给出问题,然后一步一步的去解决;
这个问题是怎么显示一个棋盘,是一个渲染问题,渲染这个词不是什么很高级的词,对于网页来说,我想到两种办法,一个是直接一个棋盘图片,另一个是canvas,canvas是个html标签,它在DOM中的对象有很多画图属性,他是一个块级标签,如果用这个就是直接取坐标绘画,我上学期做的MFC版的五子棋就是这个办法,我这次用的是背景图片,比较简单,直接绘图版的我有用MFC做过一个,我也写了实验报告,想参考的同学可以看一下,我把连接给出来:MFC版五子棋;
现在进入正题,用一个图片来显示五子棋’
‘就用这个来作为一个棋盘它的css是’’’#qipan {
/*棋盘的大小格式*/
width: 500px;
height: 500px;
background: url(../imgs/board.jpg);
background-size: cover;
margin-left: 30%;
padding-left: 4px;
padding-top: 4px;
}
这样就画出了一个棋盘;第一步OK
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tIZ3JBXR-1593344020745)(csdn/board.jpg)]
怎么显示棋子呢;和点一下出现一个棋子
首先先根据图片棋盘的大小,15*15d大小,它的大小是500px,在css中有设置,所以每一个棋子的大小是500px/(15+1)=31;这里加1是为了让两个棋子间有空隙
下面是创造15*15=225个’
‘’’
for (var i = 1; i <= 15 * this.qipannum; i++) { //创建div,这个是1是为了计算行列值方便
var a = document.createElement("div");
a.setAttribute("data", i);
a.className = "qizi";
document.getElementById('qipan').appendChild(a); //把div放进棋盘div里
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-EifpxUYO-1593344020747)(csdn/qizi.png)]
这样就显示了15*15个棋子,从左到右,从上到下,每一个棋子都有一个id数值序号,这样五子棋就做好了,但是一开始肯定是不显示的,点击一下才会显示,所以它的css属性初始为’’’
.qizi {
/*棋子的大小格式*/
width: 30.5px;
height: 30.5px;
margin: 1.2px;
display: inline-block;
border-radius: 50%;
/*初始状态如果不设置背景属性就是空白的,不显示*/
}
现在这些棋子一开始都不显示,我们为每一个div都添加一个事件处理函数,点击一下就改变一下这个div的css属性,关键代码是:’’’
var y = _this.location(ev).y,
x = _this.location(ev).x;
if (_this.data[y][x].qizicontion == 0) {
if (_this.role == 0) //白棋
{
target.style.background = 'aliceblue'; //让这个棋子的颜色显示出来
_this.role = 1;
_this.data[y][x].qizicontion = 1; //表示白色
} else {
target.style.background = 'black';
_this.role = 0;
_this.data[y][x].qizicontion = 2; //表示黑色
}
上面的代码中有一个location函数,这个函数是取一个div的坐标的函数,它的代码是’’’
xuanran.prototype.location = function(ev) { //给出div的dom对象,判断出这个div的x,y坐标。行列都取决于这个
var _this = this; //这个必须要设置,在别的函数调用该函数的时候,_this还是指向的对象
var target = ev.target;
var data = target.getAttribute('data'); //获取到第N个div
var y = Math.ceil(data / 15); //表示第y行
var x = (data % 15); //表示列
if (x == 0) x = 15;
return { y: y - 1, x: x - 1 }; //返回一个json,包括div的x,y坐标
}
现在,棋子问题也解决了OK,会出现下面这个效果
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9pzyu9mJ-1593344020749)(csdn/qizi2.png)]
上面的location函数,可以获取到每一个div棋子的x,y行竖直坐标,那为何我们不设置一个二维数组来储存它的属性呢?
‘’’
xuanran.prototype.initshuzu = function() { //初始化数组
var _this = this;
for (var i = 0; i < 15; i++) { //每一行y
_this.data[i] = new Array();
for (var ii = 0; ii < 15; ii++) { //每一列x
_this.data[i][ii] = { qizicontion: 0 }
} //每个元素代表一个棋子,0是没有下棋,1是白棋,2是黑棋
}
}
这个函数,就是初始化数组函数,它会令这个数组,初始化,每一个数组元素保存的都是一个json状态变量。表示棋子的状态
怎么在某个方向上判断输赢,上下,左右,正斜,反斜;
先设置两个变量作为棋子在某一行的连在一起的数量。
设置两个嵌套的for循环,一个代表列,一个代表行,用于遍历数组
对一行的遍历,直接用逻辑表达式判断是否有五个状态变量qizicontion是否五个连在一起都一样,如果一样就令响应的白或者黑变量,设置为5
遍历的算法有很多,我这个和之前的MFC版的也不同,怎么样都行,如果你想不到什么好的办法,就用我这个,细节我在源码的注释中写的很清楚了,不做太多解释了,请看源码
‘’’
xuanran.prototype.panduanshuying = function() { //判断输赢
var _this = this;
var bai = 1,
hei = 1; //初始临时变量
//先竖直判断
for (var i = 0; i < _this.qipannum; i++) { //列
for (var q = 0; q < _this.qipannum - 4; q++) { //行遍历量,放第二级,减4最后留出五个做判断
if (_this.data[q][i].qizicontion == 1 && _this.data[q + 1][i].qizicontion == 1 &&
_this.data[q + 2][i].qizicontion == 1 && _this.data[q + 3][i].qizicontion == 1 && _this.data[q + 4][i].qizicontion == 1) { //直接判断有没有连续的五个在一起
bai = 5;
}
if (_this.data[q][i].qizicontion == 2 && _this.data[q + 1][i].qizicontion == 2 && _this.data[q + 2][i].qizicontion == 2 &&
_this.data[q + 3][i].qizicontion == 2 && _this.data[q + 4][i].qizicontion == 2) {
hei = 5;
}
}
}
//判断竖直
for (var i = 0; i < _this.qipannum; i++) { //行遍历量
for (var q = 0; q < _this.qipannum - 4; q++) { //列
if (_this.data[i][q].qizicontion == 1 && _this.data[i][q + 1].qizicontion == 1 &&
_this.data[i][q + 2].qizicontion == 1 && _this.data[i][q + 3].qizicontion == 1 && _this.data[i][q + 4].qizicontion == 1) { //直接判断有没有连续的五个在一起
bai = 5;
}
if (_this.data[i][q].qizicontion == 2 && _this.data[i][q + 1].qizicontion == 2 && _this.data[i][q + 2].qizicontion == 2 &&
_this.data[i][q + 3].qizicontion == 2 && _this.data[i][q + 4].qizicontion == 2) {
hei = 5;
}
}
}
//右上斜
for (var i = 4; i < _this.qipannum; i++) { //起始的行,从上往下,从第4行开始这个斜行才有五个棋子,
//行是先最大,后小。列是先最小,再最大
for (var hang = i, lie = 0; hang >= 0 + 4, lie < i - 3; hang--, lie++) {
if (_this.data[hang][lie].qizicontion == 1 && _this.data[hang - 1][lie + 1].qizicontion == 1 && _this.data[hang - 2][lie + 2].qizicontion == 1 &&
_this.data[hang - 3][lie + 3].qizicontion == 1 && _this.data[hang - 4][lie + 4].qizicontion == 1)
bai = 5;
if (_this.data[hang][lie].qizicontion == 2 && _this.data[hang - 1][lie + 1].qizicontion == 2 && _this.data[hang - 2][lie + 2].qizicontion == 2 &&
_this.data[hang - 3][lie + 3].qizicontion == 2 && _this.data[hang - 4][lie + 4].qizicontion == 2)
hei = 5;
};
//上面是上部分,下面是下部分
for (var hang = i - 4, lie = _this.qipannum - 1; hang < _this.qipannum - 4; hang++, lie--) {
if (_this.data[hang][lie].qizicontion == 1 && _this.data[hang + 1][lie - 1].qizicontion == 1 && _this.data[hang + 2][lie - 2].qizicontion == 1 &&
_this.data[hang + 3][lie - 3].qizicontion == 1 && _this.data[hang + 4][lie - 4].qizicontion == 1)
bai = 5;
if (_this.data[hang][lie].qizicontion == 2 && _this.data[hang + 1][lie - 1].qizicontion == 2 && _this.data[hang + 2][lie - 2].qizicontion == 2 &&
_this.data[hang + 3][lie - 3].qizicontion == 2 && _this.data[hang + 4][lie - 4].qizicontion == 2)
hei = 5;
}
}
//右下斜
for (var i = 0; i < _this.qipannum - 4; i++) //起始的行
{
for (var hang = i, lie = 0; hang < _this.qipannum - 4, lie < 14 - i - 3; hang++, lie++) {
if (_this.data[hang][lie].qizicontion == 1 && _this.data[hang + 1][lie + 1].qizicontion == 1 && _this.data[hang + 2][lie + 2].qizicontion == 1 &&
_this.data[hang + 3][lie + 3].qizicontion == 1 && _this.data[hang + 4][lie + 4].qizicontion == 1)
bai = 5;
if (_this.data[hang][lie].qizicontion == 2 && _this.data[hang + 1][lie + 1].qizicontion == 2 && _this.data[hang + 2][lie + 2].qizicontion == 2 &&
_this.data[hang + 3][lie + 3].qizicontion == 2 && _this.data[hang + 4][lie + 4].qizicontion == 2)
bai = 5;
}
for (var hang = i + 4, lie = _this.qipannum - 1; hang > 3; hang--, lie--) {
if (_this.data[hang][lie].qizicontion == 1 && _this.data[hang - 1][lie - 1].qizicontion == 1 && _this.data[hang - 2][lie - 2].qizicontion == 1 &&
_this.data[hang - 3][lie - 3].qizicontion == 1 && _this.data[hang - 4][lie - 4].qizicontion == 1)
bai = 5;
if (_this.data[hang][lie].qizicontion == 2 && _this.data[hang - 1][lie - 1].qizicontion == 2 && _this.data[hang - 2][lie - 2].qizicontion == 2 &&
_this.data[hang - 3][lie - 3].qizicontion == 2 && _this.data[hang - 4][lie - 4].qizicontion == 2)
hei = 5;
}
}
// if (_this.data[0][0].qizicontion != 0 && _this.data[1][0].qizicontion != 0) bai = 5;
//后判断
if (bai == 5) {
_this.stutus = 1;
_this.showend();
}
if (hei == 5) {
_this.stutus = 2;
_this.showend();
}
}
bai = 5;
//后判断
if (bai == 5) {
_this.stutus = 1;
_this.showend();
}
if (hei == 5) {
_this.stutus = 2;
_this.showend();
}
}
### 到这里,一个五子棋就算做完了