質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

89.06%

Swiftバグ?ミス?

解決済

回答 1

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 1,128

souroppy

score 44

Swiftで、〜〜をいったら負けゲームのようなものを作ってみたのですが予期せぬ動きがまれに起こります。
まず全文がこんな感じなんですが、たまに、1、23、ボタンを押したときにゼロに戻ってしまったり、すでにtetoがXを超えているのに、ゲームが続けられたりしてしまいます。理由が自分ではわからないのでお教えください。

import UIKit
import SpriteKit

class ViewController: UIViewController {


    @IBOutlet weak var start: UIButton!
    @IBOutlet weak var one: UIButton!
    @IBOutlet weak var two: UIButton!
    @IBOutlet weak var three: UIButton!
    @IBOutlet weak var kekka: UILabel!
    @IBOutlet weak var agote: UILabel!
    @IBOutlet weak var konkai: UILabel!
    @IBOutlet weak var serifu: UILabel!
    @IBOutlet weak var make: UILabel!

    var teto = 0
    var X = 0




    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }


    //開始ボタン
    @IBAction func starta(sender: AnyObject) {
        teto = 0
        self.make.hidden = true
        self.one.hidden = false
        self.two.hidden = false
        self.three.hidden = false
        self.agote.hidden = false
        self.kekka.hidden = false
        self.serifu.hidden = false
        self.konkai.hidden = false
        X = Int(arc4random_uniform(20))+10
        if X % 4 == 1{
            return
        }
        self.start.hidden = true
        konkai.text = String(X)
        if X % 4 == 0 {
            teto = 3
        } else {
            teto = (X-4)%4-1
        }
        agote.text = String(teto)
        kekka.text = String(teto)
    }

    //1ボタン
    @IBAction func onea(sender: AnyObject) {
        teto = teto + 1
        kekka.text = String(teto)
        serifu.text = "考え中"
        self.one.hidden = true
        self.two.hidden = true
        self.three.hidden = true
        if X <= teto {
            make.text = "You have lose"
            self.make.hidden = false
            self.start.hidden = false
            self.one.hidden = true
            self.two.hidden = true
            self.three.hidden = true
            self.agote.hidden = true
            self.kekka.hidden = true
            self.serifu.hidden = true
            self.konkai.hidden = true
        } else {
        let delay = 3 * Double(NSEC_PER_SEC)
        let time = dispatch_time(DISPATCH_TIME_NOW, Int64(delay))
        dispatch_after(time, dispatch_get_main_queue(), {
        self.teto = self.teto + 3
        self.kekka.text = String(self.teto)
        self.agote.text = String(3)
        self.serifu.text = "君の番だよ"
            self.one.hidden = false
            self.two.hidden = false
            self.three.hidden = false
            if self.teto > self.X - 1{
                self.two.hidden = true
                self.three.hidden = true
            }
            if self.teto > self.X - 2{
                self.three.hidden = true
            }
        self.teto = 0
        })
        }

}
    //2ボタン
    @IBAction func twoa(sender: AnyObject) {
        teto = teto + 2
        kekka.text = String(teto)
        serifu.text = "考え中"
        self.one.hidden = true
        self.two.hidden = true
        self.three.hidden = true
        if X <= teto {
            make.text = "You have lose"
            self.make.hidden = false
            self.start.hidden = false
            self.one.hidden = true
            self.two.hidden = true
            self.three.hidden = true
            self.agote.hidden = true
            self.kekka.hidden = true
            self.serifu.hidden = true
            self.konkai.hidden = true
        } else {
        let delay = 3 * Double(NSEC_PER_SEC)
        let time = dispatch_time(DISPATCH_TIME_NOW, Int64(delay))
        dispatch_after(time, dispatch_get_main_queue(), {
            self.teto = self.teto + 2
            self.kekka.text = String(self.teto)
            self.agote.text = String(2)
            self.serifu.text = "君の番だよ"
            self.one.hidden = false
            self.two.hidden = false
            self.three.hidden = false
            if self.teto >= self.X - 1{
                self.two.hidden = true
                self.three.hidden = true
            }
            if self.teto >= self.X - 2{
                self.three.hidden = true
            }
        })
        }
    }
    //3ボタン
    @IBAction func threea(sender: AnyObject) {
        teto = teto + 3
        kekka.text = String(teto)
        serifu.text = "考え中"
        self.one.hidden = true
        self.two.hidden = true
        self.three.hidden = true
        if X <= teto {
            make.text = "You have lose"
            self.make.hidden = false
            self.start.hidden = false
            self.one.hidden = true
            self.two.hidden = true
            self.three.hidden = true
            self.agote.hidden = true
            self.kekka.hidden = true
            self.serifu.hidden = true
            self.konkai.hidden = true
        } else {
        let delay = 3 * Double(NSEC_PER_SEC)
        let time = dispatch_time(DISPATCH_TIME_NOW, Int64(delay))
        dispatch_after(time, dispatch_get_main_queue(), {
            self.teto = self.teto + 1
            self.kekka.text = String(self.teto)
            self.agote.text = String(1)
            self.serifu.text = "君の番だよ"
            self.one.hidden = false
            self.two.hidden = false
            self.three.hidden = false
            if self.teto > self.X - 1{
                self.two.hidden = true
                self.three.hidden = true
            }
            if self.teto > self.X - 2{
                self.three.hidden = true
            }
        })
    }
    }

}

・追記
このゲームは二人(自分とコンピューター)で1〜3(任意)ずつ言っていき、Xの数字を言った人が負けです。今のところ設定は必ずコンピューターが勝つようにしているつもりです。今回の誤作動?は、例えば今の数字が4で次に人が3を押すと7になるはずなのに3(押した数)に戻ってしまいます。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • _Kentarou

    2016/06/10 20:23

    このゲームのルールがそもそも分からないので、バグなのか仕様なのかがハッキリしません。このボタンを押すとこう動くのが正解、こうするとゲームオーバーでこう動く等、細かい仕様を記述してください。

    キャンセル

  • souroppy

    2016/06/10 20:47

    すみません。説明不足でした・・・。

    キャンセル

回答 1

checkベストアンサー

+1

1、23、ボタンを押したときにゼロに戻ってしまったり

こちらの件は1ボタンの相手のターンの最後にself.teto = 0と書いてあるのでカウントがリセットされています。

すでにtetoがXを超えているのに、ゲームが続けられたり

上記のコードを削除して、数回試したところ数がオーバーしてもゲームが続けられるという事はありませんでした。
確認してみてください。


コードの中に同じ様な記述が複数あったのでまとめてみました、参考にしてみてください。

import UIKit
import SpriteKit

class ViewController: UIViewController {

    @IBOutlet weak var start: UIButton!
    @IBOutlet weak var one  : UIButton!
    @IBOutlet weak var two  : UIButton!
    @IBOutlet weak var three: UIButton!

    @IBOutlet weak var kekka : UILabel!
    @IBOutlet weak var agote : UILabel!
    @IBOutlet weak var konkai: UILabel!
    @IBOutlet weak var serifu: UILabel!
    @IBOutlet weak var make  : UILabel!

    var teto = 0
    var X = 0

    //開始ボタン
    @IBAction func starta(sender: AnyObject) {
        teto = 0
        [make].forEach { $0.hidden = true }
        [one, two, three, agote, kekka, serifu, konkai].forEach { $0.hidden = false }

        X = Int(arc4random_uniform(20))+10
        if X % 4 == 1{
            return
        }

        self.start.hidden = true
        konkai.text = String(X)
        if X % 4 == 0 {
            teto = 3
        } else {
            teto = (X-4)%4-1
        }
        agote.text = String(teto)
        kekka.text = String(teto)
    }

    // 1ボタン
    @IBAction func onea(sender: AnyObject) {
        setTeto(player1Teto: 1, player2Teto: 3)
    }

    // 2ボタン
    @IBAction func twoa(sender: AnyObject) {
        setTeto(player1Teto: 2, player2Teto: 2)
    }

    // 3ボタン
    @IBAction func threea(sender: AnyObject) {
        setTeto(player1Teto: 3, player2Teto: 1)
    }

    func setTeto(player1Teto teto1: Int, player2Teto teto2: Int) {
        setPlayer1(teto1)
        if X <= teto {
            gemeOver()
        } else {
            setPlayer2(teto2)
        }
    }

    func setPlayer1(player1Teto: Int) {
        teto += player1Teto
        kekka.text = String(teto)
        serifu.text = "考え中"
        [one, two, three].forEach { $0.hidden = true }
    }

    func setPlayer2(player2Teto: Int) {

        // 3秒後にメインスレッドで実行
        dispatch_async_main_after(3) {
            self.teto += player2Teto
            self.kekka.text = String(self.teto)
            self.agote.text = String(player2Teto)
            self.serifu.text = "君の番だよ"
            [self.one, self.two, self.three].forEach { $0.hidden = false }
            if self.teto > self.X - 1 {
                [self.two, self.three].forEach { $0.hidden = true }
            }
            if self.teto > self.X - 2 {
                self.three.hidden = true
            }
        }
    }

    func gemeOver() {
        make.text = "You have lose"
        [make, start].forEach { $0.hidden = false }
        [one, two, three, agote, kekka, serifu, konkai].forEach { $0.hidden = true }
    }
}

// メインスレッドで遅延実行
func dispatch_async_main_after(minute: Double, block: () -> ()) {
    let delayTime = dispatch_time(DISPATCH_TIME_NOW, Int64(minute * Double(NSEC_PER_SEC)))
    dispatch_after(delayTime, dispatch_get_main_queue(), block)
}

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/06/12 08:12

    解決しました!ありがとうございます!
    次はランダムで数字が出てくるものをつくろうとおもいます。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 89.06%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る