我正在为一个javascript项目创建一个扫雷游戏,并遇到了一个我无法理解的问题。当你在扫雷游戏中为那些不知道的人点击一个空单元格(一个没有任何地雷并因此没有显示数字的单元格)时,这将显示相邻的空单元格的整个块,当找到包含这些空块的“数字墙”时停止。示例如下:
[1] http://datagenetics.com/blog/june12012/hole.png
这需要一个递归函数来确定要显示哪些块。我的代码目前只显示点击的块:
function revealGridContents()
{
switch (positionClickContents)
{
case 0:
ctx.drawImage(clickedImage, (xClick*20), (yClick*20));
break;
case 1:
ctx.drawImage(num1Image, (xClick*20), (yClick*20));
break;
case 2:
ctx.drawImage(num2Image, (xClick*20), (yClick*20));
break;
case 3:
ctx.drawImage(num3Image, (xClick*20), (yClick*20));
break;
case 4:
ctx.drawImage(num4Image, (xClick*20), (yClick*20));
break;
case 5:
ctx.drawImage(num5Image, (xClick*20), (yClick*20));
break;
case 6:
ctx.drawImage(num6Image, (xClick*20), (yClick*20));
break;
case 7:
ctx.drawImage(num7Image, (xClick*20), (yClick*20));
break;
case 8:
ctx.drawImage(num8Image, (xClick*20), (yClick*20));
break;
};
};
传递给switch语句的数字是数组grid[xClick][yClick]
中数据的值;例如,4表示一个区域,周围有4个地雷,因此将显示4的图像。
案例0是单击空白块的情况,因此需要修改此代码,但我真的不知道该怎么做。
根据我的理解,我需要从案例0调用revealGridContents();
函数,但为每个方格传递xClick和yClick的新值(数组位置的x和y值)想检查一下。
任何有助于阐明我下一步需要做什么的帮助都将不胜感激!
答案 0 :(得分:1)
如果不了解您的程序,就很难为您提供准确的解决方案。你可能需要一个单独的功能才能做到这一点,因为只需使用相同的功能就可以显示所有内容(这显然不是游戏的工作原理)。你还需要一些方法来跟踪显示的细胞,否则你会进入一个循环(我假设它存储在另一个2d数组revealed[x][y]
中)。
您可能想要做这样的事情(我没有对此进行测试,因此可能存在错误 - 道歉):
function revealGridContents(){
switch (positionClickContents){
case 0:
ctx.drawImage(clickedImage, (xClick*20), (yClick*20));
checkAdjacentCells(xClick, yClick);
break;
...
}
}
function checkAdjacentCells(x,y){
var cellsToCheck = [
[x,y+1],
[x,y-1],
[x+1,y],
[x-1,y]];
var x,y;
for(var i=0; i<=cellsToCheck.length; i++){
x = cellsToCheck[i][0];
y = cellsToCheck[i][1];
if(!revealed[x][y] && grid[x][y] == 0){
ctx.drawImage(clickedImage, x*20, y*20);
checkAdjacentCells(x,y);
}
}
}
答案 1 :(得分:0)
正如一般建议,您需要在游戏模型和用户界面之间进行更好的分离。
这是我对扫雷游戏的解释的开始:
function init() {
var i,j; // indexes
map = []; // global map, because i'm lazy
for (i=0; i<10; i++) {
var row = [];
for (j=0; j<10; j++)
row.push({
bomb : Math.round(Math.random()-0.4), // set bombs randomly, change to your correct ratio
revealed : false, // nothing is visible at start
count : 0 // counts will be computed after all the map is created
});
map.push(row);
}
// set adjacent bomb counts
for (i=0; i<10; i++)
for (j=0; j<10; j++) {
if (map[i-1] && map[i-1][j-1] && map[i-1][j-1].bomb) map[i][j].count++;
if (map[i-1] && map[i-1][j] && map[i-1][j].bomb) map[i][j].count++;
if (map[i-1] && map[i-1][j+1] && map[i-1][j+1].bomb) map[i][j].count++;
if (map[i] && map[i][j-1] && map[i][j-1].bomb) map[i][j].count++;
if (map[i] && map[i][j+1] && map[i][j+1].bomb) map[i][j].count++;
if (map[i+1] && map[i+1][j-1] && map[i+1][j-1].bomb) map[i][j].count++;
if (map[i+1] && map[i+1][j] && map[i+1][j].bomb) map[i][j].count++;
if (map[i+1] && map[i+1][j+1] && map[i+1][j+1].bomb) map[i][j].count++;
}
}
function print() { // uses console to display instead of canvas
var output = '\n';
for (var i=0; i<10; i++) {
for (var j=0; j<10; j++) {
var item = map[i][j];
output += (item.revealed ? item.count : 'x') + ' ';
}
output += '\n';
}
console.log(output);
}
function click(x,y) {
reveal(x,y);
print(map);
}
function reveal(x,y) {
// break early if click is invalid (invalid clicks are generated)
if (x < 0 || x > 9 || y < 0 || y > 9 || map[x][y].revealed) return;
// mark the square as clicked
map[x][y].revealed = true;
if (map[x][y].bomb) { // losing click
console.log('You lost');
} else if (map[x][y].count === 0) { // click on 0 adjacent bombs
reveal(x-1, y);
reveal(x, y-1);
reveal(x, y+1);
reveal(x+1, y);
}
}
init();
console.log('First print');
print();
console.log('Click 1,3');
click(1,3);
困难的部分在click()函数中。
试试这个演示(点击&#39;用JS&#39运行几次,直到你不输,然后命中0): http://jsbin.com/iqeganU/1/edit