static void Main() { //XorShift乱数ジェネレータの初期化 // 論文デフォルトシード var r_def = new XorShift.defaultSeed(); // 固定値シード var r_const = new XorShift(100); // 時間シード var r = new XorShift(); //デフォルトシード値の取得 Console.WriteLine(">> defaults"); Console.WriteLine(String.Join(", ", XorShift.defaults)); //適用したシード値の取得 Console.WriteLine(">> seeds in r"); Console.WriteLine(String.Join(", ", r.seeds)); //乱数の生データを取得 Console.WriteLine(">> rand 0 to UInt32Max"); for (int i = 0; i < 5; i++) { Console.WriteLine(r_def.rand()); } //0-100の乱数(100含む)を整数で取得 Console.WriteLine(">> randInt 0 to 100"); for (int i = 0; i < 5; i++) { Console.WriteLine(r_const.randInt(0, 100)); } //0-1の乱数を浮遊小数点で取得 Console.WriteLine(">> randFloat 0 to 1"); for (int i = 0; i < 5; i++) { Console.WriteLine(r.randFloat()); } //静的配列のシャッフル //値渡しとなるので元の配列は破壊されない Console.WriteLine(">> shuffle Array"); int[] a = Enumerable.Range(0, 20).ToArray(); Console.WriteLine(String.Join(", ", r.shuffle(a))); Console.WriteLine(String.Join(", ", a)); //List<T>のシャッフル Console.WriteLine(">> shuffle List<T>"); var b = new List <int>(Enumerable.Range(0, 20)); Console.WriteLine(String.Join(", ", r.shuffle(b))); Console.WriteLine(String.Join(", ", b)); //今の乱数を回した回数 Console.WriteLine(">> randCount in r"); Console.WriteLine(r.randCount); }
//クエストルーレット public static string quest(List <string> questLasts, List <string> questList, XorShift xs) { //履歴保存数 int n; if (questLasts.Count == 0 || questList.Count <= 2) { n = 0; } else if (questList.Count - 1 <= questLasts.Count) { n = questList.Count - 2; } else if (questLasts.Count < 10) { n = questLasts.Count; } else { n = 10; } //履歴数調整 questLasts.RemoveRange(0, questLasts.Count - n); //履歴に含まれるクエストは選択しない string quest; do { quest = questList[xs.randInt(0, questList.Count - 1)]; }while(2 <= questList.Count && questLasts.Contains(quest)); questLasts.Add(quest); return(quest); }
//プレイヤー項目用ルーレット public static void item( List <Player> players, //プレイヤーリスト string[] lasts, //プレイヤー毎の履歴リスト string[] itemList, //ルーレット対象 string key, //ルーレット項目 bool isOptionAll, //項目の統一を行う? bool isOptionOnly, //項目の重複をさせない? XorShift xs //乱数ジェネレータ ) { //ルーレットが失敗した時もう一度 for (;;) { repeat: //履歴はルーレット対象は最低2つ以上存在する場合のみ参照する var isLastChk = 2 <= itemList.Length; //項目の統一させる場合、 if (isOptionAll) { int x = xs.randInt(0, itemList.Length - 1); //全てのプレイヤーに等しく結果を代入 //履歴は1人目のプレイヤーの物のみ参照する foreach (var(p, i) in players.Select((p, i) => (p, i))) { if (isLastChk && i == 0 && lasts[0] == itemList[x]) { goto repeat; } p.items[key].index = x; } //履歴を更新 for (int i = 0; i < lasts.Length; i++) { lasts[i] = players[0].items[key].value; } } else { int[] xList; //項目の重複をさせない場合 if (isOptionOnly && players.Count < itemList.Length) { //重複しない乱数で結果を生成 xList = Enumerable.Range(0, itemList.Length).ToArray(); xList = xs.shuffle(xList); } //通常条件 else { //通常の乱数 xList = Enumerable.Range(0, players.Count) .Select(v => xs.randInt(0, itemList.Length - 1)).ToArray(); } if (isLastChk) { //履歴を参照して2連続で選択されるものがあればもう一回 foreach (var(p, i) in players.Select((p, i) => (p, i))) { if (lasts[i] == itemList[xList[i]]) { goto repeat; } } } //ルーレット結果をプレイヤーに代入、履歴を更新 foreach (var(p, i) in players.Select((p, i) => (p, i))) { p.items[key].index = xList[i]; lasts[i] = p.items[key].value; } } return; } }