2015-07-20 70 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来标识数字或者使用一些数据结构来为你存储这些信息。 –