2013-10-30 56 views
1

我正在为一个JavaScript项目创建一个扫雷游戏,并遇到了一个问题,我无法让我的脑袋回合。当你在扫雷游戏中点击一个空单元(没有任何地雷的单元,因此不显示数字)时,这将显示与其他单元相邻的空单元格块,当找到包含这些空块的“数字墙”时停止。下面的实施例:递归函数来检查2D数组

[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是空白块被点击的情况,所以这个代码需要修改,但我真的无法想象该怎么做。

从我能理解的情况来看,我需要调用case 0中的revealGridContents();函数,但为每个要检查的方格传入xClick和yClick的新值(数组位置的x和y值) 。

任何帮助阐明我下一步需要做的事情将不胜感激!

回答

1

不知道稍微多一点的程序,很难给你一个确切的解决方案。你可能需要一个单独的功能来做到这一点,因为只是使用相同的功能将显示一切(显然不是游戏的工作原理)。你还需要一些方法来跟踪显示的单元格,否则你会进入一个循环(我假设这是存储在另一个二维数组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); 
     }  
    } 
} 
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); 

困难的部分是在点击()函数。

试试这个演示(点击几次“与JS运行”直到你不输,并触及0): http://jsbin.com/iqeganU/1/edit