目次
⓪ scratchでプロトタイプを作成
① dictionaryを用意
② 文字を1文字ずつに分けてdictionaryに入れる
③ inputfieldで入力された文字を1文字ずつdictionaryに登録する
④ inputfieldに入力された文字を、1回目と2回目ので処理変える。
⑤ 完成版コード全容
完成系
クロスワードを作る際に必要そうな、以下の機能の実装を試みた。
①入力された文字を辞書型で保存
②入力された文字をkeyを使い指定の位置へ表示
③2週目に入力された文字の処理
1週目に入力された文字で、重なる部分の文字が一致する場合、指定した位置へ表示
勉強しながら実装したものの備忘録なので、つらつら長い文章になります。
コードだけ欲しい方はこちらへ
⓪scratchでプロトタイプを作成
①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);
}
<結果>
「0,1」
“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};
// 各数値を3倍する
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)
{
//省略
//2週目へ繋ぐ処理
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.");
}
}
//2週目へ繋ぐ処理
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 + "週目へ");
}
}
}