Created
June 22, 2018 11:49
-
-
Save todorok1/ff5ae5ece5a2f59d94a78173a896c851 to your computer and use it in GitHub Desktop.
逆鱗マラソンのシミュレーション
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System.Collections; | |
using System.Collections.Generic; | |
using UnityEngine; | |
using System.IO; | |
public class RandomGekirinMarathon : MonoBehaviour { | |
// サイコロの目を定義 | |
int[] dice = new int[] {1, 2, 3, 4, 5, 6}; | |
// 結果を記録するジャグ配列 | |
int[][] results = new int[userNum][]; | |
// ユーザー数 | |
const int userNum = 10000; | |
// 最小値を保持 | |
int sampleNumMin; | |
// 最大値を保持 | |
int sampleNumMax; | |
// 試行回数の合計を保持 | |
int sampleNumSum; | |
// 試行回数の分布確認用辞書 | |
Dictionary<int, int> resultDistribution = new Dictionary<int, int>(); | |
void Start(){ | |
OutputDiceResultsWithAllType(); | |
} | |
// 出るまで頑張る逆鱗マラソン | |
void OutputDiceResultsWithAllType(){ | |
// 処理開始のメッセージ | |
Debug.Log("***** 出るまで頑張る逆鱗マラソンを開始 *****"); | |
// CSVファイルのヘッダを出力 | |
StreamWriter sw; | |
FileInfo fi; | |
string fineName = Application.dataPath + "/Resources/Csv/RandomLessSample/dice_all_output.csv"; | |
fi = new FileInfo(fineName); | |
sw = fi.CreateText(); | |
for (int userIndex = 0; userIndex < results.Length; userIndex++){ | |
// 出たサイコロの目を記録するリスト | |
List<int> rollList = new List<int>(); | |
// 達成状況確認の辞書 | |
Dictionary<int, bool> achievedDict = new Dictionary<int, bool>(); | |
foreach (int pips in dice){ | |
achievedDict.Add(pips, false); | |
} | |
while (true){ | |
int pips = RollADice(); | |
rollList.Add(pips); | |
if (CheckAllTypeAchieved(rollList, achievedDict)){ | |
break; | |
} | |
} | |
// 作成されたリストを配列に変換してジャグ配列にセット | |
int[] userResultsArray = rollList.ToArray(); | |
results[userIndex] = userResultsArray; | |
// 結果の文字列を出力 | |
sw.WriteLine(OutPutLineAllType(userIndex)); | |
// 最小値、最大値、試行回数の記録 | |
RecordStats(userIndex); | |
} | |
// Streamを閉じて書き込み | |
sw.Flush(); | |
sw.Close(); | |
fineName = Application.dataPath + "/Resources/Csv/RandomLessSample/dice_all_output_summary.csv"; | |
fi = new FileInfo(fineName); | |
sw = fi.CreateText(); | |
// 平均を算出 | |
float average = 1.0f * sampleNumSum / userNum; | |
// 達成人数を出力 | |
sw.WriteLine("***** summary *****"); | |
sw.WriteLine("平均, 最小値, 最大値"); | |
System.Text.StringBuilder sb = new System.Text.StringBuilder(); | |
sb.Append(average).Append(",").Append(sampleNumMin).Append(",").Append(sampleNumMax); | |
sw.WriteLine(sb.ToString()); | |
sw.WriteLine("分布確認用データ"); | |
sb = new System.Text.StringBuilder(); | |
System.Text.StringBuilder distSb = new System.Text.StringBuilder(); | |
for (int i = 1; i <= sampleNumMax; i++){ | |
// 分布のラベル | |
sb.Append(i).Append(","); | |
// ラベルに対応する人数 | |
if (resultDistribution.ContainsKey(i)){ | |
distSb.Append(resultDistribution[i]).Append(","); | |
} else { | |
distSb.Append("0,"); | |
} | |
} | |
// 分布を出力 | |
sw.WriteLine(sb.ToString()); | |
sw.WriteLine(distSb.ToString()); | |
// Streamを閉じて書き込み | |
sw.Flush(); | |
sw.Close(); | |
// 処理開始のメッセージ | |
Debug.Log("***** 出るまで頑張る逆鱗マラソンを終了 *****"); | |
} | |
int RollADice(){ | |
// 乱数の範囲指定で配列のインデックスを取得する | |
int index = Random.Range(0, dice.Length); | |
// サイコロの目を取得する | |
int pips = dice[index]; | |
return pips; | |
} | |
bool CheckAllTypeAchieved(List<int> rollList, Dictionary<int, bool> achievedDict){ | |
bool isAchieved = false; | |
// 辞書に結果を格納 | |
foreach (int pips in rollList){ | |
// 各ユーザーの配列を確認し、辞書内で出た目に一致するキーの値をtrueにする | |
achievedDict[pips] = true; | |
} | |
// 辞書内全てのキーの値がtrueなら達成 | |
int trueCount = 0; | |
foreach (KeyValuePair<int, bool> pair in achievedDict){ | |
if (pair.Value){ | |
trueCount++; | |
} | |
} | |
if (trueCount == dice.Length){ | |
isAchieved = true; | |
} | |
return isAchieved; | |
} | |
string OutPutLineAllType(int userIndex){ | |
// 各ユーザーの結果を出力する | |
System.Text.StringBuilder sb = new System.Text.StringBuilder(); | |
sb.Append(userIndex).Append(","); | |
// 結果の数だけループ | |
for (int i = 0; i < results[userIndex].Length; i++){ | |
int pips = results[userIndex][i]; | |
sb.Append(pips).Append(","); | |
} | |
sb.Append("finished."); | |
return sb.ToString(); | |
} | |
void RecordStats(int userIndex){ | |
int length = results[userIndex].Length; | |
// 最小値の記録 | |
if (sampleNumMin > length || sampleNumMin == 0){ | |
sampleNumMin = length; | |
} | |
// 最大値の記録 | |
if (sampleNumMax < length){ | |
sampleNumMax = length; | |
} | |
// 試行回数の記録 | |
sampleNumSum += length; | |
// 分布の記録 | |
if (resultDistribution.ContainsKey(length)){ | |
resultDistribution[length]++; | |
} else { | |
resultDistribution.Add(length, 1); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment