🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
Unity

Unityは、Unity Technologiesが開発・販売している、IDEを内蔵するゲームエンジンです。主にC#を用いたプログラミングでコンテンツの開発が可能です。

Q&A

解決済

2回答

1336閲覧

Unity 問題をシャッフルしても重複しないようにしたい

hanaGame

総合スコア1

Unity

Unityは、Unity Technologiesが開発・販売している、IDEを内蔵するゲームエンジンです。主にC#を用いたプログラミングでコンテンツの開発が可能です。

0グッド

0クリップ

投稿2021/02/26 03:45

前提・実現したいこと

下記のサイトを参考にクイズを作っています
https://moneytyping.com/archives/405

下のコードで作ってみましたがシャッフルはされますが
問題が重複してしまいます
問題がシャッフルされても重複しないようにしたいです
よろしくお願いいたします

該当のソースコード

C#

1using UnityEngine; 2using System.Collections; 3using UnityEngine.UI;//UI オブジェクトを扱う時は必須 4using System.Collections.Generic; 5using System.IO; 6using System.Linq; 7using Random = UnityEngine.Random; 8 9 10public class Question : MonoBehaviour { 11 12 public string[] questions = { 13 "問題", 14 "問題", 15 "問題", 16 "", 17 18 }; 19 public int num; 20 public string nQJ; 21 public static string answer; 22 23 24 25 //アタッチしたオブジェクトが呼ばれた時に実行される。 26 void Start () { 27 num = Random.Range(0,questions.Length); 28 nQJ = questions[num]; 29 QuestionLabelSet (); 30 AnswerLabelSet(); 31 } 32 33 private void QuestionLabelSet(){ 34 35 //特定の名前のオブジェクトを検索してアクセス 36 Text qLabel = GameObject.Find("Quiz/QuestionField").GetComponentInChildren<Text> (); 37 //データをセットすることで、既存情報を上書きできる 38 qLabel.text = nQJ; 39 } 40 private void AnswerLabelSet(){ 41 //回答文面の作成 42 string[][] array = new string[questions.Length][]; 43 //正解の選択肢は必ず一番前に持ってきます。 44 //下のアンサーで使います。 45 array[0] = new string[4]{"選択肢","選択肢","選択肢","選択肢"}; 46 array[1] = new string[4]{"選択肢","選択肢","選択肢","選択肢"}; 47 array[2] = new string[4]{"選択肢","選択肢","選択肢","選択肢"}; 48 49 50 answer = array[num][0]; 51 array[num].Shuffle(); 52 53 54 //ボタンが4つあるのでそれぞれ代入 55 for (int i=1; i<=4 ; i++){ 56 57 Text ansLabel = GameObject.Find("Quiz/AnsButton" + i).GetComponentInChildren<Text> (); 58 ansLabel.text = array[num][i-1]; 59 } 60 } 61 public static string get() 62 { 63 return answer; 64 } 65 66} 67 68 69public static class Extensions //拡張メソッド用 static クラス(名前は任意) 70{ 71 //配列の要素をシャッフルする (Fisher-Yates shuffle) 72 public static void Shuffle<T>(this T[] arr) 73 { 74 for (int i = arr.Length - 1; i > 0; i--) 75 { 76 int j = Random.Range(0, i + 1); //[0]~[i] 77 T tmp = arr[i]; //swap 78 arr[i] = arr[j]; 79 arr[j] = tmp; 80 } 81 } 82}

試したこと

「シャッフル、重複」などで検索し
https://kan-kikuchi.hatenablog.com/entry/ListExtension
を参考に下記のコードも試してみました

====================

/// <summary>
/// 重複しないように追加
/// </summary>
public static void AddToNotDuplicate<T>(this List<T> list, T t){
if(list.Contains(t)){
return;
}
list.Add (t);
}

/// <summary>
/// 重複を無くす
/// </summary>
public static void RemoveDuplicate<T>(this List<T> list){
List<T> newList = new List<T>();

foreach (T item in list) { newList.AddToNotDuplicate(item); } list = newList;

}

====================

こちらの質問の
https://teratail.com/questions/92257
も試してみましたがうまくいきませんでした

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

出題時に乱数で選ぶのがまずいかと。

問題の配列(あるいは、問題のインデックスを格納した配列)をあらかじめシャッフルしといて、
最初から順番に出題するようにすればいいのでは

[C#] 配列をランダムソート(シャッフル)する方法 │ Web備忘録

投稿2021/02/26 04:44

y_waiwai

総合スコア88038

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

hanaGame

2021/02/26 05:51

回答ありがとうございます 上記のサイトを参考にコードを書き直してみましたがエラーが出ます 該当のソースコードは using UnityEngine; using System.Collections; using UnityEngine.UI; using System.Collections.Generic; using System.IO; using System.Linq; using Random = UnityEngine.Random; public class Question : MonoBehaviour { static void Main() { public string[] questions = { "問題", "問題", "問題", "", string[] questions2 = questions.Shuffle().ToArray(); } public int num; public string nQJ; public static string answer; //アタッチしたオブジェクトが呼ばれた時に実行される。 void Start () { //questionsのリスト内から選ばれた数字の問題を選んでいく nQJ = questions[num]; QuestionLabelSet (); AnswerLabelSet(); } private void QuestionLabelSet(){ //特定の名前のオブジェクトを検索してアクセス Text qLabel = GameObject.Find("Quiz/SafeAreaLayout/QuestionField").GetComponentInChildren<Text> (); //データをセットすることで、既存情報を上書きできる qLabel.text = nQJ; } private void AnswerLabelSet(){ //回答文面の作成 string[][] array = new string[questions.Length][]; //正解の選択肢は必ず一番前に持ってきます。 //下のアンサーで使います。 array[0] = new string[4]{"選択肢","選択肢","選択肢","選択肢"}; array[1] = new string[4]{"選択肢","選択肢","選択肢","選択肢"}; array[2] = new string[4]{"選択肢","選択肢","選択肢","選択肢"}; answer = array[num][0]; //選択肢のシャッフルを行う array[num].Shuffle(); //ボタンが4つあるのでそれぞれ代入 for (int i=1; i<=2 ; i++){ Text ansLabel = GameObject.Find("Quiz/SafeAreaLayout/AnsButton" + i).GetComponentInChildren<Text> (); ansLabel.text = array[num][i-1]; } } //正誤判断するスクリプト(Jadge)に答えを渡す public static string get() { return answer; } } public static class IEnumerableExtension //拡張メソッド用 static クラス { public static IEnumerable<T> Shuffle<T>(this IEnumerable<T> collection) { return collection.OrderBy(i => Guid.NewGuid()); } }   です エラーは Assets/Question.cs(214,1): error CS1022: Type or namespace definition, or end-of-file expected と Assets/Question.cs(16,6): error CS1513: } expected です 行数は問題などを非表示にしているため違っているかと思います 単純に } がぬかっているかと思いましたが見当たりません 何かミスを見落としているかもしれません よろしくお願いいたします
y_waiwai

2021/02/26 05:55

中身全く見てませんが、 string[] questions2 = questions.Shuffle().ToArray(); この記述おかしいですよ
hanaGame

2021/02/26 08:20

コメントありがとうございます 「[C#] 配列をランダムソート(シャッフル)する方法 │ Web備忘録」のサイトのコードが //シャッフルする配列 int[] ary1 = new int[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; //シャッフルする int[] ary2 = ary1.Shuffle().ToArray(); になっていたので参考に変えてみました 他のサイトも参考に色々とやってみましたがうまくいきません。 もう少し調べてみます ありがとうございました
y_waiwai

2021/02/26 08:23

記述がおかしいってより記述している場所がおかしいってことですな。 まだそこらへんの文法の理解が怪しいようなので、勉強しよう
U_U_Jenkins

2021/03/02 08:11

シャッフル、重複させたいのなら既にステートメントに追加されてますが、 Linqを使うのが手っ取り早いと思います。
guest

0

自己解決

とりあえず他の方法を使うことにしました
コメントありがとうございました

投稿2021/03/17 00:42

hanaGame

総合スコア1

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問