text: // var direction = { x: 1024, y: 1024 };
  let left = { x: 0, y: -1 };
  let right = { x: 0, y: 1 };
  let up = { x: -1, y: 0 };
  let down = { x: 1, y: 0 };
  isInBoard = function(i, j) {
      return (i < 4 && i >= 0 && j < 4 && j >= 0);
  };
  var game = {
      $score: $('.score-value'),
      $cell: [],
      notEmpty: 0,
      init: function() {
          this.$score.text('0');
          this.notEmpty = 0;
          $row = $('.row');
          for (var i = 0; i < 4; i++) {
              this.$cell.push([]);
              for (var j = 0; j < 4; j++) {
                  this.$cell[i].push($row.eq(i).children().eq(j));
                  this.$cell[i][j].text("");
              }
          }
          this.notEmpty++;
          this.createNumber();
          this.createNumber();
      },
  
      move: function(direction) {
          // left || up 正向遍历
          if (direction.x + direction.y == -1) {
              for (i = 0; i < 4; i++) {
                  for (j = 0; j < 4; j++) {
                      if (this.$cell[i][j].text()) {
                          this.elementMove(i, j, direction);
                      }
                  }
              }
          } else {
              for (i = 3; i >= 0; i--) {
                  for (j = 3; j >= 0; j--) {
                      if (this.$cell[i][j].text()) {
                          this.elementMove(i, j, direction);
                      }
                  }
              }
          }
      },
      changeStyle: function(x, y) {
          if (this.$cell[x][y].text().length == 3) {
              this.$cell[x][y].css("font-size", "53px");
          } else if (this.$cell[x][y].text().length == 4) {
              this.$cell[y][x].css("font-size", "32px");
          }
      },
      elementMove: function(x, y, direction) {
          nextX = x + direction.x;
          nextY = y + direction.y;
          if (isInBoard(nextX, nextY)) {
              this.changeStyle(x, y);
              if (!this.$cell[nextX][nextY].text()) {
                  this.$cell[nextX][nextY].text(this.$cell[x][y].text());
                  this.$cell[x][y].text("");
                  this.elementMove(nextX, nextY, direction);
              } else if (this.$cell[nextX][nextY].text() === this.$cell[x][y].text() && this.$cell[x][y].text()) {
                  this.$score.text(this.$score.text() * 1 + 1 * this.$cell[x][y].text());
                  this.$cell[nextX][nextY].text(this.$cell[x][y].text() * 2);
                  this.$cell[x][y].text("");
                  this.notEmpty--;
              }
              this.elementMove(nextX, nextY, direction);
          }
      },
      isGameOver: function() {
          fla = true;
          for (var i = 0; fla && i < 4; i++) {
              for (var j = 0; fla && j < 3; j++) {
                  fla = this.$cell[i][j].text() != this.$cell[i][j + 1].text();
              }
          }
          for (var i = 0; fla && i < 3; i++) {
              for (var j = 0; fla && j < 4; j++) {
                  fla = this.$cell[i][j].text() != this.$cell[i + 1][j].text();
              }
          }
          fla ? console.log("gameOver") : console.log("you can still run it");
          return fla;
      },
      gameOver: function() {
          setTimeout(function() {
              $('.game-over').slideDown();
          }, 1);
      },
      createNumber: function() {
          value = Math.floor(2 * Math.random()) == 1 ? 4 : 2;
          which = Math.floor(Math.random() * 16);
          row = Math.floor(which / 4);
          col = which % 4;
          if (!this.$cell[row][col].text()) {
              this.$cell[row][col].text(value);
              this.notEmpty++;
          } else {
              this.createNumber();
          }
      },
  };
  $(document).ready(function() {
      game.init();
      $("body").on('keyup', function(e) {
          switch (e.keyCode) {
              case 38:
              case 87:
                  direction = up;
                  break;
              case 40:
              case 83:
                  direction = down;
                  break;
              case 37:
              case 65:
                  direction = left;
                  break;
              case 39:
              case 68:
                  direction = right;
                  break;
              default:
                  direction = false;
                  break;
          }
          if (direction) {
              console.log(game.notEmpty);
              if (game.notEmpty === 16 && game.isGameOver()) {
                  game.gameOver();
              }
              game.move(direction);
              if (game.notEmpty < 16) {
                  game.notEmpty++;
                  game.createNumber();
              }
          }
      });
      $('.new-game').on('click', function() {
          game.init();
          $('.game-over').hide();
      });
      touchMove($('body')[0]);
  });
  
  function touchMove(el, options) {
      var isMove = false;
      var startX = 0;
      var startY = 0;
  
      //设置指针距离元素的边框的距离
      var disX = 0;
      var disY = 0;
      // 如果用户未传入参数2，自己定义一个
      var data = {
          swipeLeft: function() {},
          swipeRight: function() {},
          swipeDown: function() {},
          swipeUp: function() {},
          drag: function() {}
      }
  
      // 判断是否传入参数2，有的话覆盖默认值
      Object.assign(data, options);
      // 给元素绑定三个事件
      el.addEventListener('touchstart', function(e) {
          //获取手指开始的坐标
          startX = e.touches[0].pageX;
          startY = e.touches[0].pageY;
          //计算指针距离元素边框的位置
          disX = startX - el.offsetLeft;
          disY = startY - el.offsetTop;
      });
      el.addEventListener('touchmove', function(e) {
          //如果触发了move事件，打开开关
          isMove = true;
          // 获取移动时的坐标
          moveX = e.touches[0].pageX;
          moveY = e.touches[0].pageY;
          e.mation = {
                  startX: startX,
                  startY: startY,
                  moveX: moveX,
                  moveY: moveY,
                  disX: disX,
                  disY: disY
              }
              // data.drag.call(el, e);
      });
      el.addEventListener('touchend', function(e) {
          // 判断是否触发了move事件
          if (isMove) {
              // 计算水平边长
              var absX = Math.abs(moveX - startX);
              // 计算垂直边长
              var absY = Math.abs(moveY - startY);
              // 判断垂直还是水平滑动
              if (absX > absY) {
                  // console.log('水平滑动');
                  //再判断是左滑右滑
                  if (moveX - startX > 0) {
                      game.move(right);
                  } else {
                      game.move(left);
                  }
              } else {
                  //判断是上滑还是下滑
                  if (moveY - startY > 0) {
                      game.move(down);
                  } else {
                      game.move(up);
                  }
              }
              if (game.notEmpty < 16) {
                  game.notEmpty++;
                  game.createNumber();
              }
          }
          isMove = false;
      });
  };