我知道有一些Tic Tac Toe问题,但逻辑取决于所使用的模型,我对获胜者模型的检查似乎有所不同。我可以插入一个else语句或if循环来检查我在底部评论 的情况吗?在我的模型中,我可以简单地检查一下是否胜利者!= letterX&& letterO做了“Game is a Tie”提醒。我没有IDEA如何做到这一点。感谢
func fieldTapped(recognizer:UITapGestureRecognizer){
let tappedField = recognizer.view as TTTImageView //
if turn == "deviceA" || turn == "yourTurn"{
tappedField.setPlayer(currentPlayer)
let messageDict = ["field":tappedField.tag, "player":currentPlayer, "turnString":"deviceA"]
let messageData = NSJSONSerialization.dataWithJSONObject(messageDict, options: NSJSONWritingOptions.PrettyPrinted, error: nil)
let data = messageData
// do something with the returned data
var error: NSError?
appDelegate.mpcHandler.session.sendData(data, toPeers: appDelegate.mpcHandler.session.connectedPeers, withMode: MCSessionSendDataMode.Unreliable, error:&error)
if error != nil{
println("error:\(error?.localizedDescription)")
}
}
checkResults()
turn = "deviceB"
}
func setupField(){
for index in 0...fields.count - 1{
let gestureRecognizer = UITapGestureRecognizer(target: self, action: "fieldTapped:")
gestureRecognizer.numberOfTapsRequired = 1
fields[index].addGestureRecognizer(gestureRecognizer)
}
}
func resetField(){
for index in 0...fields.count - 1 {
fields[index].image = nil
fields[index].activated = false
fields[index].player = ""
}
currentPlayer = "letterX"
}
@IBAction func newGame(sender: AnyObject) {
resetField()
let messageDict = ["string":"New Game"]
let messageData = NSJSONSerialization.dataWithJSONObject(messageDict, options: NSJSONWritingOptions.PrettyPrinted, error: nil)
var error:NSError?
appDelegate.mpcHandler.session.sendData(messageData, toPeers: appDelegate.mpcHandler.session.connectedPeers, withMode: MCSessionSendDataMode.Reliable, error: &error)
if error != nil{
println("error: \(error?.localizedDescription)")
}
}
func checkResults(){
var winner = ""
if fields[0].player == "letterX" && fields[1].player == "letterX" && fields[2].player == "letterX"{
winner = "letterX"
}else if fields[0].player == "letterO" && fields[1].player == "letterO" && fields[2].player == "letterO"{
winner = "letterO"
}else if fields[3].player == "letterX" && fields[4].player == "letterX" && fields[5].player == "letterX"{
winner = "letterX"
}else if fields[3].player == "letterO" && fields[4].player == "letterO" && fields[5].player == "letterO"{
winner = "letterO"
}else if fields[6].player == "letterX" && fields[7].player == "letterX" && fields[8].player == "letterX"{
winner = "letterX"
}else if fields[6].player == "letterO" && fields[7].player == "letterO" && fields[8].player == "letterO"{
winner = "letterO"
}else if fields[0].player == "letterX" && fields[3].player == "letterX" && fields[6].player == "letterX"{
winner = "letterX"
}else if fields[0].player == "letterO" && fields[3].player == "letterO" && fields[6].player == "letterO"{
winner = "letterO"
}else if fields[1].player == "letterX" && fields[4].player == "letterX" && fields[7].player == "letterX"{
winner = "letterX"
}else if fields[1].player == "letterO" && fields[4].player == "letterO" && fields[7].player == "letterO"{
winner = "letterO"
}else if fields[2].player == "letterX" && fields[5].player == "letterX" && fields[8].player == "letterX"{
winner = "letterX"
}else if fields[2].player == "letterO" && fields[5].player == "letterO" && fields[8].player == "letterO"{
winner = "letterO"
}else if fields[0].player == "letterX" && fields[4].player == "letterX" && fields[8].player == "letterX"{
winner = "letterX"
}else if fields[0].player == "letterO" && fields[4].player == "letterO" && fields[8].player == "letterO"{
winner = "letterO"
}else if fields[2].player == "letterX" && fields[4].player == "letterX" && fields[6].player == "letterX"{
winner = "letterX"
}else if fields[2].player == "letterO" && fields[4].player == "letterO" && fields[6].player == "letterO"{
winner = "letterO"
}
if winner != ""{
let alert = UIAlertController(title: "Tic Tac Toe", message: "The winner is \(winner)", preferredStyle: UIAlertControllerStyle.Alert)
alert.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.Default, handler: { (alert:UIAlertAction!) -> Void in
self.resetField()
}))
self.presentViewController(alert, animated: true, completion: nil)
}
if winner != "letterX" && "letterO" {
let alert = UIAlertController(title: "Tic Tac Toe", message: "Tie Game", preferredStyle: UIAlertControllerStyle.Alert)
alert.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.Default, handler: { (alert:UIAlertAction!) -> Void in
self.resetField()
}))
self.presentViewController(alert, animated: true, completion: nil)
}
答案 0 :(得分:0)
在底部你有:
if winner != "letterX" && "letterO" {
...
}
尝试将其更改为:
if winner != "letterX" && winner != "letterO" {
...
}
答案 1 :(得分:0)
您遇到的问题是您的测试的逻辑结果
winner != "letterX" && "letterO"
等于运算符==和!=优先于&&逻辑上,所以它首先以这种方式评估:
winner != "letterX"
这将导致逻辑真或假。让我们说它是真的然后评估的下一部分继续这样:
true && "letterO"
您可以看到问题所在。运算符有一个优先顺序,但如果有疑问,只需使用括号。
if ( ( winner != "letterX" ) && ( winner != "letterO" ) )
让我们说赢家等于" sdfds"这将评估为:
if ( ( true ) && ( true ) )
使得在需要时更容易跟踪和调试。
=========基于GIT CODE的其他答案=======
我检查了您的Git以及您发生的问题,因为在其他设备的应用中检查可以在来自传入消息的字段被激活之前给出正的连接条件。我认为,不是在该协议中添加更多检查,而是通过保持一定数量的游戏来增加一个自己的游戏或者来自其他设备中的水龙头的消息并将其用作测试。这样,当没有赢家并且你已经完成了所有可能的游戏时(numberOfPlays> = 9)那么它就是平局。
将此添加到viewcontroller类
var turn:String!
var numberOfPlays = 0 // number of plays counter
在此处添加:
fields[field!].player = player
fields[field!].setPlayer(player!)
numberOfPlays++ // there was a tap in the other device
也在这里:
if turn == "deviceA" || turn == "yourTurn"{
tappedField.setPlayer(currentPlayer)
numberOfPlays++ // we tapped on our device
也在resetField()中:
func resetField(){
for index in 0...fields.count - 1 {
//println(index, fields.count)
fields[index].image = nil
fields[index].activated = false
fields[index].player = ""
}
numberOfPlays = 0 // rest counter to zero
currentPlayer = "letterX"
}
并从checkResults()函数中删除整个func handlePotentialTie()并将其替换为
if winner == "" {
if numberOfPlays >= 9 { //there is no winner and you've done all possible plays then it's a tie
let alert = UIAlertController(title: "Tic Tac Toe", message: "Tie Game", preferredStyle: UIAlertControllerStyle.Alert)
alert.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.Default, handler: { (alert:UIAlertAction!) -> Void in
self.resetField()
}))
self.presentViewController(alert, animated: true, completion: nil)
resetField()
}
}
我开始玩了它,非常酷。
答案 2 :(得分:0)
正如其他答案所指出的那样,你说winner != "letterX" && "letterO"
,你需要说winner != "letterX" && winner != "letterO"
。但是你的代码还有其他一些问题。您无法辨别领带游戏和尚未结束的游戏之间的区别,这意味着您将在第一步之后将游戏称为平局。此外,你在整个地方重复了一些字符串,你正在以非常重复的方式检查胜利。这两件事都容易出错。让我们解决这些问题。
我们应该为玩家字符串和电路板大小定义常量:
class TicTacToeController {
let X = "X"
let O = "O"
let boardSize = 3
var fields: [Field]
init() {
fields = [Field](count: boardSize * boardSize, repeatedValue: Field())
}
为什么要定义一个包含X
的名为"X"
的常量?因为如果我们在某处错误地将X
错误地归类为Y
,编译器会报告错误,但如果我们错误地将"X"
错误地指定为"Y"
,我们将不得不弄清楚错误是什么在运行时。
在checkResults
中,我们需要处理游戏的四种可能状态:
func checkResults() {
if handlePotentialWinForPlayer(X) { return }
if handlePotentialWinForPlayer(O) { return }
if handlePotentialTie() { return }
switchTurnsAndContinueGame()
}
要检查玩家是否获胜,我们会检查获胜行,获胜列或获胜对角线:
func handlePotentialWinForPlayer(p: String) -> Bool {
if playerHasWon(p) {
// End game and announce that player p has won...
return true
} else {
return false
}
}
func playerHasWon(p: String) -> Bool {
for i in 0..<boardSize {
// Check column i
if player(p, hasWonWithStartingIndex: i, stride: boardSize) { return true }
// Check row i
if player(p, hasWonWithStartingIndex: i * boardSize, stride: 1) { return true }
}
// Check diagonal shaped like \
if player(p, hasWonWithStartingIndex: 0, stride: boardSize+1) { return true }
// Check diagonal shaped like /
if player(p, hasWonWithStartingIndex: boardSize-1, stride: boardSize-1) { return true }
return false
}
依靠辅助函数来实际检查获胜的运行:
func player(player: String, hasWonWithStartingIndex start: Int, stride: Int) -> Bool {
for i in 0..<boardSize {
if fields[start + i * stride].player != player {
return false
}
}
return true
}
要检查平局,我们会看到该板是否还有空白字段。如果所有字段都已填写,则必须是平局(因为我们已经检查过并且没有找到胜利):
func handlePotentialTie() -> Bool {
if contains(fields, { $0.player == "" }) {
// An empty field: the game isn't over.
return false
} else {
// No empty fields: the game is over and must be a tie.
// End game and announce the tie.
return true
}
}