前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >微信小程序(游戏)----五子棋(棋盘,重置,对弈)

微信小程序(游戏)----五子棋(棋盘,重置,对弈)

作者头像
Rattenking
发布2021-02-01 11:15:41
1.4K0
发布2021-02-01 11:15:41
举报
文章被收录于专栏:Rattenking

五子棋对弈、悔棋DEMO

效果图

五子棋效果图
五子棋效果图

分析

  1. 采用微信小程序的canvas制作五子棋;
  2. 确定棋盘大小及格数;
  3. 绘制棋盘----通过棋盘宽高和格数计算间距,同时保存坐标点;
  4. 黑方和白方下子----定义一个布尔变量代表各自的身份;
  5. 重置棋盘----重新开始;
  6. 通过判断当前棋手,悔棋时进行改变。
绘制棋盘
代码语言:javascript
复制
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);
  }
绘制当前点击坐标的棋子
代码语言:javascript
复制
// 获取当前点击位置的坐标
  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度斜线方向连成五个颜色相同的棋子,为了更加清楚的表示,我将四个方向的判断做四个函数处理。

代码语言:javascript
复制
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;
    }
  }
重置棋盘
代码语言:javascript
复制
resetChessBoard(){
  this.page.setData({ isHide: false });
  this.init();
}
this.page.changeReset = function(e){
 self.resetChessBoard();
}

注意

  1. 绘制棋盘前必须清空canvas,方便最后的重新开始和重置棋盘;
  2. 对当前棋子的坐标四个方向的判断,采用的原始坐标而不是计算后的绘制坐标;
  3. 在判断持棋人时,各自采用一个值,方便添加悔棋功能。
只是实现了简单的对下五子棋功能,后续添加悔棋、记分、记时等功能!
同时向判断胜利的函数可以合并为一进行优化!

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2018/01/11 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 效果图
  • 分析
    • 绘制棋盘
      • 绘制当前点击坐标的棋子
        • 五子棋胜利方判断
          • 重置棋盘
            • 只是实现了简单的对下五子棋功能,后续添加悔棋、记分、记时等功能!
            • 同时向判断胜利的函数可以合并为一进行优化!
        • 注意
        相关产品与服务
        云开发 CloudBase
        云开发(Tencent CloudBase,TCB)是腾讯云提供的云原生一体化开发环境和工具平台,为200万+企业和开发者提供高可用、自动弹性扩缩的后端云服务,可用于云端一体化开发多种端应用(小程序、公众号、Web 应用等),避免了应用开发过程中繁琐的服务器搭建及运维,开发者可以专注于业务逻辑的实现,开发门槛更低,效率更高。
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档