井字游戏循环

Tic-Tac-Toe Loop

我正在 javascript 中制作井字游戏。我列出了一些我认为是基本构建块的内容:

var board = [
            0, 0, 0,
            0, 0, 0,
            0, 0, 0
            ];
gameOn = true;
player1Move = true;
counter = 0;
player1 = [];
player2 = [];
var ask = console.log(prompt('where would you like to go?'));

var drawBoard = function(){
    console.log("   A " + (board[0]) + "| B " + (board[1]) + "| C " + (board[2]));
    console.log("  ------------- ");
    console.log("   D " + (board[3]) + "| E " + (board[4]) + "| F " + (board[5]));
    console.log("  ------------- ");
    console.log("   G " + (board[6]) + "| H " + (board[7]) + "| I " + (board[8]));
    console.log("  ------------- ");
};

var solutions = [
    (board[0] && board[1] && board[2]) || (board[3] && board[4] && board[5]) ||
    (board[6] && board[7] && board[8]) || (board[0] && board[3] && board[6]) ||
    (board[1] && board[4] && board[7]) || (board[2] && board[5] && board[8]) ||
    (board[0] && board[4] && board[8]) || (board[2] && board[4] && board[6])
];



while (gameOn === true){
// for loop for game logic
    for (var i = 0 ; i < 9; i++){
      if (player1Move === true) {
        player1.push(ask);
        drawBoard();
        player1Move = false;
      } else if (player1Move === false){
        player2.push(ask);
        drawBoard();
        player1Move = true;
      } else if ((player1 || player2) === solutions){
          gameOn = false;
          console.log((player1 || player2) + "wins!");
      } else {
        gameOn = false;
        console.log("Tie Game!");
      }
    }
}

我知道我的主循环语法不正确。为什么我不能做当前写的?如果您有此现有代码,您将使用哪种类型的循环设置来完成此操作?抱歉,如果这看起来不够具体,我只是迷失在这一切的逻辑中!

对于这个现有的循环,我现在要做的就是遍历并提示 2 个用户 9 次(因为最大移动数 = 9)。一旦成功,我将继续向其中添加更多游戏逻辑。为什么我上来9次都提示不上来?现在的结果是提示我一次,打印板子9次,全部都是false

顺便说一下,这现在也只需要在终端 window 中工作。

我尽可能少地更改了您的代码,但有些地方有所不同,我正在逐一解释。

var board = {
    A: null,
    B: null,
    C: null,
    D: null,
    E: null,
    F: null,
    G: null,
    H: null,
    I: null
};

gameOn = true;
player1Move = true;

var drawBoard = function(){
    console.log("   A " + (board.A || '') + "| B " + (board.B || '') + "| C " + (board.C || ''));
    console.log("  ------------- ");
    console.log("   D " + (board.D || '') + "| E " + (board.E || '') + "| F " + (board.F || ''));
    console.log("  ------------- ");
    console.log("   G " + (board.G || '') + "| H " + (board.H || '') + "| I " + (board.I || ''));
    console.log("  ------------- ");
};

var solutions = function() {
    return (board.A && (board.A == board.B && board.A == board.C))
        || (board.D && (board.D == board.E && board.D == board.F))
        || (board.G && (board.G == board.H && board.G == board.I));
};

drawBoard();
var currentPlayer;

while (gameOn === true){
// for loop for game logic
    for (var i = 0 ; i < 9; i++){
        if (solutions()){
            console.log(currentPlayer + " wins!");
            gameOn = false;
            break;
         }
        //else {
        //    gameOn = false;
        //    console.log("Tie Game!");
        //}
        currentPlayer = 'Player 1';
        if(!player1Move)
            currentPlayer = 'Player 2';

        var ask = prompt(currentPlayer + ': where would you like to go (A or B or C or ..)?');
        if(ask == 'exit') {
            gameOn = false;
            break;
        }

        if (player1Move === true) {
            //player1.push(ask);
            board[ask] = 'X';
            drawBoard();
            player1Move = false;
        } else if (player1Move === false){
            board[ask] = 'O';
            drawBoard();
            player1Move = true;
        }
    }
}

这还没有完全完成,但那是你之后可以做的事情,可能你不希望我为你做这一切。

这一切都在 Chrome 控制台中运行。

有一些基本的东西阻碍了你:

  1. var ask = console.log(prompt('where would you like to go?')); 应该是 var ask = prompt(currentPlayer + ': where would you like to go?'); - 您的版本正在 ask 填充 null。
  2. 这个提示也放错地方了:需要在循环里,在drawBoard()之后,让玩家有看点。
  3. 我已将棋盘从数组更改为对象,这样 'A' 等玩家的回答就直接指向对象字段。这样就可以删除播放器数组。
  4. solutions() 函数需要完成,如您所见,可能有更简洁的方法。
  5. 我在提示里增加了写'exit'的可能,不然没办法提前退出游戏
  6. 我没有完成 'Tie game!' 代码。

确保您了解全局对象是什么,window.prompt 是什么,以及在您的上下文中 console.log 是什么。 绝对有必要了解适合您环境的调试器。在 Chrome 中,它称为开发人员工具。

window.prompt 在 jsfiddle 或 Stack overflow 内置的代码沙箱中不是很有用。我建议使用 HTML 作为您的用户界面。

function init() {
    trapForm();
    trapInput();
    toggleCurrentUser();
    askUser();
}

var game = [
    [null,null,null],
    [null,null,null],
    [null,null,null]
];

var trapInput = function() {
    //  capture input and use to to create a play in the game
    document.querySelector('#go').addEventListener('click',function(ev) {

        var position = document.querySelector('#square').valueAsNumber;

        if (position < 10 && position > 0) {

            //  render X or O to the HTML
            var td = document.querySelectorAll('#t3 td')[position-1];
            td.innerHTML = currentUser;

            //  modify the corresponding game array
            var row = Math.floor( (position-1) / 3 );
            var col = ( (position+2) % 3) ;
            game[row][col] = currentUser;

            //  this helps us visualize what's happening
            debug(game);
            checkGameStatus();
            toggleCurrentUser();            

        } else {
            debug({"msg":"illegal move"});
        }

    });
};

var trapForm = function() {
    //  prevent form from submitting
    var f = document.querySelector('#f');
    f.addEventListener('submit',function(ev) {
        ev.preventDefault();
        trapInput();
    });
};

;(function(window,document,undefined){
  "use strict";

  function init() {
      trapForm();
      trapInput();
      toggleCurrentUser();
      askUser();
  }

  var currentUser = 'Y';

  var toggleCurrentUser = function(){
      if (currentUser === 'X') {
       currentUser = 'Y';   
      } else {
          currentUser = 'X';
      }
      document.querySelector('#currentuser').value = currentUser;
  };

  var isVirginal = function(game) {
      return game.every(function(row) {
          return row.every(function(cell) { return (cell === null); });
      });
  };

  var isStaleMate = function(game){
      return game.every(function(row){
          return row.every(function(cell){
              return (cell === 'X' || cell === 'Y');
          });
      });
  };

  var horizontalWinner = function(game) {
      var r = false;
      return game.some(function(row){
          var firstletter = row[0];
          if (firstletter === null) {
              return false;
          } else {
              return row.every(function(cell){
                  return ( cell !== null && cell === firstletter);
              });            
          }
      });
  };

  var verticalWinner = function(game) {
      var r = false;
      for (var i = 0; i < 4; i++) {
          if (game[0][i] === null) {
              continue;
          }
          if (game[0][i] === game[1][i] && game[1][i] === game[2][i]) {
              r = game[0][i];
              break;
          }
      };
      return r;
  };

  var diagonalWinner = function(game) {
      var r = false;
      if (game[0][0] !== null && (game[0][0] === game[1][1] === game[2][2])) {
          r = game[0][0];
      }
      if (game[0][2] !== null && (game[0][2] === game[1][1] === game[2][0])) {
          r = game[0][2];
      }    
      return r;
  };

  var checkGameStatus = function(){
      var r = 'unknown';
      if (isVirginal(game)) {
          r = 'Virginal Game';   
      } else {
          r = 'In Play';   
      }
      if (isStaleMate(game)) {
          r = 'Stale Mate';
      }
      if (diagonalWinner(game)){
          r = 'Diagonal Winner: ' + diagonalWinner(game);
      }
      if (verticalWinner(game)) {
          r = 'vertical Winner: ' + verticalWinner(game);
      }
      if (horizontalWinner(game)) {
          r = 'Horizontal Winner: ' + horizontalWinner(game);
      }
      document.querySelector('#status').value = r;
  };

  var debug = function(stuff) {
      document.querySelector('#debug').innerHTML = JSON.stringify(stuff);
  };

  var game = [
      [null,null,null],
      [null,null,null],
      [null,null,null]
  ];

  var trapInput = function() {
      // capture input and use to to create a play in the game
      document.querySelector('#go').addEventListener('click',function(ev) {

          var position = document.querySelector('#square').valueAsNumber;

          if (position < 10 && position > 0) {

              // render X or O to the HTML
              var td = document.querySelectorAll('#t3 td')[position-1];
              td.innerHTML = currentUser;

              // modify the corresponding game array
              var row = Math.floor( (position-1) / 3 );
              var col = ( (position+2) % 3) ;
              game[row][col] = currentUser;

              // this helps us visualize what's happening
              debug(game);
              checkGameStatus();
              toggleCurrentUser();            

          } else {
              debug({"msg":"illegal move"});
          }

      });
  };

  var trapForm = function() {
      // prevent form from submitting
      var f = document.querySelector('#f');
      f.addEventListener('submit',function(ev) {
          ev.preventDefault();
          trapInput();
      });
  };

  document.addEventListener('DOMContentLoaded',init);

})(window,document);
#t3 {
    font-family: "Courier New";
    font-size: xx-large;
}
#t3 td {
 border: 1px solid silver;
 width: 1em;
 height: 1em;
    vertical-align: middle;
    text-align: center;
}

#f {
    position: relative;
}

#f label, input, button {
    float: left;
    width: 200px;
}

#f label, button {
    clear: left;
}

hr {
    clear: both;
    visibility: hidden;
}
<form id="f">
    <label for="currentuser">Current User</label>
    <input type="text" readonly id="currentuser" name="currentuser" />
    <label for="square">What Square (1-9)?</label>
    <input type="number" step="1" min="1" max="9" id="square" name="square" />
    <label for="status">Game Status</label>
    <input type="text" readonly id="status" name="status" value="Virgin Game" />
    <button type="button" id="go">make move</button>
</form>

<hr />

<table id="t3">
    <tr>
        <td> </td>
        <td> </td>
        <td> </td>
    </tr>
    <tr>
        <td> </td>
        <td> </td>
        <td> </td>
    </tr>
    <tr>
        <td> </td>
        <td> </td>
        <td> </td>
    </tr>
</table>

<pre id="debug"></pre>