柿霖不是林 发表于 2017-3-3 15:17:45

微信小程序游戏类demo:经典扫雷,绘制一张 10*10 的地图



undefined不会玩扫雷

作者:jixiaod
微信小程序这几天很火,9号正式发布,今天19号过了10天,到现在略有降温的趋势。个大厂商对微信小程序的态度很不看好,最激进的要数[罗辑思维],直接下架了自己的[得到APP]。滴滴、京东等APP也只保留了最精简的功能,某些担心过于完善的功能会抢夺APP本身的用户。不过这也印证了小程序的初衷,小而精、用完即走。(并不否认腾讯微信平台确实流氓的事实)PS:墨迹天气也开发了微信小程序版本,并且在1月9号第一时间发布,欢迎使用。作为技术人员,怎能不亲手试试小程序开发呢?扫雷 Minesweeper实现思路:
[*]如果不了解扫雷的游戏规则,请自行 Google
[*]绘制一张 10*10 的地图,并且标注地雷和非地雷,并且需要用数字表示每个点周围地雷的数量
[*]用 mineMap 表示一个点位

[*]mineMap < 0 (代码中 == -1) 初始状态
[*]0 < mineMap < 9 该点周围地雷的数量
[*]mineMap == 9 表示该点是地雷
[*]mineMap > 9 (代码中 == 10)表示该点插旗

如何跑起来?
[*]下载&安装微信小程序开发工具
[*]配置 wechat-app-minesweeper 代码目录到开发工具即可
玩法
[*]需要注意的是,由于没有鼠标右键标记Flag,简单做了 Flag 切换,开启后,方可标记Flag
[*]最初的想法是通过 tap 和 longtap 来区分扫雷和Flag,但是开发工具不能区分这俩个事件,只能作罢







//index.js
//获取应用实例
var app = getApp()

Page({

    data: {
      mineMap: {},
      timesGo: 0,
      minesLeft: 0
    },

    mineMap: {},
    mineMapMapping: {},
    rowCount: 10,
    colCount: 10,
    mineCount: 10,
    minMineCount: 10,
    maxMineCount: 20,
    minesLeft: 0,
    timesGo: 0,
    timeInterval: null,
    flagOn: false,
    flags: 0,
    endOfTheGame: false,
    safeMinesGo: 0,

    onLoad: function() {

      this.setData({
            minesLeft: 0,
            timesGo: 0
      });
      this.drawMineField();
    },

    setGame: function() {

      this.drawMineField();
      this.createMinesMap();
      this.setMinesLeft();
      this.timeGoReset();
      this.timeGoClock();
      this.endOfTheGame = false;
      this.safeMinesGo = 0;
    },

    setMinesLeft: function() {
      this.minesLeft = this.mineCount;
      this.setData({minesLeft: this.minesLeft});
    },

    timeGoClock: function() {
      var self = this;
      this.timeInterval = setInterval(function () {
            // console.log(self.data.timesGo);
            self.timesGo = self.timesGo + 1;
            self.setData({timesGo: self.timesGo});
            
      }, 1000);
    },

    timeGoStop: function() {
   
      clearInterval(this.timeInterval);
    },

    timeGoReset: function() {
      clearInterval(this.timeInterval);
      this.timesGo = 0;
      this.setData({timesGo: this.timesGo});
    },

    createMinesMap: function() {

      var tmpMineMap = {};
      // initalize mine map with 0.
      for (var row = 0; row < this.rowCount; row++) {

            tmpMineMap = [];
            for (var col = 0; col < this.colCount; col++) {

                tmpMineMap = 0;
            }
      }
         //console.log(tmpMineMap);
         
      // laying mines with 9
      this.mineCount = this.rangeRandom(this.minMineCount, this.maxMineCount);

      var tmpCount = this.mineCount;
      //console.log("Mine count: ", tmpCount);
      while (tmpCount > 0) {

            var row = this.rangeRandom(0, this.rowCount - 1);
            var col = this.rangeRandom(0, this.colCount - 1);

            if (tmpMineMap != 9) {

                tmpMineMap = 9;
                tmpCount--;
            }
      }

      // calculate numbers around mines.
      for (var row = 0; row < this.rowCount; row++) {
            for (var col = 0; col < this.colCount; col++) {
                var startRow = row - 1;
                var startCol = col - 1;
                //console.log("check====== r" +startRow +"c"+startCol );
                for (var r = row-1; r < row+2; r++) {
                  for (var c = col-1; c < col+2; c++) {
                        //console.log("go: r"+r+":c"+c);
                        if (c >= 0 && c < this.colCount
                            && r >= 0 && r < this.rowCount
                        && !(r === row && c === col)
                        && tmpMineMap == 9
                        && tmpMineMap != 9) {
                            tmpMineMap++;
                        }
                  }
                }
            }
      }
      this.mineMapMapping = tmpMineMap;
    },

    drawMineField: function() {

      var tmpMineMap = {};
      for (var row = 0; row < this.rowCount; row++) {

            tmpMineMap = [];
            for (var col = 0; col < this.colCount; col++) {

                tmpMineMap = -1;
            }
      }
      this.mineMap = tmpMineMap;
      //console.log(this.mineMap);

      this.setData({
            mineMap: this.mineMap
      })

    },

    demining: function(event) {

      if (JSON.stringify(this.mineMapMapping) == "{}") return;


      var x = parseInt(event.target.dataset.x);
      var y = parseInt(event.target.dataset.y);
      var value = parseInt(event.target.dataset.value);
      //console.log("value:" + value +" x:"+x +" y:"+y);

      //flag this field as mine.
      if (this.flagOn) {

            this.flag(x, y, value);
            return;
      }

      // if field has been opened, return.
      if (value > 0) return;
         
      var valueMapping = this.mineMapMapping;
      //console.log(this.mineMapMapping);
      //console.log(valueMapping);

      if (valueMapping < 9) {
            this.mineMap = valueMapping;
            this.setData({mineMap: this.mineMap});
            this.safeMinesGo++;
            console.log("Safe mine go: " + this.safeMinesGo);
            if ((this.safeMinesGo + this.mineCount) == (this.rowCount * this.colCount)) {
                this.success();
            }
      }

      // When digg the mine.
      if (valueMapping == 9) {
            this.failed();
      }

      // Open the fields with 0 mines arround.
      if (valueMapping == 0) {

            this.openZeroArround(x, y);
            this.setData({mineMap:this.mineMap});
      }
    },

    success: function() {

      wx.showToast({
            title: 'GOOD!',
            duration: 3000
      })
      this.timeGoStop();
      this.endOfTheGame = true;
    },

    failed: function() {
      wx.showToast({
            title: 'SORRY!',
            duration: 3000
      })

      this.showAll();
      this.timeGoStop();
      this.endOfTheGame = true;
    },

    // Open the fields arround 0 field recursively.
    openZeroArround: function(row, col) {
      //console.log("click" + row + " " + col)
      for (var r = (row-1); r < (row+2); r++) {
            for (var c = (col-1); c < (col+2); c++) {
                //console.log("go: r"+r+":c"+c);
                if (r >= 0 && r < this.rowCount
                  && c >= 0 && c < this.colCount
                && !(r === row && c === col)
                && this.mineMap < 0) {

                  this.mineMap = this.mineMapMapping;
                  this.safeMinesGo++;

                  if (this.mineMapMapping == 0) {
                        this.openZeroArround(r, c);
                  }

                }
            }
      }
      console.log("Safe mine go: " + this.safeMinesGo);
      if ((this.safeMinesGo + this.mineCount) == (this.rowCount * this.colCount)) {
            this.success();
      }

    },

    flagSwitch: function(e) {

      if (e.detail.value) {

            this.flagOn = true;
      } else {

            this.flagOn = false;
      }
    },

    flag: function(x, y, value) {

      if (value > 0 && value < 10) return;

      // if flaged already, set the original state.
      if (value == 10) {

            this.pullUpFlag(x, y);
            return;
      }

      if (this.minesLeft <= 0) return;

      this.minesLeft = this.minesLeft - 1;
      this.mineMap = 10;

      this.setData({mineMap: this.mineMap, minesLeft: this.minesLeft});
    },

    pullUpFlag: function(x, y) {

      if (this.minesLeft < this.mineCount) {
            this.minesLeft = this.minesLeft + 1;
      }
      this.mineMap = -1;
      this.setData({mineMap: this.mineMap, minesLeft: this.minesLeft});
    },

    rangeRandom: function(x, y) {
      var z = y - x + 1;
      return Math.floor(Math.random() * z + x);
    },

    showAll: function() {
      this.mineMap = this.mineMapMapping;
      this.setData({mineMap: this.mineMap});
    }

});


**** Hidden Message *****

123123123qwe 发表于 2018-3-1 16:18:40

正需要,支持楼主大人了!

TMD 发表于 2018-11-23 17:17:26

谢谢楼主的分享

人称活力小猛男 发表于 2019-3-31 15:49:53

十分感谢楼主的分享,课程作业很需要参照。

xbzrwlan 发表于 2019-4-15 10:19:16

参考一下

t.瞳似 发表于 2019-7-4 15:03:03

999999999999999999999999999999

仍然给 发表于 2019-7-11 15:29:47

999999999999999999999999999999

sheerly 发表于 2019-8-3 22:30:31

:handshake

772534272 发表于 2019-8-23 08:59:29

谢谢分享!

放声大哭发 发表于 2019-12-17 10:57:49

粗放预估i后的一天
页: [1] 2
查看完整版本: 微信小程序游戏类demo:经典扫雷,绘制一张 10*10 的地图