2014-04-19 93 views
3

我正在嘗試在一個項目中重新創建掃雷工具,我已經儘可能地放置了地雷和數字。我似乎無法找出擴展點擊瓦片並清除鄰居的遞歸算法。有兩個數組,_map保存背景+地雷&數字,_clickable地圖保存位於背景頂部的瓦片。所以基本上,我要求的是幫助遞歸。如果這不夠清楚,我會用必要的信息更新問題。掃雷清算算法

private function onClick(e:MouseEvent):void 
{ 
    trace("on Click"); 

    var symbol = e.currentTarget; 
    var tempTileMask:TileMask = symbol; 
    var tempTile:Tile = _map[tempTileMask.yCoord][tempTileMask.xCoord] 

    if (tempTile.hasMine) 
    { 
     for (var i:int = _gridSize - 1; i >= 0; i--) 
      for (var j:int = _gridSize - 1; j >= 0; j--) 
      { 
       var temp:TileMask = _clickableMap[i][j]; 
       removeChild(temp); 
      } 

     //explosion(); 

     //gameOver(); 
    } 

    if (tempTile.hasNumber) 
    { 
     removeChild(tempTileMask); 
     tempTile.cleared = true; 
    } 

    else 
    { 
     clearTiles(tempTile.xCoord, tempTile.yCoord); 
    } 
} 

這是我修改,以清除地雷

function clearTiles(x:int, y:int) 
{ 
    // Get an object that contains the tile information for the location 
    // we are checking 
    if(_map[y][x] != null) 
    { 
     var tempTile:Tile = _map[y][x]; 
     var tempTileMask:TileMask = _clickableMap[y][x]; 

     // Check if the location we are checking is out of the bounds of the 
     // playable area 

     trace(tempTile); 
     if (tempTile.outOfBounds(x, y)) 
     { 
      return; 
     } 

     // If the tile has already been revealed then there is nothing to do 

     trace("before clearing"); 
     if (tempTile.cleared) 
     { 
      trace("clearing tile"); 
      return; 
     } 

     // If the tile hasn't been revealed and it's an empty square we 
     // reveal the location then call this function again for each 
     // surrounding block 

     trace("before check for surrounding tiles"); 
     if (tempTile.hasNumber != true && tempTile.hasMine != true) 
     { 
      trace("check for surrounding tiles"); 

      // Remove the mask hiding the tiles property 
      removeChild(tempTileMask); 
      // Set the tile as cleared 
      tempTile.cleared = true; 

      if(_map[tempTile.yCoord][tempTile.xCoord - 1] != null) 
      { 
       var tile1:Tile =_map[tempTile.yCoord][tempTile.xCoord - 1] 

       if(!tile1.cleared) 
        clearTiles(tempTile.xCoord - 1 , tempTile.yCoord); //Check tile to the left 
      } 

      if(_map[tempTile.yCoord][tempTile.xCoord + 1] != null) 
      { 
       var tile2:Tile =_map[tempTile.yCoord][tempTile.xCoord + 1] 

       if(!tile2.cleared) 
        clearTiles(tempTile.xCoord + 1 , tempTile.yCoord); //Check tile to the left 
      } 

      if(_map[tempTile.yCoord - 1][tempTile.xCoord] != null) 
      { 
       var tile3:Tile =_map[tempTile.yCoord - 1][tempTile.xCoord] 

       if(!tile3.cleared) 
        clearTiles(tempTile.xCoord, tempTile.yCoord - 1); //Check tile to the left 
      } 

      if(_map[tempTile.yCoord + 1][tempTile.xCoord] != null) 
      { 
       var tile4:Tile =_map[tempTile.yCoord + 1][tempTile.xCoord] 

       if(!tile4.cleared) 
        clearTiles(tempTile.xCoord, tempTile.yCoord + 1); //Check tile to the left 
      } 

      if(_map[tempTile.yCoord - 1][tempTile.xCoord - 1] != null) 
      { 
       var tile5:Tile =_map[tempTile.yCoord - 1][tempTile.xCoord - 1] 

       if(!tile5.cleared) 
        clearTiles(tempTile.xCoord - 1, tempTile.yCoord - 1); //Check tile to the left 
      } 

      if(_map[tempTile.yCoord + 1][tempTile.xCoord + 1] != null) 
      { 
       var tile6:Tile =_map[tempTile.yCoord + 1][tempTile.xCoord + 1] 

       if(!tile6.cleared) 
        clearTiles(tempTile.xCoord + 1, tempTile.yCoord + 1); //Check tile to the left 
      } 

      if(_map[tempTile.yCoord - 1][tempTile.xCoord + 1] != null) 
      { 
       var tile7:Tile =_map[tempTile.yCoord - 1][tempTile.xCoord + 1] 

       if(!tile7.cleared) 
        clearTiles(tempTile.xCoord + 1, tempTile.yCoord - 1); //Check tile to the left 
      } 


      if(_map[tempTile.yCoord + 1][tempTile.xCoord - 1] != null) 
      { 
       var tile8:Tile =_map[tempTile.yCoord + 1][tempTile.xCoord - 1] 

       if(!tile8.cleared) 
        clearTiles(tempTile.xCoord - 1, tempTile.yCoord + 1); //Check tile to the left 
      } 
     } 
    } 
    else 
     return; 

} 

回答

4

請原諒,如果我搞砸了ActionScript語法功能。我只是喜歡遞歸函數,所以我不得不回答這個問題。我只是將代碼粘貼到我可以調用的最準確的評論中。如果您有問題,請詢問。我敢肯定,你可以轉換成任何你需要將相應的函數調用,屬性引用等

// Function to check if a tile is an empty space and then call 
// itself for the surrounding tiles 

function clearTiles(x:int, y:int):void 
{ 
    // Check if the location we are checking is out of the bounds of the 
    // playable area 
    if (outOfBounds(x, y)) 
    { 
     return; 
    } 

    // Get an object that contains the tile information for the location 
    // we are checking 
    var tempTile:Tile = _map[x][y]; 


    // If the tile has already been revealed then there is nothing to do 
    if (tempTile.cleared) 
    { 
     return; 
    } 

    // If the tile is a number then reveal it and return without checking 
    // surrounding tiles 
    var tempTileMask:DisplayObject = getTileMask(x,y); 
    // since we're no longer in the click handler context, we need 
    // to initialize the variable with something [TODO] 
    if (tempTile.hasNumber) 
    { 
     removeChild(tempTileMask); 
     tempTile.cleared = true; 
     return; 
    } 


    // If the tile hasn't been revealed and it's an empty square we 
    // reveal the location then call this function again for each 
    // surrounding block 

    if (tempTile.isEmpty) 
    { 
     // Remove the mask hiding the tiles property 
     removeChild(tempTileMask); 
     // Set the tile as cleared 
     tempTile.cleared = true; 

     clearTiles(tempTile.x - 1 , tempTile.y); //Check tile to the left 
     clearTiles(tempTile.x + 1 , tempTile.y); //Check tile to the right 
     clearTiles(tempTile.x , tempTile.y - 1); //Check tile above 
     clearTiles(tempTile.x , tempTile.y + 1); //Check tile below 
    } 

} 

你必須創建一個outOfBounds()函數只檢查如果X和被檢查Y爲大比現在的遊戲板。它看起來像引用_gridSize作爲一個靜態數字,所以我假設所有的遊戲板都是正方形(例如:4x4,9x9,120x120)。在這種情況下,你可以使用這樣的事情:

function outOfBounds(int x, int y) 
{ 
    if (x < 0) 
    { 
     return true; 
    } 

    if (y < 0) 
    { 
     return true; 
    } 

    if (x > _gridSize - 1) 
    { 
     return true; 
    } 

    if (y > _gridSize -1) 
    { 
     return true; 
    } 

    return false; 
} 
+0

你是什麼意思由tempTile.outOfBounds()?這是我需要編寫的函數,還是閃存的一部分,我不知道檢查數組的邊界? – user3523222

+0

我只是添加了一個編輯來幫助澄清。我有很多崩潰的經驗,因爲我引用了超出數組邊界的數組元素。所以在處理數組時,我現在要做的第一件事就是確保我沒有引用不存在的東西。我給你的代碼絕對不能複製粘貼,但希望你看到我是如何構建遞歸函數的,你可以傳遞你認爲合適的任何參數。 –

+0

我與您的代碼存在問題,它將清除一些相鄰的地塊,既沒有地雷也沒有數字,但不是所有相鄰的地塊 – user3523222