2015-07-20 36 views
0

我正在製作一個棋盤遊戲,其中每個斑點都是一個按鈕。除了我想要檢測勝利之外,一切工作都應該如此。我的板子高5個,寬4個。所以20個按鈕。他們的名字是這樣的:如何檢查我的遊戲陣列陣列

0 1 2 3 

4 5 6 7 

8 9 10 11 

12 13 14 15 

16 17 18 19 

我做了一個包含所有可能勝利的數組數組。按鈕上有一些圖片,你必須連續獲取三張圖片。這裏是我的數組陣列的勝利

      // horizontal wins 
var winList: [[Int]] = [ [0,1,2], [1,2,3], 
          [4,5,6], [5,6,7], 
          [8,9,10], [9,10,11], 
          [12,13,14], [13,14,15], 
          [16,17,18], [17,18,19], 

          // vertical wins 
          [0,4,8], [4,8,12], [8,12,16], 
          [1,5,9], [5,9,13], [9,13,17], 
          [2,6,10], [6,10,14], [10,14,18], 
          [3,7,11], [7,11,15], [11,15,19], 

          // right diagonal wins 
          [2,5,8], [3,6,9], [6,9,12], 
          [7,10,13], [10,13,16], [11,14,17], 

          // left diagonal wins 
          [1,6,11], [0,5,10], [5,10,15], 
          [4,9,14], [9,14,19], [8,13,18]] 

我有一個名爲checkForWin的空函數。我該如何檢查是否有任何標題按鈕與winList中的某個模式相匹配。爲了獲勝,他們都應該在按鈕上有相同的圖像。

我之前在法律上採取了類似的行動。我有一個數組的數組。這裏是我的函數之前:

func checkIfValidMove(moveFromButton: UIButton, moveToButton: UIButton) -> Bool { 
     var moveFromButtonTitle = moveFromButton.currentTitle 
     var moveToButtonTitle = moveToButton.currentTitle 
     var moveFromButtonTitleInt = moveFromButtonTitle?.toInt() 
     var moveToButtonTitleInt = moveToButtonTitle?.toInt() 
     if moveToButton.imageView!.image != UIImage(named:"NoPiece.png") { 
      return false 
     } else { 
      if contains(moveList[moveFromButtonTitleInt!], moveToButtonTitleInt!) { 
       return true 
      } else { 
       return false 
      } 
     } 
    } 

這裏是我的合法舉動變量:

var moveList: [[Int]] = [ [1,4],  [0,2,5],  [1,3,6],  [2,7], 
          [0,5,8], [1,4,6,9],  [2,5,7,10],  [3,6,11], 
          [4,9,12], [5,8,10,13], [6,9,11,14], [7,10,15], 
          [8,13,16], [9,12,14,17], [10,13,15,18], [11,14,19], 
          [12,17], [13,16,18],  [14,17,19],  [15,18]] 

任何幫助表示讚賞!感謝您的時間!

+2

這是一個定義如何贏的可怕方式。你應該定義更多動態的東西 –

回答

1

黃晨的評論讓我想到了如何做到這一點更聰明的方法,而不僅僅是定義巨大的數組。你的解決方案的問題是顯而易見的 - 如果你想要增加遊戲板的尺寸或者只是改變尺寸,你將不得不重建你的定義文件。另外,當增加「按鈕」數量時,可能的組合數量將呈指數增長。當然,這意味着你將不得不爲小板執行瘋狂的迭代次數,更不用說10x10之類的東西了。

模式

不過想想這不同的方式,如果你能在你的定義中找到的圖案是什麼?然後,它會使它更容易。當你看到你的定義時,是否有一些相似之處?是的,有!

  • 似乎一切都按升序排列,這是良好的開端
  • 一切都按相同的量的增加!
  • 對於水平勝,一切都必須在同一行上,並且必須有數字之間1個差
  • 對於垂直勝,一切都必須在同一列上,並且必須有數字
  • 對於對角線4之間的差異,那些必須是3或5的差異序列,它也必須有行的序列,所以每個數字開始在下一行,只在下一行

所以,當你看到這是真實的對於每一種模式,但對其他所有模式都不是這樣,你可以清楚地看到,一切都只是簡單的加法序列,我們可以做算法,t帽子會檢查所有的模式,不使用你的定義?我們需要的是一些方法:

檢查號碼順序:

func isSequence3(selection : [Int], allowedDifference : Int) -> Bool { 

    // Check if difference between [10] is the same as [21], which makes sequence. Also, check for value of that difference 
    let difference10 = selection[1] - selection[0] 
    let difference21 = selection[2] - selection[1] 
    return difference10 == difference21 && difference10 == allowedDifference 
} 

檢查數量在不同行,連續:

func isRowSequence(selection : [Int], rowSize : Int) -> Bool { 

    var currentRow = (selection[0]/rowSize) - 1 
    for number in selection { 
     // Check if row is increasing by one in each step, if yes, remember last row 
     if number/rowSize - currentRow == 1 { 
      currentRow++ 
     } else { 
      return false 
     } 
    } 

    // It is row Sequence 
    return true 
} 

檢查號碼在同一行上,並在同一列上:

func isOnSameRow(selection : [Int], rowSize : Int) -> Bool { 

    return selection.first!/rowSize == selection.last!/rowSize 
} 


func isOnSameColumn(selection : [Int], columnSize : Int) -> Bool { 

    let column = selection.first! % columnSize 
    for number in selection { 
     if number % columnSize != column { 
      return false 
     } 
    } 

    return true 
} 

現在,我們有充分的,我們需要的方法,我們只需要驗證方法把所有這些規則一起:

func isValidPattern(selection : [Int]) -> Bool { 

    // Sort user selection first, ascending 
    var ascSelection = selection.sorted(ascending) 

    // Validate for horizontal wins 
    let isValidForHorizontalWins = self.isSequence3(ascSelection, allowedDifference: 1) 
           && self.isOnSameRow(ascSelection, rowSize: ROW_SIZE) 

    // Validate for vertical wins 
    let isValidForVerticalWins = self.isSequence3(ascSelection, allowedDifference: 4) 
          && self.isOnSameColumn(ascSelection, columnSize: COLUMN_SIZE) 

    // Validate for diagonals 
    let isValidForDiagonals = self.isSequence3(ascSelection, allowedDifference: 3) 
          || self.isSequence3(ascSelection, allowedDifference: 5) 
          && self.isRowSequence(ascSelection, rowSize: ROW_SIZE) 

    // Is at least one rule valid? 
    return isValidForHorizontalWins || isValidForVerticalWins || isValidForDiagonals 
} 

這就是它(或至少我覺得應該是,考慮如何後期它是的,我將在明天進行審查,以確保:)無論如何,here is complete gist與所有代碼在一起。通過調整驗證方法中的數字,您可以使其適用於任何您想要的尺寸。還有優化工作要做,但那是爲了你。

末一些提示:

  • 隨時搜索是動態的解決方案。最後,它會爲你節省大量的時間(試圖找出所有的組合..不好玩)
  • 我正在使用Ints,因爲你可能已經注意到了。 UIButton具有.tag變量,您可以在其中分配數字。通過這種方式,您可以輕鬆識別按鈕而不是按圖像,而是通過標籤來識別按鈕,這樣可以使整個解決方案變得更加輕鬆。
0

我不知道如何從UIImage獲取圖像的名稱,所以我將繼承UIButton的子類,以便可以在該按鈕上顯示圖像名稱的字段。之後,只需使用雙重for循環並檢查所有按鈕的圖像名稱。

for win in winList 
{ 
    let name = buttons[win[0]].imageName //imageName is the field in the UIButton subclass 
    var won = true 

    //make sure all the buttons in the win have the same name 
    for i in 1..<win.count 
    { 
     if !buttons[win[i]].imageName.isEqualToString(name) 
     { 
      won = false 
      break 
     } 
    } 

    if won 
    { 
     //do something because a win has been achieved 
    } 
} 
+0

謝謝!我已經想出瞭如何獲取圖像的名稱。謝謝你的幫助! –

+0

雖然它有效,但這是非常糟糕的做法,你不應該遵循。您不應該將UI組件分類以存儲您的信息。你應該使用.tag來標識數字或者使用一些數據結構來爲你存儲這些信息。 –