啊哈,水了这么久的五子棋终于迎来完结的一天了,去除了我得狗蛋ai,所以以下内容之中没有关于ai咋实现的方式,不过我觉得我应该可以讲清楚棋通过query,这个五子我是怎么实现基本功能的qwq
先附上动图两张,在读之前看看是不是你要的亚子,不然浪费你宝贵的时间概不负责。
插件上传地址
怎么绘制棋盘
直接用table-tr-td的结构绘制出来,但是14×14的棋盘是针对边的,所以我们td格子在画的时候是画出来13×13就可以了,在画的同时要把下标记录进去,具体怎么落子看下文
怎么确定坐标与落子的效果
在渲染棋盘的时候,每一个格子我们都让标签记录自己的坐标系(因为要for两次),这样点击的时候我们就可以直接知道这个落子的位置,当然,我们直接这样做会导致最右边与最下边的边线是无法被选中的,所以这个时候我们要在两处进行参数的修正,第一点就是点击td的时候获取的参数要进行修正,通过判断鼠标在当前td点击的位置是否偏向四个角的某一个位置我们对点击的坐标进行1个参数的修正,这样子获取的参数之中就包含了整个棋盘的所有坐标了。
不过渲染的时候我们直接通过查找出对应的td格子把棋子渲染在这个td格子上,然后用absolute定位到左上角的位置达到落子在交线上的效果,不过落子此时并没有做到最右边和最下边的落子,请记住,我们的坐标是14×14的,但是我们的格子实际上是13×13,所以这个时候我们即使有了{x:14:y:14}这个落子坐标,上述的落子效果是完不成这个效果的,所以我就做额外的判断,假若落子的点实在最右边的边线上,那么我把落子画在13的格子里面,然后把棋子的定位挪到右边的边线上,同理另外俩特殊情况也这样操作,那么我们的落子效果就算是达成了。
怎么判断胜负
为了实现这个效果,我么在渲染落子的时候同时要把已落子的坐标计入一个缓存的数组,通过它来实现阻止重复落子与胜负手的判断,五子棋逻辑比较简单,可以直接硬解,我们遍历缓存中的所有坐标点,然后依次判断→,↓,↘,↙ 四个位置同色的坐标是否存在,然后直接给返回结果就行了,js里面是可以直接用find这种类linq的查询方式就行判断的,我之前用for实现完全是在浪费时间。
怎么给结算界面
结算最基础的三个点就是:
代码实现部分,完全体
html部分
<html>
<head>
<meta charset="utf-8">
<title>五子棋实现title>
<script src="js/jquery-3.4.1.min.js">script>
<script src="js/wzqsx.js">script>
<link href="css/wzqsx.css" rel="stylesheet" type="text/css" />
<style>
#div{
border: 1px solid lightgray;
width: 500px;
height: 500px;
position: absolute;
left: 200px;
top: 200px;
}
style>
head>
<body>
<div id="div">div>
body>
html>
<script>
wzqsx("div").load();
script>
css部分
.beijing{
display: flex;
justify-content:center;
align-items:center;
background-color: rgb(247,230,183);
position: absolute;
z-index: 1;
}
.qipan{
width: 92%;
height: 92%;
border-collapse: collapse;
}
.qipan td{
border: 1px solid black;
position: relative;
}
.white{
border: 1px solid lightgray;
border-radius: 50%;
background-color: white;
position: absolute;
z-index: 2;
width: 90%;
height: 90%;
left: -50%;
top: -50%;
color: lightgray;
font-size: 12px;
font-weight: bold;
display: flex;
justify-content: center;
align-items: center;
}
.black{
border: 1px solid lightgray;
border-radius: 50%;
background-color: black;
position: absolute;
z-index: 2;
width: 90%;
height: 90%;
left: -50%;
top: -50%;
color: lightgray;
font-size: 12px;
font-weight: bold;
display: flex;
justify-content: center;
align-items: center;
}
.win{
border: 1px solid red;
box-shadow: 0 0 3px 2px red;
}
js部分,打了很多注释
var wzqsx = function(div) {
var $obj = $("#" + div); //目标容器
$obj.addClass("beijing") //给目标容器增加需要的样式
$qipan = $("
") //渲染table表作为棋盘
$qipan.appendTo($obj) //添加进目标容器
for (var i = 0; i < 14; i++) {
//绘制14×14的棋盘格子,并且把下标标进去以便后面有用
var $row = $(" ")
for (var j = 0; j < 14; j++) {
var $line = $(" ")
$line.appendTo($row);
}
$row.appendTo($qipan);
}
return {
$obj: $obj, //缓存容器
$arrs: [], //缓存棋子数据
$qipan: $qipan, //缓存棋盘
$action: true, //是否正在游戏中
$now: 'white', //当前落子方
load: function() {
var that = this; //作用域
var tdw = that.$obj.width() * 0.92 / 14; //每个格子边长
that.$qipan.find("td").click(function(e) {
//某个td被点击之后,判断点击的位置距离这个td的四个角哪个角最近然后就视为落子点,再进行落子操作
var temp = Object.assign({
}, $(this)[0].dataset) //获取
var f1 = e.offsetX > tdw / 2;
var f2 = e.offsetY > tdw / 2; //定位落子的位置是在四个角的哪一个
var index = {
//生成点击的坐标点
x: f1 ? parseInt(temp.line) + 1 : parseInt(temp.line),
y: f2 ? parseInt(temp.row) + 1 : parseInt(temp.row),
c: that.$now
}
//把坐标点给到落子实现
that.luozi(index);
})
},
luozi: function(index) {
var that = this;
if (that.exist(index) && that.$action) {
that.$arrs.push(index)
var $qizi = $("")
if(index.x<14&&index.y<14){
$qizi.appendTo($obj.find("td[data-row='" + index.y + "']td[data-line='" + index.x + "']"))
}
if(index.x==14&&index.y<14){
$qizi.appendTo($obj.find("td[data-row='" + index.y + "']td[data-line='" + 13 + "']"))
$qizi.css({
"left":"50%"})
}
if(index.x<14&&index.y==14){
$qizi.appendTo($obj.find("td[data-row='" + 13 + "']td[data-line='" + index.x + "']"))
$qizi.css({
"top":"50%"})
}
if(index.x==14&&index.y==14){
$qizi.appendTo($obj.find("td[data-row='" + 13 + "']td[data-line='" + 13 + "']"))
$qizi.css({
"top":"50%","left":"50%"})
}
that.$now = that.$now == "white" ? "black" : "white";
}
//落子之后进入胜负检查
that.check();
},
exist: function(t) {
//检查该坐标是否可以落子
var temp = this.$arrs.find(n=>n.x==t.x&&n.y==t.y);
var flag = temp==undefined?true:false;
return flag;
},
check:function(){
//检查当前棋盘中是否有获胜的棋子出现,符合条件的话就进入结算界面
var that =this;
for(var i = 0;i<that.$arrs.length;i++){
var t = that.$arrs[i];
//检查横的→
var t2 = that.$arrs.find(n=>n.x==t.x+1&&n.y==t.y&&n.c==t.c)
var t3 = that.$arrs.find(n=>n.x==t.x+2&&n.y==t.y&&n.c==t.c)
var t4 = that.$arrs.find(n=>n.x==t.x+3&&n.y==t.y&&n.c==t.c)
var t5 = that.$arrs.find(n=>n.x==t.x+4&&n.y==t.y&&n.c==t.c)
if(t2&&t3&&t4&&t5){
that.end(t,t2,t3,t4,t5)
}
//检查竖的↓
var t2 = that.$arrs.find(n=>n.x==t.x&&n.y==t.y+1&&n.c==t.c)
var t3 = that.$arrs.find(n=>n.x==t.x&&n.y==t.y+2&&n.c==t.c)
var t4 = that.$arrs.find(n=>n.x==t.x&&n.y==t.y+3&&n.c==t.c)
var t5 = that.$arrs.find(n=>n.x==t.x&&n.y==t.y+4&&n.c==t.c)
if(t2&&t3&&t4&&t5){
that.end(t,t2,t3,t4,t5)
}
//检查斜的1↘
var t2 = that.$arrs.find(n=>n.x==t.x+1&&n.y==t.y+1&&n.c==t.c)
var t3 = that.$arrs.find(n=>n.x==t.x+2&&n.y==t.y+2&&n.c==t.c)
var t4 = that.$arrs.find(n=>n.x==t.x+3&&n.y==t.y+3&&n.c==t.c)
var t5 = that.$arrs.find(n=>n.x==t.x+4&&n.y==t.y+4&&n.c==t.c)
if(t2&&t3&&t4&&t5){
that.end(t,t2,t3,t4,t5)
}
//检查斜的2↙
var t2 = that.$arrs.find(n=>n.x==t.x-1&&n.y==t.y+1&&n.c==t.c)
var t3 = that.$arrs.find(n=>n.x==t.x-2&&n.y==t.y+2&&n.c==t.c)
var t4 = that.$arrs.find(n=>n.x==t.x-3&&n.y==t.y+3&&n.c==t.c)
var t5 = that.$arrs.find(n=>n.x==t.x-4&&n.y==t.y+4&&n.c==t.c)
if(t2&&t3&&t4&&t5){
that.end(t,t2,t3,t4,t5)
}
}
},
end:function(){
//结算界面,展示所有棋子的状况,并且此时允许点击询问是否重开
var that = this;
if(that.$action){
that.$action=false;
//首先把所有棋子的先后顺序全部标出来
for(var i = 0;i<that.$arrs.length;i++){
var t = that.$arrs[i];
that.$qipan.find("div[data-row='"+t.y+"']div[data-line='"+t.x+"']").html(i+1)
}
//然后把获胜的那五个棋子标记出来
console.log(arguments)
for(var i = 0;i<arguments.length;i++){
var t = arguments[i];
that.$qipan.find("div[data-row='"+t.y+"']div[data-line='"+t.x+"']").addClass("win")
}
that.$qipan.find("td").click(function(){
if(that.$action==false&&confirm("是否重开?")){
that.reload();
}
})
}
},
reload:function(){
//重开
var that = this;
that.$arrs=[];
that.$qipan.find(".white,.black").remove();//把所有落子清空
that.$now="white";
that.$action=true;
}
}
}