Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
336 views
in Technique[技术] by (71.8m points)

javascript - 关灯-检查灯光(Ligths Off - checking for lights)

I'm working on a game in JavaScript (I'm a novice), classic Lights Off puzzle.

(我正在使用JavaScript(我是新手)开发游戏,这是经典的Lights Off拼图。)

I managed to get the table to print out, and.

(我设法将表格打印出来,然后。)

However, I have a problem with checkAllOff function, which is supposed to test whether all buttons are in the off state (black), and if this is the case it should display a message "You win!".

(但是,我对checkAllOff函数有问题,该函数应该测试所有按钮是否都处于关闭状态(黑色),如果是这种情况,它应该显示一条消息“ You win!”。)

I want this function to also remove the message if, following a subsequent press, one or more buttons returns to the on state(yellow).

(如果在随后按下后,一个或多个按钮返回到打开状态(黄色),则我希望此功能也删除该消息。)

I'm asking for pointing out my mistakes in that functions and an explenation of how it should be done properly.

(我要指出我在该功能中的错误,以及如何正确完成操作的说明。)

My code is included in images:

(我的代码包含在图像中:)

 <!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> 

在此处输入图片说明

enter image description here

(在此处输入图片说明)

在此处输入图片说明

  ask by Nika translate from so

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

∞ loop in press()(press() ∞循环)

There is an issue in your press function.

(您的press功能出现问题。)

I see where you want to get at, but this won't work!

(我知道您想去哪里,但是这行不通!)

Everytime you click on a button a while loop is initiated and it will start toggling the button you've pressed on and off as well as checking the conditions (j!=0) , (i, j-1) , (j+1<5) , (i, j+1) , (i+1<5) , (i!=0) .

(每次您单击按钮时,都会启动while循环,它将开始切换您按下和关闭的按钮,并检查条件(j!=0)(i, j-1)(j+1<5)(i, j+1)(i+1<5)(i!=0) 。)

There is nothing stopping this loop!

(没有什么可以阻止这个循环!)

There's an easier way of going about this problem: simply call toggle on all adjacent buttons.

(解决此问题的方法更简单:只需在所有相邻按钮上调用toggle 。)

Then in toggle check if the button you're wanting to toggle actually exists (if it does exist change its state, if it doesn't, just return).

(然后在toggle检查您要toggle的按钮是否确实存在(如果确实存在,则更改其状态,如果不存在,则返回)。)

Indeed you will be expecting press to call toggle on buttons that don't exist.

(事实上,你会希望press呼叫toggle上不存在按钮。)

For instance: if you press but_01 you will call press(0,1) in turn calling toggle(0,1) , toggle(-1,1) , toggle(1,1) , toggle(0,0) and toggle(0,2) .

(例如:如果按下but_01 ,则会依次调用press(0,1) ,依次调用toggle(0,1)toggle(-1,1)toggle(1,1)toggle(0,0)toggle(0,2) 。)

However but_-11 doesn't exists and only but_01 , but_11 , but_00 and but_02 will see their state change.

(但是but_-11不存在,只有but_01but_11but_00but_02会看到它们的状态更改。)


checkAllOf() will always return the state of but_00(checkAllOf()将始终返回but_00的状态)

You have several issues when checking the state of the board:

(检查电路板的状态时遇到几个问题:)

First, you are initializing i , j and counter :

(首先,您要初始化ijcounter :)

var i = 0
var j = 0
var counter = 0

Then you select the content of but_00

(然后选择but_00的内容)

b = document.getElementById("but_" + i + j)
t = b.innerHTML

You loop over i x j ie [0;5[ x [0;5[ ( 5[ means 5 is excluded) ie [0;4] x [0;4] .

(您遍历i x j[0;5[ x [0;5[5[表示5被排除在外]),即[0;4] x [0;4] 。)

Here I should mention you are out of bound (i needs to be smaller than 5, it can't be equal as you only have 5 rows: 0 , 1 , 2 , 3 , 4 .

(这里我应该提到你是结合(ⅰ需要是小于5,它可以是不相等的,你只具有5行的: 01234 。)

for (i=0 ; i<5 ; i++)
  for (j=0 ; j<5 ; j++){
    if (t=="X") 
      counter++;
    }
  }
}

The problem is: the value of t is whatever b.innerHTML returned but it will not change over the period of these loops.

(问题是: t的值是返回的b.innerHTML但是在这些循环期间它不会改变。)

You're essentially checking if t=="X" 25 times!

(您实际上是在检查t ==“ X” 25次!)

Instead, we need to update its value then check if it's equal to "X".

(相反,我们需要更新它的值, 然后检查它是否等于“ X”。)

Lastly, you're checking for the total number of "X"s on the board to be equal to 25. This is simply not necessary.

(最后,您要检查板上的“ X”总数是否等于25。这根本没有必要。)

To know if you've won, you need to check all buttons, but if at least one button is an O then you already know you didn't win, right?

(要知道您是否赢了,需要检查所有按钮,但是如果至少一个按钮是O那么您已经知道自己没有赢,对吗?)

So when looping over the buttons, if you find an "X" you can directly return false .

(因此,当遍历按钮时,如果找到“ X”,则可以直接返回false 。)

If the loop as passed, ie all values are not "X"s then you know you've won and you can return true :

(如果循环通过,即所有值都不是 “ 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;
    }
  }
}

So you don't need to keep in memory the number of "X"s on the board.

(因此,您无需在内存中保留板上的“ X”数。)

We can write this even better by declaring the variables i and j inside the loop's head.

(我们可以通过在循环头内声明变量ij更好地编写此代码。)

Also, you might want to use the let declaration statement...

(另外,您可能要使用let声明语句...)


Side note, you have a syntax error on your alert , you need quotes.

(旁注,您的alert有语法错误,需要用引号引起来。)

But that wasn't really the main concern here I presume.

(但这并不是我想的主要关注点。)

Also, you need to actually call checkAllOf with checkAllOf() in the if condition as checkAllOf will return the function itself, not the result of the function.

(另外,您实际上需要在if条件中使用带有checkAllOf() checkAllOf调用 ,因为checkAllOf将返回函数本身,而不是函数的结果。)


Possible solution(可能的解决方案)

 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> 


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...