【问题标题】:Javascript - Connect Four game validationJavascript - 连接四游戏验证
【发布时间】:2015-12-13 02:48:08
【问题描述】:

我有以下测试多维数组,它反映了标准四连接游戏板:

var board = [['-','-','-','-','-','-','-'],
             ['-','-','-','-','-','-','-'],
             ['-','-','-','R','R','R','R'],
             ['-','-','-','Y','Y','R','Y'],
             ['-','-','-','Y','R','Y','Y'],
             ['-','-','Y','Y','R','R','R']];

我正在编写一个 js 验证,它检查板阵列中的每个元素是否有 4 种匹配,无论是横向、向下还是对角线。查看上面的测试板,我的验证器应该返回 R 作为正确答案,因为第三行中有 4 个 R 元素的连接匹配。这是我的代码:

function fourTogether(a,b,c,d) {
   return (a != '-') && (a == b) && (a == c) && (a == d);
}

function connectFour(board) {
  // check RIGHT
   for (row=col=0; row<3 && col<7; row++, col++) {
       if (fourTogether(board[row][col], board[row+1][col], board[row+2][col], board[row+3][col])) {
         return board[row][col];
       }
     } 
    //  check DOWN    
   for (row=col= 0; row<6 && col<4; row++, col++) {
       if (fourTogether(board[row][col], board[row][col+1], board[row][col+2], board[row][col+3])) {
         return board[row][col];
       }
     }    
    //  check DIAGONAL to RIGHT
   for (row=col=0; row<3 && col<4; row++, col++) {
       if (fourTogether(board[row][col], board[row+1][col+1], board[row+2][col+2], board[row+3][col+3])) {
          return board[row][col];
       }
     }
    //  check DIAGONAL to LEFT
   for (row=3, col=0; row<6 && col<4; row++, col++) {
       if (fourTogether(board[row][col], board[row-1][col+1], board[row-2][col+2], board[row-3][col+3])) {
         return board[row][col];
       }
     }
   return board.indexOf('-') > -1 ? 'in progress' : 'draw';
}

所以我基本上使用 fourTogether 函数来建立 4-of-a-kind 匹配并省略 '-' 元素(代表未填充的板槽)。然后在connectFour 函数中,我使用四个不同的FOR 循环根据检查的方向遍历整个数组,然后我添加了一个IF 语句来检查fourTogether 函数对递增的板元素。最后,最后有一个三元语句,如果棋盘中没有 4 种匹配,则应该返回“平局”或“游戏进行中”,这取决于空的 '-' 棋盘槽的存在。不幸的是,我返回undefined,我对代码具体在哪里失败感到有点茫然。任何帮助或指点将不胜感激。

【问题讨论】:

  • SyntaxError: Unexpected token return(…),将return 移到函数末尾的三元运算符前面。另外,fourTogether 没有返回语句
  • 我很确定那些 for 循环并没有达到你的预期。
  • 感谢保罗。我的fourTogether中有return语句,这里我错误地省略了。我已经进行了相应的编辑。

标签: javascript


【解决方案1】:

for 循环,例如:

for (row=col=0; row<3 && col<7; row++, col++) {

将遍历(0,0),(1,1),(2,2)。你想要的是(0,0),(0,1),(0,2),...,(1,0),(1,1),(1,2),...。为此,您必须使用嵌套循环:

for (row = 0; row<3; row++) {
    for (col = 0; col<7; col++) {
        // do that check
    }
}

【讨论】:

  • 谢谢。我想我试图在一个for 语句中同时包含特定于行和列的循环,这太过分了。也感谢您展示了在这两种情况下将迭代的确切内容。
【解决方案2】:

如果需要,使用两个嵌套循环并检查四个方向中的每一个。

var board = [['-','-','-','-','-','-','-'],
             ['-','-','-','-','-','-','-'],
             ['-','-','-','R','R','R','R'],
             ['-','-','-','Y','Y','R','Y'],
             ['-','-','-','Y','R','Y','Y'],
             ['-','-','Y','Y','R','R','R']];

function fourTogether(a,b,c,d) {
   return (a != '-') && (a == b) && (a == c) && (a == d);
}

function connectFour(board) {
  var bl = board.length, bw = board[0].length;

  // loop through the whole board once not a bunch of times
  for (var row = 0; row < bl; row++) {
    for (var col = 0; col < bw; col++) {
      var sq = board[row][col];
      
      // check right if we have to
      if (col < bw - 3 &&
          fourTogether(sq, board[row][col+1], board[row][col+2], board[row][col+3])) {
        return sq;
      }
      // check down if we have to
      if (row < bl - 3 &&
          fourTogether(sq, board[row+1][col], board[row+2][col], board[row+3][col])) {
        return sq;
      }
      // down right
      if (row < bl - 3 && col < bw - 3 &&
          fourTogether(sq, board[row+1][col+1], board[row+2][col+2], board[row+3][col+3])) {
        return sq;
      }
      // down left
      if (row < bl - 3 && col > 2 && 
          fourTogether(sq, board[row+1][col-1], board[row+2][col-2], board[row+3][col-3])) {
        return sq;
      }
    }      
  } 
  //board.indexOf('-') > -1 ? return 'in progress' : return 'draw'; //?????
  return "no winner";
}
alert(connectFour(board));

【讨论】:

  • 非常好的解决方案,并且摆脱了大量不必要的循环
【解决方案3】:

我会以不同的方式解决这个问题..

首先,设置函数以轻松获取要测试的线路

function row(board, i) {
    return board[i].join('');
}
function col(board, j) {
    return board.map(e => e[j]).join('');
}
function diagDown(board, i) {
    return board.map((e, j) => e[i - board.length + j] || '').join('');
}
function diagUp(board, i) {
    return board.slice(0).reverse().map((e, j) => e[i - board.length + j] || '').join('');
}

(如果您想查看对角线的情况,请尝试在控制台中使用一些值,您会看到它是如何进行映射的)

现在遍历有效行

function whoWon(board) {
    var i, s, r = 'RRRR', y = 'YYYY';
    // rows
    for (i = 0; i < board.length; ++i) {
        s = row(board, i);
        if (s.indexOf(r)) return 'R';
        if (s.indexOf(y)) return 'Y';
    }
    // cols
    for (i = 0; i < board[0].length; ++i) {
        s = col(board, i);
        if (s.indexOf(r)) return 'R';
        if (s.indexOf(y)) return 'Y';
    }
    // diagonals
    for (i = 4; i <= board.length + board[0].length - 4; ++i) {
        s = diagDown(board, i);
        if (s.indexOf(r)) return 'R';
        if (s.indexOf(y)) return 'Y';
        s = diagUp(board, i);
        if (s.indexOf(r)) return 'R';
        if (s.indexOf(y)) return 'Y';
    }
    return '-';
}

现在有

whoWon(board); // "R"

另请注意

function isDraw(board) {
    return board[0].every(e => e !== '-');
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-07-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多