2013-10-30 55 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