我只是遇到一个小问题。
我计算机科学课的最后一项任务是用JavaScript编写一个Tic-Tac-Toe游戏。游戏通过单击表格中的单元格并使用函数()将img源(一个空白图像直到被点击)切换为X或O来工作。它刚刚完成,但有一件事我无法获得
显然,这场比赛是由两名球员进行的。我需要的最后一件事就是让它(一个函数)检测玩家何时获胜并在发生这种情况时杀死脚本。我只是想不出来。我知道它涉及if语句,我尝试了几种不同的代码,但是我编写的所有代码都打破了游戏。
我确实之前已经问过这个问题了,我已经尝试点击右侧“类似问题”框中的几个链接,但所有这些链接都是我没有学过的语言(例如作为C#)。
这是我的剧本:
<script type="text/javascript" charset="ISO-8859-1">
function placeMove(value)
{
if (document.getElementById(value).src.indexOf("FC")!=-1) //"FC" because of the FC contained in the file name. I intended for it to stand for "free cell", for easy indentification.
{
var turn = document.getElementById("playerturn").innerHTML;
if (turn == "X")
{
document.getElementById(value).src="../Images/TicTacToeX.jpg";
document.getElementById("playerturn").innerHTML="O";
}
if (turn == "O")
{
document.getElementById(value).src="../Images/TicTacToeO.jpg";
document.getElementById("playerturn").innerHTML="X";
}
}
else
{
window.alert("Tile is in use. Please select another tile.");
}
}
function detectWin()
{
}
</script>
这是游戏发生的表格,如果它有帮助:
<table class="gametable" id="gametable" border="1">
<tr>
<td><img onclick="placeMove('r1c1')" id="r1c1" class="blank" alt="blank space" src="../Images/TicTacToeFC.jpg"></img></td>
<td><img onclick="placeMove('r1c2')" id="r1c2" class="blank" alt="blank space" src="../Images/TicTacToeFC.jpg"></img></td>
<td><img onclick="placeMove('r1c3')" id="r1c3" class="blank" alt="blank space" src="../Images/TicTacToeFC.jpg"></img></td>
</tr>
<tr>
<td><img onclick="placeMove('r2c1')" id="r2c1" class="blank" alt="blank space" src="../Images/TicTacToeFC.jpg"></img></td>
<td><img onclick="placeMove('r2c2')" id="r2c2" class="blank" alt="blank space" src="../Images/TicTacToeFC.jpg"></img></td>
<td><img onclick="placeMove('r2c3')" id="r2c3" class="blank" alt="blank space" src="../Images/TicTacToeFC.jpg"></img></td>
</tr>
<tr>
<td><img onclick="placeMove('r3c1')" id="r3c1" class="blank" alt="blank space" src="../Images/TicTacToeFC.jpg"></img></td>
<td><img onclick="placeMove('r3c2')" id="r3c2" class="blank" alt="blank space" src="../Images/TicTacToeFC.jpg"></img></td>
<td><img onclick="placeMove('r3c3')" id="r3c3" class="blank" alt="blank space" src="../Images/TicTacToeFC.jpg"></img></td>
</tr>
</table>
明天将分配作业,我需要的只是最后一点代码。
非常感谢任何帮助。这是我上学期的最后一次作业。
谢谢,
凯尔
编辑:经过一些建议,这是我一直在尝试的。输入此代码将不允许玩游戏。如果只是缺少分号,请原谅我。它涉及将每个单元格中的img源设置为变量,并检查这些变量是否匹配。我创建了9个变量,每个单元格对应一个/ X或O图像:
var pic1 = document.getElementById("r1c1").src;
var pic2 = document.getElementById("r1c2").src;
var pic3 = document.getElementById("r1c3").src;
var pic4 = document.getElementById("r2c1").src;
var pic5 = document.getElementById("r2c2").src;
var pic6 = document.getElementById("r2c3").src;
var pic7 = document.getElementById("r3c1").src;
var pic8 = document.getElementById("r3c2").src;
var pic9 = document.getElementById("r3c3").src;
这是在第一个脚本的最后:
function detectWin()
{
if (var pic1 == var pic2 && var pic3)
{
window.alert("Game won. Please reset the game.");
}
}
这显然只能检测到第一行的胜利。如果我可以让它工作,我会知道其余代码必须是什么。不过,我仍然不知道如何杀死剧本。
编辑删除一些不必要的评论和语法错误。
答案 0 :(得分:3)
我从开头的代码中写道,你可以查看我的查看谁赢得游戏的版本。如果我的游戏版本不是你,请不要贬低。我只是想告诉你如何在不知道任何算法的情况下编写代码。
你只需要动力。不要下次这么快就放弃。
我的版本用于检查谁赢了:
var checkResult = function(){
$("table tr").each(function(i, val){
$(this).find('td').each(function(j, val2){
arr[i][j] = parseInt($(this).attr("data-points"));
});
});
for(var i = 0; i<3;i++){
var rowSum = 0;
for(var j = 0; j<3;j++){
rowSum += arr[i][j];
}
if(rowSum === 3)
alert("Circle WIN!");
else if(rowSum === -3)
alert("Cross WIN!");
}
for(var i = 0; i<3;i++){
var colSum = 0;
for(var j = 0; j<3;j++){
colSum += arr[j][i];
}
if(colSum === 3)
alert("Circle WIN!");
else if(colSum === -3)
alert("Cross WIN!");
}
if(arr[0][0] + arr[1][1] + arr[2][2] === 3)
alert("Circle WIN!");
else if(arr[0][0] + arr[1][1] + arr[2][2] === -3)
alert("Cross WIN!");
if(arr[2][0] + arr[1][1] + arr[0][2] === 3)
alert("Circle WIN!");
else if(arr[2][0] + arr[1][1] + arr[0][2] === -3)
alert("Cross WIN!");
};
答案 1 :(得分:1)
我看到你说你搜索了Stack Overflow的类似问题。我理解如何对编程不熟悉,用另一种语言阅读内容并不容易,但基本思想就在那里。以下是已完成此操作的链接:Algorithm for Determining Tic Tac Toe Game Over。
话虽如此,在游戏中基本上有3种方法可以赢得胜利,并且你正朝着正确的方向前进。
获胜的三种方式是
简单的部分是行和列,只是循环遍历每一行/列,看看你是否得到三个匹配,如果你这样做,那么你可以声明一个胜利者。
非效率伪代码示例:
if pic1, pic2, and pic3 are the same
alert user X or O has won
end the game.
对第2行和第3行重复。
if pic1, pic4, and pic7 are the same
alert user X or O has won
end the game.
重复第2栏和第3栏。
对角线也可以以简单的方式完成,而不使用示例中的二维数组。基本上只有两种对角胜利的可能性:
你可以在平局中结束比赛。我建议使用链接示例中显示的计数器。
祝你好运! - 为清晰起见而编辑 -答案 2 :(得分:1)
我不能真诚地给你答案,但我可以引导你思考这个问题;绝不是最好的解决方案,但它至少可以让你开始。
要检测获胜者,必须确保以下一个:
幸运的是,您可以循环使用表格元素,以便轻松进行检查。
您提供的if
声明存在缺陷。在您已经声明变量后,您不需要在变量之前加上var
。此外,您使用&&
是错误的。这将做的是检查左语句是否为真,在这种情况下是var pic1 == var pic2
,然后检查右语句是否也为真,这只是var pic3
。就其本身而言,这不是一个好的陈述,因为它将自动转换为Javascript对布尔值的最佳解释,在这种情况下,只要定义了pic3,就会true
。相反,你需要像if(pic1 == pic2 && pic2 == pic3)
这样的东西,但我会使用除了比较图像之外的东西,这就是你正在做的事情。您可以将每个单元格的类别更改为“X”或“O”,具体取决于哪个单元格更加优雅。
可以通过.className
电话访问班级名称:
<div id="foo" class="bar"></div>
<script>
document.getElementById("foo").className; //returns "bar"
</script>
Here是对如何更改元素类的更深入的描述。
答案 3 :(得分:1)
假设&#39;正方形&#39;是一个方形大小的数组,其中0表示未填充 ,1表示玩家1(x),-1表示其他玩家(O)。
e.g。
let squares = Array(3).fill(Array(3).fill(0))
将是盯着董事会。
以下适用于电路板尺寸1,2,3,4 ...对于尺寸为n的电路板,n个连续的x或o需要在行列或对角线中。
如果没有人赢了,则返回0,对于玩家1则返回1,为另一个玩家返回-1。
首先定义两个辅助函数以使代码更具可读性。
const add = (a, b) =>
a + b
function sum(array)
{
return array.reduce(add);
}
function calculateWinner(squares) {
// check for horizontal wins along rows and diagonals
let winner = calculateWinnerInner(squares);
if (winner !== 0) return winner;
// check for possible vertical wins as well
const stranspose = squares.map((col, i) => squares.map(row => row[i]));
return calculateWinnerInner(stranspose);
}
function calculateWinnerInner(squares) {
for (let r = 0; r < squares.length; r++) {
if (squares[r].length === sum(squares[r])) {
return 1;
}
if (squares[r].length === - sum(squares[r])) {
return -1;
}
}
const diagonal = squares.map((row, r) => squares[r][r]);
if (squares[0].length === sum(diagonal)) {
return 1;
}
if (squares[0].length === -sum(diagonal)) {
return -1;
}
const len=squares.length;
const crossdiagonal = squares.map((row, r) => squares[r][len-r-1]);
if (squares[0].length === sum(crossdiagonal)) {
return 1;
}
if (squares[0].length === -sum(crossdiagonal)) {
return -1;
}
return 0;
}
&#13;
答案 4 :(得分:0)
进行一些优化。
答案 5 :(得分:0)
我的版本,但它没有领带游戏检查:
var table = [
['','',''],
['','',''],
['','','']
]
function GameIsOver(player) {
var result = true;
for (var j = 0; j < 3; j++) { //first diagonal
result= result && (table[j][j] == player);
}
if (result) {
return gameResult = {
result: result,
player: player
};
}
result = true;
for (var j = 0; j < 3; j++) { //second diagonal
result= result && (table[2-j][j] == player);
}
if (result) {
return gameResult = {
result: result,
player: player
};
}
for (var k = 0; k < 3; k++) {
result = true;
for (var j = 0; j < 3; j++) { //lines
result = result && (table[k][j] == player);
}
if (result) {
return gameResult = {
result: result,
player: player
};
}
result = true;
for (var j = 0; j < 3; j++) { //colums
result = result && (table[j][k] == player);
}
if (result) {
return gameResult = {
result: result,
player: player
};
}
}
return false;
}
答案 6 :(得分:0)
取决于您希望以哪种方式代表董事会。
我已经编写了一个Tic-Tac-Toe游戏(在 React 中),并选择了一个 flat array ,因为我认为它更易于使用(也在游戏的其他方面)
我以预定义所有可能的获胜位置的方式编写了 win-detection 代码,并将表示游戏板的Array转换为两个字符串组成的数组(每个玩家一个),因此每个字符串都有该特定玩家选择的单元格索引。
/**
*
* @param {Array} board - flat array representation of the board,
* from right to left, top to bottom, Ex.
* [1,2,2,1,1,2,1,2,1]
*/
function checkWin(board){
// all possible winning combinations (of cells filled by the same player)
const winMap = [123, 456, 789, 147, 258, 369, 357, 159]
// convert the board to array represening the filled cells, per player.
// each array item is a string of only the cells (indices) filled by a player
const moves = board.reduce((players, v, i) => {
if(v) players[v-1] += i+1
return players
}, ['', ''])
// console.log(JSON.stringify(moves))
// find & return the winning combination
const winningMove = winMap.find(comb =>
moves.some(m => // there are only 2 sets of moves, one for each player
// break down the current combination to array and check if every item exists
// also in the current set of moves. quit on first match.
comb.toString().split('').every(c => m.includes(c))
)
)
return winningMove ?
{ // get the first number of the winning-move,
// substract 1 from it, and use as index to find which
// player played that move from the board Array
player: board[winningMove.toString()[0] - 1],
move: winningMove
}
: false
}
// sample tests:
[
[1,1,1,2,2,2], // player 1 wins, horizontal, row 1
[1,2,2,1,,,1], // player 1 wins, vertical, col 1
[2,1,1,1,2,1,2,1,2], // player 2 wins, diagonal to right
[1,1,2,1,2,1,2,1,2], // player 2 wins, diagonal to left
[1,2,1,1,2,1,2,1,2] // no win
].forEach(board => console.log(
checkWin(board)
))