2017-04-18 51 views
1

我打開了幾年前寫過的一個簡單的MineSweeper程序,如果你可以優化下面的代碼,那麼它就會受到干擾,因爲它看起來並不好看。如何在給定索引周圍的bool [,]中計算真實值?

以下方法是用於檢查所述索引不超出範圍並返回請求的索引的值:

private static bool IsMineOnCoords(bool[,] field, int posI, int posJ) 
{ 
    if (posI < 0 || posI > field.GetLength(0) - 1 || posJ < 0 || posJ > field.GetLength(1) - 1) return false; 
    return field[posI, posJ]; 
} 

我把這種方法用於在8圍繞一個給定索引的每個位置如果陳述:

int count = 0; 

if (IsMineOnCoords(field, posI + 1, posJ)) count++; 
if (IsMineOnCoords(field, posI - 1, posJ)) count++; 
if (IsMineOnCoords(field, posI + 1, posJ + 1)) count++; 
if (IsMineOnCoords(field, posI + 1, posJ - 1)) count++; 
if (IsMineOnCoords(field, posI - 1, posJ + 1)) count++; 
if (IsMineOnCoords(field, posI - 1, posJ - 1)) count++; 
if (IsMineOnCoords(field, posI, posJ + 1)) count++; 
if (IsMineOnCoords(field, posI, posJ - 1)) count++; 

有沒有更好的辦法,我可以做到這一點?

回答

2

像這樣的東西應該爲你工作。基本上,你只要通過這些細胞找出最小值和最大值周圍細胞的ij座標,然後循環,增加了true值(但跳過被傳遞的細胞):

private static int GetSurroundingBombCount(bool[,] field, int posI, int posJ) 
{ 
    var surroundingBombCount = 0; 

    // Get the minimum and maximum i and j coordinates of the surrounding cells 
    var iMin = posI - 1 < 0 ? 0 : posI - 1; 
    var iMax = posI + 1 > field.GetUpperBound(0) ? posI : posI + 1; 
    var jMin = posJ - 1 < 0 ? 0 : posJ - 1; 
    var jMax = posJ + 1 > field.GetUpperBound(1) ? posJ : posJ + 1; 

    // Loop through these cells and increment our counter for each true value 
    // unless we hit the initial cell, in which case we just continue 
    for (int i = iMin; i <= iMax; i++) 
    { 
     for (int j = jMin; j <= jMax; j++) 
     { 
      if (i == posI && j == posJ) continue; 
      if (field[i, j]) surroundingBombCount++; 
     } 
    } 

    return surroundingBombCount; 
} 

然後使用看起來像:

int surroundingBombCount = GetSurroundingBombCount(field, posI, posJ); 

我用這個代碼來測試它,它產生一個3x3的網格(您可以將其調整到任何你想要的),放置在細胞上,然後顯示隨機炸彈兩個網格,以便您可以直觀地檢查它們:一個網格與炸彈位置,另一個網格與c ounts:

private static void Main() 
{ 
    bool[,] field = new bool[3, 3]; 

    Random rnd = new Random(); 

    // The lower this number, the more bombs will be placed. 
    // Must be greater than one, should be greater than 2. 
    // If set to '2', all cells will contain a bomb, which isn't fun. 
    int bombScarcity = 10; 

    // Assign random bombs 
    for (int i = 0; i < field.GetLength(0); i++) 
    { 
     for (int j = 0; j < field.GetLength(1); j++) 
     { 
      field[i, j] = rnd.Next(1, bombScarcity) % (bombScarcity - 1) == 0; 
     } 
    } 

    // Show bomb locations 
    Console.WriteLine("\nBomb Locations:\n"); 

    for (int i = 0; i < field.GetLength(0); i++) 
    { 
     for (int j = 0; j < field.GetLength(1); j++) 
     { 
      Console.Write(field[i, j] ? " T" : " F"); 
      if ((j + 1) % field.GetLength(1) == 0) Console.WriteLine(); 
     } 
    } 

    // Show bomb counts 
    Console.WriteLine("\nBomb Counts:\n"); 

    for (int i = 0; i < field.GetLength(0); i++) 
    { 
     for (int j = 0; j < field.GetLength(1); j++) 
     { 
      Console.Write($" {GetSurroundingBombCount(field, i, j)}"); 
      if ((j + 1) % field.GetLength(1) == 0) Console.WriteLine(); 
     } 
    } 

    Console.Write("\nDone!\nPress any key to exit..."); 
    Console.ReadKey(); 
} 

輸出

enter image description here

而一個有趣的10×10:

enter image description here

+1

增加了一個 「bombScarcity」 變量調整(炸彈的數量因此難度級別)。在我看來,投擲太多的炸彈會造成太多的炸彈,而用戶沒有得到點擊單元格的巨大感覺,並且看到整個空白單元格的空間打開。 :) –

0

使用這樣的事情:

for (int i = posI - 1; i <= posI + 1; i++) 
{ 
    for (int j = posJ - 1; j <= posJ + 1; j++) 
    { 
     if (!(i == posI && j == posJ) && IsMineOnCoords(field, i, j)) 
     { 
      count++; 
     } 
    } 
} 
1

我認爲這是好的,因爲據我所知,應該執行,特別是因爲短路的快。

條件OR運算符(||)執行其bool操作數的邏輯OR。如果第一個操作數的計算結果爲真,則不計算第二個操作數。如果第一個操作數的計算結果爲false,則第二個運算符將確定OR表達式是否爲真或假。

https://msdn.microsoft.com/en-us/library/6373h346.aspx

相關問題