UNITYでクロスワード作成記録



### 目次
[⓪　scratchでプロトタイプを作成](##-⓪scratchでプロトタイプを作成)
[①　dictionaryを用意](##-①dictionaryを用意)
[②　文字を1文字ずつに分けてdictionaryに入れる](##-②文字を1文字ずつに分けてdictionaryに入れる)
[③　inputfieldで入力された文字を1文字ずつdictionaryに登録する](##-③inputfieldで入力された文字を1文字ずつdictionaryに登録する)
[④　inputfieldに入力された文字を、1回目と2回目ので処理変える。](##-④inputfieldに入力された文字を、1回目と2回目ので処理変える。)
[⑤　完成版コード全容](##-⑤完成版コード全容)

## 完成系
![クロスワード.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2959805/b28874fb-2817-f550-86c9-f1351a5a970d.gif)


クロスワードを作る際に必要そうな、以下の機能の実装を試みた。
①入力された文字を辞書型で保存
②入力された文字をkeyを使い指定の位置へ表示
③2週目に入力された文字の処理
　1週目に入力された文字で、重なる部分の文字が一致する場合、指定した位置へ表示

勉強しながら実装したものの備忘録なので、つらつら長い文章になります。
コードだけ欲しい方は[こちら](##-⑤完成版コード全容)へ



## ⓪scratchでプロトタイプを作成
https://scratch.mit.edu/projects/1127364865

## ①dictionaryを用意
scratchのリストの機能をunityで再現したい。
最初、listを使おうかと思ったが、以下の理由よりdictionaryで実装することにした。
理由）scratchの「リストのn番目をhogeで置き換える」の命令を実装するとき、絶対参照できるkeyがあるdictionaryの方が便利。

dicrionaryの使い方を学ぶために、keyを文字位置番号にして、初期の文字を取り出すところまで練習

```
using System.Collections;
using System.Collections.Generic;
using UnityEngine;


public class dicTest : MonoBehaviour
{
    Dictionary<int, string> list = new Dictionary<int, string>();

    void Start()
    {
        list.Add(1,".");
        list.Add(2,".");
        list.Add(3,".");

        foreach (var item in list)
        {
            Debug.Log(item);
        }
    }

}
```
### ①発見まとめ
#### ①dictionaryの使い方
一度keyのデータを削除してからじゃないと、新しくデータを入れられない
#### ②foreachの使い方
↑配列、リスト、辞書などで使える。

＜書き方＞
```
 foreach(変数 in コレクション)
 {
    // 処理
 }
```

＜例＞
```
int[] array = { 0, 1, 2, 3, 4, 5 };
 
foreach(int i in array)
{
    if (i == 2) continue;
    else if (i == 3) break;
 
    Debug.Log(i);
}
```
＜結果＞
「０,１」

“continue;”を記述することで、
それ以降の処理を無視して、次のループへと進むことができる。
“break;”を記述することで、
foreach文を抜ける（終了させる）ことができる。


## ②文字を1文字ずつに分けてdictionaryに入れる

```
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Linq;

public class eachLetterPractice : MonoBehaviour
{
    

    // Start is called before the first frame update
    void Start()
    {
        string word = "apple";
        Dictionary<int, string> charDict = word
            .Select((c, index) => new KeyValuePair<int, string>(index, c.ToString()))
            .ToDictionary(pair => pair.Key, pair => pair.Value);

        foreach (var kvp in charDict)
        {
            Debug.Log($"Key: {kvp.Key}, Value: {kvp.Value}");
        }
    }


}
```
### ②発見まとめ
#### ①C#のLinqについて　[参考記事]（https://qiita.com/shinozakiy/items/e261cbee8e39f776654d）
##### A. selectメソッド
ーリストや配列の各要素を順番に処理
```
        int[] numbers = new int[]{1, 2, 3, 4, 5};
        
        // 各数値を３倍する
        IEnumerable<int> it = numbers.Select(item => item * 3);
        
        foreach(int item in it) {
            Console.WriteLine(item);
        }
```
出力結果：3,6,9,12,15


##### B. whereメソッド
ー条件に合致したデータを抽出する
```
        int[] numbers = new int[]{1, 2, 3, 4, 5};
        
        // 偶数のみを抽出する
        IEnumerable<int> it = numbers.Where(item => item % 2 == 0);
        
        foreach(int item in it) {
            Console.WriteLine(item);
        }
```
出力結果：2,4

##### c. selectのおまけ(正誤判定)
```
        int[] numbers = new int[] {1,2,3,4,5,6};
        //4の倍数かどうかを判定する
        var olds = numbers.Select(x => x % 4 == 0);
        foreach(var old in olds)
        {
            Console.WriteLine(old);
        }
```
出力結果：False,False,False,True,False,False



## ③inputfieldで入力された文字を1文字ずつdictionaryに登録する

```
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using System.Linq;


public class dicTest : MonoBehaviour
{
    public GameObject inputf;
    public GameObject result;
    public Dictionary<int, string> letters = new Dictionary<int, string>();

    public void GetInput(){
        //inputfieldからテキストを所得し、inputへ入れる
        string input = inputf.GetComponent<InputField>().text;


        //lettersのdictionaryに、取得した文字を1文字ずつ代入する。
            letters = input
                .Select((c, index) => new KeyValuePair<int, string>(index, c.ToString())) 
                .ToDictionary(pair => pair.Key, pair => pair.Value);

        foreach (var kvp in letters)
        {
            Debug.Log($"Key: {kvp.Key}, Value: {kvp.Value}");
        }

    }
}

```
point
最初dictionaryをpublicで定義せずに作り始めると、if文で囲った時に、使えなくなっちゃったので、publicで宣言した。なんとなく、参照できる範囲に決まりがあるのは知ってるけど、全部理解は諦めた。とりあえずpublicで言っときゃ、参照できる！！


## ④inputfieldに入力された文字を、1回目と2回目ので処理変える。

```
    void Start()
    {
        round = 1;
    }

    public void GetInput()
    {
        
        //1ラウンド目の処理
        if (round == 1)
        {
            //省略

            //２週目へ繋ぐ処理
            round++;
            Debug.Log(round + "週目へ");
        
        }

        else if (round == 2){

            Debug.Log("2週目スタート");
            //省略

        }


    }

```
## ⑤2週目に入力された文字の1番目と1週目に入力された文字の3番目が一致するか判定してから、代入
```
        else if (round == 2){

            Debug.Log("2週目スタート");
            string input2 = inputf.GetComponent<InputField>().text;

            //key2の文字を取り出す
            letters.TryGetValue(2, out value2);
            Debug.Log(value2);
            //input2の1文字目を取り出す
            string s2 = input2.Substring(0,1);
            Debug.Log(s2);

            if(s2 == value2){
                //文字一致の確認
                Debug.Log("重なる部分の文字が一致しました");

                //☆ dictionaryのkey5,8へletter2の二文字目からを入れる
                letters[5] = input2[1].ToString(); // letter2の2文字目をKey5に
                letters[8] = input2[2].ToString(); // letter2の3文字目をKey8に

                //dictionaryの確認用※あとで消してOK
                foreach (var kvp in letters)
                {
                    Debug.Log($"Key: {kvp.Key}, Value: {kvp.Value}");
                }

                // DictionaryのKeyとTextObjectのElement番号を一致させて表示
                foreach (var kvp in letters)
                {
                    int key = kvp.Key;        // DictionaryのKey（0から8）
                    string value = kvp.Value; // DictionaryのValue（文字）

                    if (key >= 0 && key < letter.Length && letter[key] != null)
                    {
                        // UnityEngine.UI.Text コンポーネントを取得
                        Text textComponent = letter[key].GetComponent<Text>();

                        if (textComponent != null)
                        {
                            textComponent.text = value; // DictionaryのValueをTextに設定
                            Debug.Log($"Set '{value}' to {letter[key].name} (Key/Index: {key})");
                        }
                        else
                        {
                            Debug.LogWarning($"Text component not found on {letter[key].name}");
                        }
                    }
                    else
                    {
                        Debug.LogWarning($"Invalid key/index {key} or missing GameObject at that position.");
                    }
                }

            }
```

### ⑤完成版コード全容
```
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using System.Linq;


public class dicTest : MonoBehaviour
{
    public GameObject inputf;
    public GameObject[] letter = new GameObject[9];
    int round;

    public string value2;

    public Dictionary<int, string> letters = new Dictionary<int, string>();
    void Start()
    {
        round = 1;
    }

    // Update is called once per frame
    void Update()
    {
        
    }

    public void GetInput(){
        
        //1ラウンド目の処理
        if (round == 1)
        {
            string input = inputf.GetComponent<InputField>().text;

            //lettersのdictionaryに、取得した文字を1文字ずつ代入する。
            letters = input
                .Select((c, index) => new KeyValuePair<int, string>(index, c.ToString())) 
                .ToDictionary(pair => pair.Key, pair => pair.Value);
            
            //dictionaryの確認用※あとで消してOK
            foreach (var kvp in letters)
            {
                Debug.Log($"Key: {kvp.Key}, Value: {kvp.Value}");
            }
            
            int index = 0; // letter[] のインデックス管理用

            // Dictionaryのキー1から順番にGameObjectにセット
        // DictionaryのKeyとTextObjectのElement番号を一致させて表示
        foreach (var kvp in letters)
        {
            int key = kvp.Key;        // DictionaryのKey（0から8）
            string value = kvp.Value; // DictionaryのValue（文字）

            if (key >= 0 && key < letter.Length && letter[key] != null)
            {
                // UnityEngine.UI.Text コンポーネントを取得
                Text textComponent = letter[key].GetComponent<Text>();

                if (textComponent != null)
                {
                    textComponent.text = value; // DictionaryのValueをTextに設定
                    Debug.Log($"Set '{value}' to {letter[key].name} (Key/Index: {key})");
                }
                else
                {
                    Debug.LogWarning($"Text component not found on {letter[key].name}");
                }
            }
            else
            {
                Debug.LogWarning($"Invalid key/index {key} or missing GameObject at that position.");
            }
        }
            //２週目へ繋ぐ処理
            round++;
            Debug.Log(round + "週目へ");
        
        }

        else if (round == 2){

            Debug.Log("2週目スタート");
            string input2 = inputf.GetComponent<InputField>().text;

            //key2の文字を取り出す
            letters.TryGetValue(2, out value2);
            Debug.Log(value2);
            //input2の1文字目を取り出す
            string s2 = input2.Substring(0,1);
            Debug.Log(s2);

            if(s2 == value2){
                //文字一致の確認
                Debug.Log("重なる部分の文字が一致しました");

                //☆ dictionaryのkey5,8へletter2の二文字目からを入れる
                letters[5] = input2[1].ToString(); // letter2の2文字目をKey5に
                letters[8] = input2[2].ToString(); // letter2の3文字目をKey8に

                //dictionaryの確認用※あとで消してOK
                foreach (var kvp in letters)
                {
                    Debug.Log($"Key: {kvp.Key}, Value: {kvp.Value}");
                }

                // DictionaryのKeyとTextObjectのElement番号を一致させて表示
                foreach (var kvp in letters)
                {
                    int key = kvp.Key;        // DictionaryのKey（0から8）
                    string value = kvp.Value; // DictionaryのValue（文字）

                    if (key >= 0 && key < letter.Length && letter[key] != null)
                    {
                        // UnityEngine.UI.Text コンポーネントを取得
                        Text textComponent = letter[key].GetComponent<Text>();

                        if (textComponent != null)
                        {
                            textComponent.text = value; // DictionaryのValueをTextに設定
                            Debug.Log($"Set '{value}' to {letter[key].name} (Key/Index: {key})");
                        }
                        else
                        {
                            Debug.LogWarning($"Text component not found on {letter[key].name}");
                        }
                    }
                    else
                    {
                        Debug.LogWarning($"Invalid key/index {key} or missing GameObject at that position.");
                    }
                }

            }
            Debug.Log(round);
            
            //3週目へ繋ぐ処理
            round++;
            Debug.Log(round + "週目へ");

        }


    }
}

```