

プログラミング初心者です。  
今趣味でゲームを作っていてわからないことがいくつかあり質問させていただきました。

下の4色はボタンになっています。(今度5色に増やす予定です。)  
各色ボタンを押すごとにタッチしたマス目に押したボタンの色を反映できます。

１  
アプリのタスクを切るとまた初めからになってしまいます。  
NSUserDefaultsでマス目の色をスマホ本体に保存して、アプリのタスクを切っても続きから始められるようにしたいです。  
その場合マス目をタッチするたび保存にすれば大丈夫ですか？  
また、色を保存する時はどのようなコードを書けばよろしいでしょうか？

２  
すべてのマス目を埋めた時、隣り合ったマス目の色が違う場合のみゲームクリアにしたいです。  
隣り合ったマス目の色が一致した場合は何も起こらず、すべての隣り合うマス目の色が違う場合のみ  
画面移行し「ゲームクリア」にしたいです。  
この場合マス目ごとにTagを振ればよろしいでしょうか？  
またこの条件のコードはどのように書けばいいでしょうか？

以上の２点です。  
１度に２つもしてしまい申し訳有りません。  
この２点は今の自分ではわからないので教えてもらいたいです。

どちらもコードを書いていただくと非常に助かります。  
一応今書いてあるコードと画像を載せておきます。

質問がわかりにくくて申し訳有りません。

回答お待ちしています。

[![画像の説明をここに入力](https://i.stack.imgur.com/r597N.png)](https://i.stack.imgur.com/r597N.png)

[code]

             myImageA = UIColor.redColor();
             myImageB = UIColor.greenColor();
             myImageC = UIColor.blueColor();
             myImageE = UIColor.yellowColor();
    
    
            myImageView.backgroundColor = myImageD
            myImageView2.backgroundColor = myImageD
            myImageView3.backgroundColor = myImageD
            myImageView4.backgroundColor = myImageD
            myImageView5.backgroundColor = myImageD
            myImageView6.backgroundColor = myImageD
    
            myImageView8.backgroundColor = myImageD
            myImageView9.backgroundColor = myImageD
            myImageView10.backgroundColor = myImageD
            myImageView11.backgroundColor = myImageD
            myImageView12.backgroundColor = myImageD
            myImageView13.backgroundColor = myImageD
             myImageView14.backgroundColor = myImageD
            myImageView15.backgroundColor = myImageD
            myImageView16.backgroundColor = myImageD
    
            myImageViewa.backgroundColor = myImageD
            myImageView2a.backgroundColor = myImageD
            myImageView3a.backgroundColor = myImageD
            myImageView4a.backgroundColor = myImageD
            myImageView5a.backgroundColor = myImageD
            myImageView6a.backgroundColor = myImageD
            myImageView7a.backgroundColor = myImageD
            myImageView8a.backgroundColor = myImageD
            myImageView9a.backgroundColor = myImageD
            myImageView10a.backgroundColor = myImageD
            myImageView12a.backgroundColor = myImageD
            myImageView14a.backgroundColor = myImageD
            myImageView13a.backgroundColor = myImageD
            myImageView15a.backgroundColor = myImageD
            myImageView16a.backgroundColor = myImageD
    
            myImageViewb.backgroundColor = myImageD
            myImageView2b.backgroundColor = myImageD
            myImageView3b.backgroundColor = myImageD
            myImageView4b.backgroundColor = myImageD
            myImageView5b.backgroundColor = myImageD
            myImageView6b.backgroundColor = myImageD
            myImageView7b.backgroundColor = myImageD
            myImageView8b.backgroundColor = myImageD
            myImageView9b.backgroundColor = myImageD
            myImageView10b.backgroundColor = myImageD
            myImageView11b.backgroundColor = myImageD
            myImageView13b.backgroundColor = myImageD
            myImageView14b.backgroundColor = myImageD
            myImageView15b.backgroundColor = myImageD
            myImageView16b.backgroundColor = myImageD
    
    
            myImageView2c.backgroundColor = myImageD
            myImageView3c.backgroundColor = myImageD
            myImageView4c.backgroundColor = myImageD
            myImageView5c.backgroundColor = myImageD
            myImageView6c.backgroundColor = myImageD
            myImageView7c.backgroundColor = myImageD
            myImageView8c.backgroundColor = myImageD
            myImageView9c.backgroundColor = myImageD
            myImageView10c.backgroundColor = myImageD
            myImageView11c.backgroundColor = myImageD
            myImageView12c.backgroundColor = myImageD
            myImageView13c.backgroundColor = myImageD
            myImageView14c.backgroundColor = myImageD
            myImageView15c.backgroundColor = myImageD
            myImageView16c.backgroundColor = myImageD
    
    
    
    
    
    
        }
    
    
    
        func onClickMyButton(sender: UIButton){
    
    
            myImageD = myImageA
    
    
            }
    
    
        func onClickMyButton2(sender: UIButton){
    
            myImageD = myImageB
    
            }
    
    
        func onClickMyButton3(sender: UIButton){
    
            myImageD = myImageC
    
        }
    
        func onClickMyButton4(sender: UIButton){
    
            myImageD = myImageE
    
        }
    
    
        override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
            let touch = touches.first as UITouch?
    
            if let touchedImageView = touch!.view as? UIImageView {
    
                touchedImageView.backgroundColor = myImageD
    
    
            }
    
    
    
    
        }
    
    
    
    
    
    
        override func didReceiveMemoryWarning() {
            super.didReceiveMemoryWarning()
            // Dispose of any resources that can be recreated.
        }
    
    
    }
    
[/code]

保存する色が4つあるのでその分forkeyも4つ用意したほうがいいですか？  
forkeyが１つだと保存した場所の色がすべて同じ色になってしまいませんか？


CC BY-SA 4.0
2016-01-26T11:18:54.153
21341
2019-06-05T17:30:49.897
2019-06-05T17:30:49.897
32986
11019
question
ios swift iphone swift2
NSUserDefaultsで背景色を保存する方法とゲームクリア条件のコードの書き方を教えてください。


_説明量が大量になるので、数日かけて回答していく予定です。_

> NSUserDefaultsでマス目の色をスマホ本体に保存して、アプリのタスクを切っても続きから始められるようにしたいです。

`NSUserDefaults`クラスの使い方を説明します。  
まず、`NSUserDefaults.standardUserDefaults()`で、 **シングルトン**
（Singleton）として、インスタンスを呼び出します。`NSUserDefaults`にデータを保存するには、

[code]

    defaults.setObject("a text value", forKey: "value")
    
[/code]

このようなメソッドを送ります。整数値、実数値、`NSDate`インスタンスなど、型によってメソッドが異なりますから、詳しくはクラスリファレンスを調べてください。  
`NSUserDefaults`は、適切なタイミングで書き加えられたデータを、ファイルに保存しますが、強制的にファイル保存する必要があるときは、`synchronize()`というメソッドを使います。  
`NSUserDefaults`からデータを読み出すには、

[code]

    let theText = defaults.stringForKey("value")
    
[/code]

というメソッドを使います。これも型によって、メソッドが異なりますから、クラスリファレンスで調べてください。  
注意しなければいけないのは、
**`UIColor`のインスタンスは、`NSUserDefaults`に保存できない**点です。`NSuserDefaults`に保存可能な型（クラス）は限定的で、保存できないのは、`UIColor`だけではありません。色情報は、整数値や文字列に一対一対応させて置き換えてから、`NSUserDefaults`に保存する必要があります。  
一対一対応は、列挙体（`enum`）を使うと便利です。

[code]

    enum Color: Int {
        case White = 0
        case Red
        case Blue
        case Green
        case Yellow
    
        func color() -> UIColor {
            switch self {
            case .White :
                return UIColor.whiteColor()
            case .Red :
                return UIColor.redColor()
            case .Blue :
                return UIColor.blueColor()
            case .Green :
                return UIColor.greenColor()
            case .Yellow :
                return UIColor.yellowColor()
            }
        }
    }
    
[/code]

白＝0、赤＝1、青＝2、緑＝3、黄＝4という対応をしており、`UIColor`とも対応します。

[code]

    // 色の整数値を取得。
    let colorNumber: Int = Color.Blue.rawValue
    // 色のUIColorを取得。
    let colorValue: UIColor = Color.Red.color()
    
[/code]

◉ _2016/1/28 追記_

今回の件では、8×8=64個のマス目の色情報を保存しなければなりませんから、配列を使って、配列を保存することを考えましょう。  
まず、色情報を`Int`値に置き換えた、8×8の二次元配列`matrix`をインスタンス変数とします。

[code]

    var matrix: [[Int]]
    
[/code]

これを`NSUserDefaults`に保存するには、

[code]

    let defaults = NSUserDefaults.standardUserDefaults()
    defaults.setObject(matrix, forKey: "Matrix")
    
[/code]

保存した配列を呼び出すには、

[code]

    let defaults = NSUserDefaults.standardUserDefaults()
    if let theArray = defaults.arrayForKey("Matrix") as? [[Int]] {
        matrix = theArray
    }
    
[/code]

`arrayForKey()`の返り値は、Optional型です。アプリの最初の起動などで、`NSUserDefaults`に保存されていないと、`nil`を返します。`nil`チェックと、適切な配列の型へのダウンキャストが必要です。

◉ _追記ここまで_

どういうタイミングで`NSUserDefaults`にデータを保存するかは、プログラマの設計（デザイン）しだいで、単一の正解はないと思います。「マス目をタッチするたび保存にす」れば、いちばん心配ないですが、コードが煩雑になり、記述漏れによるバグの発生が起きやすいというリスクがあります。

> すべてのマス目を埋めた時、隣り合ったマス目の色が違う場合のみゲームクリアにしたいです。

そのためには、まず隣のマス目を取得することができるプログラムデータの構造を、設計しなければいけません。現状その設計ができていないので、どうすればいいのか、さっぱりわからない状態になっています。  
ふつうに考えれば、8×8のマス目を、二次元配列で表現する設計を思いつきます。先ほどの列挙体`Color`を使って、`Int`型を要素とする8×8の配列を作りましょう。

[code]

    var matrix = [[Int]](count: 8, repeatedValue: [Int](count: 8, repeatedValue: 0))
    
[/code]

n行m列の要素を、`matrix[m][n]`で取得できますが、隣の要素は、

[![画像の説明をここに入力](https://i.stack.imgur.com/GgUpE.png)](https://i.stack.imgur.com/GgUpE.png)

このように取得できます。（端にあるマス目の場合、隣のマス目がないことがあることには、注意してください。範囲外の配列の要素を参照しようとすると、プログラムがクラッシュします。）


CC BY-SA 3.0
2016-01-27T11:23:19.303
21391
2016-01-28T10:19:38.710
2016-01-28T10:19:38.710
7362
7362
21341
answer