I am making a tic tac toe game in Swift for 2 players. Now I know I can find a winner by making outlets for the 9 buttons and then writing for all the 3 in row cases, but I was wondering if there is a better way to do this? And is there a better way to write my switch statement?
ReDim Apps(size - 1)
For i = 1 To size
Apps(i - 1) = Cells(i, 1).Value
Next i
答案 0 :(得分:2)
我会在按钮上使用值0-9设置[ 0 ][ 1 ][ 2 ]
[ 3 ][ 4 ][ 5 ]
[ 6 ][ 7 ][ 8 ]
属性,按从上到下,从左到右的顺序排列,如下所示:
viewForTag(_:)
然后创建一个模型来表示每个方块并给它一个相应的索引值,以及对拥有它的玩家的引用。然后,您可以使用这些模型处理游戏逻辑,并通过使用class Square {
var owningPlayer: Player?
let index: Int
init( index: Int ) {
self.index = index
}
}
class Player {
let symbol: String
init( symbol: String ) {
self.symbol = symbol
}
}
class ViewController: UIViewController {
var squares = [Square]()
var players = [Player]()
var currentPlayer: Player?
override func viewDidLoad() {
super.viewDidLoad()
self.players = [ Player(symbol: "X"), Player(symbol: "O") ]
self.currentPlayer = self.players[0]
// Create squares
for i in 0..<9 {
self.squares.append( Square(index: i) )
}
}
@IBAction func buttonPressed( button: UIButton ) {
guard let player = self.currentPlayer else {
fatalError( "Don't have a current player!" )
}
if let square = self.squares.filter({ $0.index == button.tag }).first {
// Update model
square.owningPlayer = player
// Update UI
button.setTitle( player.symbol, forState: .Normal )
}
if self.checkWin() {
print( "\(player.symbol) wins!" )
}
else {
self.currentPlayer = self.players.filter({ $0 !== player }).first
}
}
func checkWin() -> Bool {
guard let player = self.currentPlayer else {
fatalError( "Don't have a current player!" )
}
let winningSequences = [
// Horizontal rows
[ 0, 1, 2 ],
[ 3, 4, 5 ],
[ 6, 7, 8 ],
// Diagonals
[ 0, 4, 8 ],
[ 2, 4, 6 ],
// Vertical rows
[ 0, 3, 6 ],
[ 1, 4, 7 ],
[ 2, 5, 8 ],
]
// Get indexes owned by this player
let selectedIndexes = self.squares.filter({ $0.owningPlayer === player }).map { $0.index }
// Change the sequence arrays into sets for accurate comparison using `contains(_:)`
if winningSequences.map({ Set<Int>($0) }).contains( Set<Int>(selectedIndexes) ) {
return true
}
return false
}
}
获取对按钮的引用来更新UI。这是我的版本:
if(Boolean){
if(Boolean) something();
else if(Boolean) something();
else something();
}
答案 1 :(得分:0)
虽然@Patrick Lynch的答案非常出色,但我发现如果比赛超过3次,它就无法与胜利相提并论。
这是因为他只检查任何winsSequences是否包含当前移动序列(selectedIndexes)。由于winsSequences地图最多只有3个项目,因此它永远不会包含一组4个动作。
要解决此问题,我将包含更改为子集。即winsSequence(0,1,2)selectedIndexes(0,5,1,2)的子集
替换
if winningSequences.map({ Set<Int>($0) }).contains( Set<Int>(selectedIndexes) ) {
return true
}
与
for seq in winningSequences.map( { Set<Int>($0)}) {
if seq.isSubset(of: selectedIndexes) {
return true
}
}
我还是新手,所以如果我错了或任何人有更好的主意,那么我会很高兴听到它。