javascript - 关灯 - 检查灯
问题描述
我正在用 JavaScript 开发一款游戏(我是新手),经典的关灯谜题。我设法让表格打印出来,并且。但是,我有一个 checkAllOff 函数的问题,它应该测试是否所有按钮都处于关闭状态(黑色),如果是这种情况,它应该显示一条消息“你赢了!”。如果在随后按下后,一个或多个按钮返回到打开状态(黄色),我希望此功能也删除消息。我要求指出我在该功能中的错误,并说明应该如何正确完成。我的代码包含在图像中:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<!-- JavasScript code is contained within an HTML <script> element -->
<script>
function toggle(i,j) {
b=document.getElementById("but_" + i + j)
t = b.innerHTML
if (t=="X") {b.innerHTML = "O";
b.setAttribute( "style", "color:red; background-color:yellow" )
}
if (t=="O") {b.innerHTML = "X";
b.setAttribute( "style", "color:white; background-color:black" )
}
}
function checkAllOf(){
//Check if board is solved
var i=0
var j=0
var counter=0
b=document.getElementById("but_" + i + j)
t = b.innerHTML
for(i=0;i<=5;i++)
for (j=0; j<5; j++){
if(t=="X")
counter++;
}
if (counter==25)
return(false);
return(true);
}
function press(i,j) {
while(1)
{
toggle( i, j )
if (j!=0)
toggle(i, j-1)
if (j+1<5)
toggle(i, j+1)
if (i+1<5)
toggle(i+1, j)
if (i!=0)
toggle(i-1, j)
if (checkAllOf){
alert(All lights are out! You win!)
}
}
}
function generateGrid() {
var d = document.getElementById("button-grid");
var table = document.createElement("table");
d.appendChild(table);
for (var i = 0; i < 5; i++) {
var row = document.createElement("tr");
for (var j = 0; j < 5; j++) {
var cell = document.createElement("td");
cell.innerHTML = "<button type=button id=but_" + i + j +
" onclick=\"press(" +i + ',' +j + ")\"" +
" style=\"color:red; background-color:yellow\"" +
">O</button>" ;
row.appendChild(cell);
}
table.appendChild(row);
}
toggle(2,2) // Set middle button to off state (otherwise seems to be impossible).
}
window.onload = function() {
generateGrid();
};
</script>
<title>Lights Off Puzzle</title>
</head>
<body>
<div align="center" id="button-grid">
<h1> *** Lights Off *** </h1>
<h2> Click on buttons until they all turn black </h2>
</div>
</body>
</html>
解决方案
∞ 循环press()
press
你的函数有问题。我知道你想去哪里,但这行不通!每次单击按钮时,都会启动一个 while 循环,它将开始切换您按下的按钮的开和关,并检查条件(j!=0)
, (i, j-1)
, (j+1<5)
, (i, j+1)
, (i+1<5)
, (i!=0)
。没有什么能阻止这个循环!
解决这个问题有一种更简单的方法:只需调用toggle
所有相邻的按钮。然后toggle
检查您要切换的按钮是否确实存在(如果确实存在则更改其状态,如果不存在,则返回)。实际上,您会期望press
调用toggle
不存在的按钮。
例如:如果您按,but_01
您将press(0,1)
依次呼叫toggle(0,1)
、toggle(-1,1)
、toggle(1,1)
和。但是不存在,只有,和会看到它们的状态变化。toggle(0,0)
toggle(0,2)
but_-11
but_01
but_11
but_00
but_02
checkAllOf() 将始终返回but_00
检查电路板状态时有几个问题:
首先,您正在初始化i
和:j
counter
var i = 0
var j = 0
var counter = 0
然后选择内容but_00
b = document.getElementById("but_" + i + j)
t = b.innerHTML
您循环i
xj
即[0;5[
x [0;5[
(不包括5[
平均值5
)即[0;4]
x [0;4]
。在这里我应该提到你超出了界限(我需要小于 5,它不能相等,因为你只有 5 行:0
, 1
, 2
, 3
, 4
.
for (i=0 ; i<5 ; i++)
for (j=0 ; j<5 ; j++){
if (t=="X")
counter++;
}
}
}
问题是: 的值t
是b.innerHTML
返回的值,但在这些循环期间不会改变。您实际上是在检查 t=="X" 25 次!相反,我们需要更新它的值,然后检查它是否等于“X”。
最后,您正在检查板上“X”的总数是否等于 25。这根本没有必要。
要知道您是否赢了,您需要检查所有按钮,但如果至少有一个按钮是,O
那么您已经知道您没有赢,对吧?所以在循环按钮时,如果你找到一个“X”,你可以直接返回false
。如果循环通过了,即所有值都不是“X”,那么你就知道你赢了,你可以返回true
:
for (i=0 ; i<5 ; i++)
for (j=0 ; j<5 ; j++){
b=document.getElementById("but_" + i + j)
t = b.innerHTML
if (t=="O")
return false;
}
}
}
所以你不需要记住板上“X”的数量。
我们可以通过在循环头部声明变量i
来写得更好。j
此外,您可能想使用let
声明语句...
旁注,你有一个语法错误alert
,你需要引号。但这并不是我认为的主要问题。
此外,您需要在 if 条件中实际调用 checkAllOf
with ,因为它将返回函数本身,而不是函数的结果。checkAllOf()
checkAllOf
可能的解决方案
function toggle(i, j) {
b = document.getElementById("but_" + i + j)
if (!b) return;
t = b.innerHTML
if (t == "X") {
b.innerHTML = "O";
b.setAttribute("style", "color:red; background-color:yellow")
}
if (t == "O") {
b.innerHTML = "X";
b.setAttribute("style", "color:white; background-color:black")
}
}
// Check if board is solved
function checkAllOff() {
for (var i = 0; i < 5; i++)
for (var j = 0; j < 5; j++) {
t = document.getElementById("but_" + i + j).innerHTML
if (t == "O")
return false
}
return (true);
}
function press(i, j) {
toggle(i, j)
toggle(i, j - 1)
toggle(i, j + 1)
toggle(i + 1, j)
toggle(i - 1, j)
if (checkAllOff()) {
console.log("All lights are out!You win!")
}
}
function generateGrid() {
var d = document.getElementById("button-grid");
var table = document.createElement("table");
d.appendChild(table);
for (var i = 0; i < 5; i++) {
var row = document.createElement("tr");
for (var j = 0; j < 5; j++) {
var cell = document.createElement("td");
cell.innerHTML = "<button type=button id=but_" + i + j +
" onclick=\"press(" + i + ',' + j + ")\"" +
" style=\"color:red; background-color:yellow\"" +
">O</button>";
row.appendChild(cell);
}
table.appendChild(row);
}
}
window.onload = function() {
generateGrid();
};
<div align="center" id="button-grid">
<h1> *** Lights Off *** </h1>
<h2> Click on buttons until they all turn black </h2>
</div>
推荐阅读
- node.js - 从另一台服务器 NodeJS 提供静态文件
- html - 如何关联两个元素以实现可访问性?
- angular - InnerHTML 指令忽略 Angular 中的 html 标签
- java - 您可以将字符串数组列表中的元素传递给函数吗?
- javascript - 切换选择所有复选框 - 未禁用
- javascript - 将 Laravel 集合/数组转换为 Javascript 数组
- javascript - 满足条件时如何让我的函数运行?
- android - 为一周中的特定日期设置警报管理器
- uml - 如何绘制两个系统的用例?
- python-3.x - 无法在 python 的插入语句中使用参数?