我在使用 html / css / javascript (使用jquery)编码的tictactoe游戏时遇到错误。
大多数时候游戏运作正常但在某些情况下(似乎它不依赖于棋盘上棋子的位置或动作的顺序,我还没有设法找出它的情况)因为它很随意而中断了它会给出错误的赢家数字(有时甚至会在任何人赢得时显示胜利警告)并且它会改变预期的部分(当玩家2正在玩时它将玩家1件放入其中)。
每当此错误发生时,它会显示获胜者的警报(总是错误的获胜者),并且当游戏重置时,最后点击的位置不会重置。
我已经检查过函数 WhoWins(board)是否正常工作。
JAVASCRIPT:
const NO_WINNER = 0;
const PL1 = 1;
const PL2 = 2;
const FREE = 0;
const PIECEPL1 = 'X';
const PIECEPL2 = 'O';
$(document).ready(function() {
TicTacToe();
});
// **** ACTION ****
function TicTacToe() {
console.log("Game start");
// Initialization of variables
var moves = 0;
var board = [[FREE, FREE, FREE],[FREE, FREE, FREE],[FREE, FREE, FREE]];
var winner = NO_WINNER;
$( ".square" ).html( "" ); // Reset of board
$( "#pnum" ).html( PL1 ); // Player 1 starts
StartMove(moves, board);
}
// **** ACTION ****
// PRE: moves is integer, board is integer 3x3 matrix.
// POST: The game has been updated.
function StartMove(moves, board) {
console.log("Move " + moves);
// We wait for a click on some square
$( ".square" ).each(function() {
$( this ).on("click", function() {
var id = $( this ).attr( "id" );
// [id[1]][id[2]] is the position of the clicked square in the board
var i = id[1];
var j = id[2];
if (board[i][j] == FREE) { // We update the board only if the clicked position isn't already marked
if (moves%2 == 0) { // Player 1 is playing
$( '#' + id ).html(PIECEPL1);
board[i][j] = PL1;
}
else { // Player 2 is playing
$( '#' + id ).html(PIECEPL2);
board[i][j] = PL2;
}
++moves;
winner = WhoWins(board);
// We check the situation of the game
if (moves == 9 && winner == NO_WINNER) {
alert( "Draw!" );
TicTacToe(); // We start a new game
}
else if (winner == NO_WINNER) {
$( "#pnum" ).html(moves%2 + 1); // We write the number of next move's player (We add one not because it's the next move but because the players are numbered 1,2 and not 0,1)
StartMove(moves, board); // We start the next move
}
else {
alert( "The winner is Player " + winner );
TicTacToe(); // We start a new game
}
}
});
});
}
// **** FUNCTION ****
// PRE: board is integer 3x3 matrix.
// POST: Returns integer 0 if there is no winner, integer 1 if player 1 wins or integer 2 if player 2 wins
function WhoWins(board) {
// We check for row equality
if (board[0][0] != FREE && board[0][0] == board[0][1] && board[0][0] == board[0][2]) return board[0][0];
if (board[1][0] != FREE && board[1][0] == board[1][1] && board[1][0] == board[1][2]) return board[1][0];
if (board[2][0] != FREE && board[2][0] == board[2][1] && board[2][0] == board[2][2]) return board[2][0];
// We check for columns equality
if (board[0][0] != FREE && board[0][0] == board[1][0] && board[0][0] == board[2][0]) return board[0][0];
if (board[0][1] != FREE && board[0][1] == board[1][1] && board[0][1] == board[2][1]) return board[0][1];
if (board[0][2] != FREE && board[0][2] == board[1][2] && board[0][2] == board[2][2]) return board[0][2];
// We check for diagonal equality
if (board[0][0] != FREE && board[0][0] == board[1][1] && board[0][0] == board[2][2]) return board[0][0];
if (board[0][2] != FREE && board[0][2] == board[1][1] && board[0][2] == board[2][0]) return board[0][2];
return NO_WINNER;
}
HTML:
<!DOCTYPE html>
<html>
<head>
<script type = "text/javascript" src = "jquery-2.1.0.min.js"> </script>
<script type = "text/javascript" src = "tictactoe.js"> </script>
<link rel = "stylesheet" type = "text/css" href = "tictactoe.css">
<title> Tic-tac-toe </title>
</head>
<body>
<header></header>
<div id = "board">
<div class = "square" id = "p00"></div> <!-- It's important for the id to not change, as it identifies the position of the square in the board -->
<div class = "square" id = "p01"></div>
<div class = "square" id = "p02"></div>
<div class = "square" id = "p10"></div>
<div class = "square" id = "p11"></div>
<div class = "square" id = "p12"></div>
<div class = "square" id = "p20"></div>
<div class = "square" id = "p21"></div>
<div class = "square" id = "p22"></div>
</div>
<p>Player <span id = "pnum"></span></p>
</body>
</html>
CSS:
body { background-color: black }
#board {
width: 914px;
height: 914px;
display: inline-block;
}
.square {
border: dotted white 3px;
width: 300px;
height: 300px;
display: inline-block;
vertical-align: top;
margin-right: -4px;
border-radius: 20%;
text-align: center;
line-height: 310px;
font-family: Arial;
font-size: 2000%;
color: white;
}
p {
color: white;
font-size: 80px;
display: inline-block;
position: absolute;
margin-left: 30px;
top: -60px;
font-family: Arial;
}
答案 0 :(得分:0)
每次调用StartMove()
函数时,都会应用新的click
事件监听器。因此,对于每个新游戏,附加的点击事件将附加到元素。您不需要这样,因此在重新应用之前删除(取消绑定)点击事件。
I.E取而代之:
$( this ).on("click", function() {...
用这个:
$( this ).unbind("click").on("click", function() {...
因为你是新人,我也让你成为jsFiddle,以便下次发帖时你更熟悉它; - )