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

微信小程序五子棋游戏的棋盘,重置,对弈实现方法【附demo源码下载】

程序员文章站 2023-12-05 23:17:52
本文实例讲述了微信小程序五子棋游戏的棋盘,重置,对弈实现方法。分享给大家供大家参考,具体如下: demo下载 五子棋对弈、悔棋demo 效果图 分析 1. 采...

本文实例讲述了微信小程序五子棋游戏的棋盘,重置,对弈实现方法。分享给大家供大家参考,具体如下:

demo下载

五子棋对弈、悔棋demo

效果图

微信小程序五子棋游戏的棋盘,重置,对弈实现方法【附demo源码下载】

分析

1. 采用微信小程序的canvas制作五子棋;
2. 确定棋盘大小及格数;
3. 绘制棋盘—-通过棋盘宽高和格数计算间距,同时保存坐标点;
4. 黑方和白方下子—-定义一个布尔变量代表各自的身份;
5. 重置棋盘—-重新开始;
6. 通过判断当前棋手,悔棋时进行改变。

绘制棋盘

drawline(arr){
 arr.foreach(current => {
  this.ctx.setfillstyle(this.linecolor);
  this.ctx.beginpath();
  this.ctx.linewidth = 1;
  this.ctx.moveto(current[0].x, current[0].y);
  for (var i = 1; i < current.length; i++) {
  this.ctx.lineto(current[i].x, current[i].y);
  }
  this.ctx.stroke();
  this.ctx.closepath();
  this.ctx.draw(true);
 });
 }
 drawchessboard(){
 // 每个格子的宽高
 var everylen = this.everylen;
 // 标记坐标的个数
 var count = 0;
 // 从纵向保存坐标
 var arry = [];
 // 双循环计算每个坐标的横纵坐标
 for(var i = 0;i <= this.type; i++){
  var arr = [],arr0 = [];
  for(var j = 0;j <= this.type; j++){
  count++;
  arr.push({
   y: this.margin + i * everylen,
   x: this.margin + j * everylen,
   pointx: j,
   pointy: i,
   index: count
  });
  arr0.push({
   x: this.margin + i * everylen,
   y: this.margin + j * everylen
  })
  }
  // 清空canvas
  this.ctx.clearrect(0, 0, this.width, this.height);
  // 保存横线坐标和竖线坐标
  this.everypoint.push(arr);
  arry.push(arr0);
 }
 // 绘制横向线
 this.drawline(this.everypoint);
 // 绘制竖向线
 this.drawline(arry);
 }

绘制当前点击坐标的棋子

// 获取当前点击位置的坐标
 getposition(e){
 return {
  x: e.touches[0].x,
  y: e.touches[0].y
 };
 }
 // 将当前坐标和棋盘坐标数组对比,找到精确坐标
 checkpoint(arr,po){
 for (var i = 0; i < this.everypoint.length; i++){
  for (var j = 0; j < this.everypoint[i].length; j++){
  if (math.abs(this.everypoint[i][j].x - po.x) < this.everylen/2 && math.abs(this.everypoint[i][j].y - po.y) < this.everylen/2){
   // 将棋盘精确坐标保存到当前持棋方数组
   arr.push(this.everypoint[i][j]);
   // 同时删除棋盘坐标数组的该值,表示当前位置已经存在棋子
   this.everypoint[i].splice(j,1);
   break;
  }
  }
 }
 }
 // 绘制当前坐标棋子
 drawcle(opts,color){
 this.ctx.setfillstyle(color);
 this.ctx.beginpath();
 this.ctx.arc(opts.x, opts.y, this.r, 0, math.pi * 2, true);
 this.ctx.closepath();
 this.ctx.fill();
 this.ctx.draw(true);
 }
 drawlastpoint(type){
 // 判断是黑方持棋还是白方持棋,进行绘制棋子
 if(type == 'ai'){
  this.aipoint.foreach((current, index) => {
  this.drawcle(current, '#000000');
  });
 }else{
  this.mypoint.foreach((current, index) => {
  this.drawcle(current, '#ffffff');
  });
 }
 }
 this.page.changetouchstart = function (e) {
  // 判断游戏是否开始
  if (self.start_game){
  // 获取当前坐标
  var newpo = self.getposition(e);
  // 获取棋盘精确坐标
  if (!self.boolai && self.boolmy) {
   self.checkpoint(self.mypoint, newpo);
  } else if (self.boolai && !self.boolmy) {
   self.checkpoint(self.aipoint, newpo);
  }
  }
 }
 this.page.changetouchend = function (e) {
  if (self.start_game) {
  // 绘制棋子
  if (!self.boolai && self.boolmy) {
   self.boolai = !self.boolai;
   self.boolmy = !self.boolmy;
   self.drawlastpoint('po');
   // 判断白棋是否五子胜利
   if (self.mypoint.length >= 5 && self.checkwinner(self.mypoint)){
   wx.showtoast({title: '白棋胜利!'});
   self.start_game = false;
   }
  } else if (self.boolai && !self.boolmy) {
   self.boolai = !self.boolai;
   self.boolmy = !self.boolmy;
   self.drawlastpoint('ai');
   // 判断黑棋是否五子胜利
   if(self.aipoint.length >= 5 && self.checkwinner(self.aipoint)){
   wx.showtoast({ title: '黑棋胜利!' });
   self.start_game = false;
   }
  }
  }
 }

五子棋胜利方判断

五子棋胜利就是横向、纵向、45度斜线方向、135度斜线方向连成五个颜色相同的棋子,为了更加清楚的表示,我将四个方向的判断做四个函数处理。

checktransverse(arr,po){//横向检查
 var len = arr.length - 1;
 var count = 1;
 // 东
 for(var i = 1; i < this.chess_len ; i++){
  for (var j = 0; j < len; j++){
  if(arr[j].pointx == po.pointx - i && arr[j].pointy == po.pointy){
   count++;
  }
  }
 }
 if (count == this.chess_len) { return true;}
 // 西
 for (var i = 1; i < this.chess_len; i++) {
  for (var j = 0; j < len; j++) {
  if (arr[j].pointx == po.pointx + i && arr[j].pointy == po.pointy) {
   count++;
  }
  }
 }
 if (count == this.chess_len) { return true; }
 }
 checkportrait(arr,po){//纵向检查
 var len = arr.length - 1;
 var count = 1;
 // 南
 for (var i = 1; i < this.chess_len; i++) {
  for (var j = 0; j < len; j++) {
  if (arr[j].pointx == po.pointx && arr[j].pointy == po.pointy - i) {
   count++;
  }
  }
 }
 if (count == this.chess_len) { return true; }
 // 北
 for (var i = 1; i < this.chess_len; i++) {
  for (var j = 0; j < len; j++) {
  if (arr[j].pointx == po.pointx && arr[j].pointy == po.pointy + i) {
   count++;
  }
  }
 }
 if (count == this.chess_len) { return true; }
 }
 checknortheast(arr,po){//45度
 var len = arr.length - 1;
 var count = 1;
 // 西南
 for (var i = 1; i < this.chess_len; i++) {
  for (var j = 0; j < len; j++) {
  if (arr[j].pointx == po.pointx - i && arr[j].pointy == po.pointy - i) {
   count++;
  }
  }
 }
 if (count == this.chess_len) { return true; }
 // 东北
 for (var i = 1; i < this.chess_len; i++) {
  for (var j = 0; j < len; j++) {
  if (arr[j].pointx == po.pointx + i && arr[j].pointy == po.pointy + i) {
   count++;
  }
  }
 }
 if (count == this.chess_len) { return true; }
 }
 checknorthwest(arr,po){//135度
 var len = arr.length - 1;
 var count = 1;
 // 西北
 for (var i = 1; i < this.chess_len; i++) {
  for (var j = 0; j < len; j++) {
  if (arr[j].pointx == po.pointx - i && arr[j].pointy == po.pointy + i) {
   count++;
  }
  }
 }
 if (count == this.chess_len) { return true; }
 // 东南
 for (var i = 1; i < this.chess_len; i++) {
  for (var j = 0; j < len; j++) {
  if (arr[j].pointx == po.pointx + i && arr[j].pointy == po.pointy - i) {
   count++;
  }
  }
 }
 if (count == this.chess_len) { return true; }
 }
 checkwinner(arr){
 var currentpo = arr[arr.length - 1];
 var win1 = this.checktransverse(arr, currentpo);
 var win2 = this.checkportrait(arr, currentpo);
 var win3 = this.checknortheast(arr, currentpo);
 var win4 = this.checknorthwest(arr, currentpo);
 if (win1 || win2 || win3 || win4){
  return true;
 }else{
  return false;
 }
 }

重置棋盘

resetchessboard(){
 this.page.setdata({ ishide: false });
 this.init();
}
this.page.changereset = function(e){
 self.resetchessboard();
}

注意

1. 绘制棋盘前必须清空canvas,方便最后的重新开始和重置棋盘;
2. 对当前棋子的坐标四个方向的判断,采用的原始坐标而不是计算后的绘制坐标;
3. 在判断持棋人时,各自采用一个值,方便添加悔棋功能。

只是实现了简单的对下五子棋功能,后续添加悔棋、记分、记时等功能!

同时向判断胜利的函数可以合并为一进行优化!

希望本文所述对大家微信小程序开发有所帮助。