Skip to content

Instantly share code, notes, and snippets.

@todorok1
Last active June 21, 2018 10:10
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save todorok1/05de9213985ce24688bb0abf8a5809ad to your computer and use it in GitHub Desktop.
Save todorok1/05de9213985ce24688bb0abf8a5809ad to your computer and use it in GitHub Desktop.
少ない試行回数だと偏りを感じる件を調査
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.IO;
public class RandomLessSampleTest : MonoBehaviour {
// サイコロの目を定義
int[] dice = new int[] {1, 2, 3, 4, 5, 6};
// 結果を記録するジャグ配列
int[][] results = new int[userNum][];
// 1ユーザーあたりの試行回数
const int rollNum = 10;
// ユーザー数
const int userNum = 10000;
// 達成状況を記録する辞書
Dictionary<int, int> achievedResulst;
void Start(){
OutputDiceResults();
}
void InitializeArrays(){
// 結果データを格納する配列を初期化
for (int i = 0; i < userNum; i++){
results[i] = new int[rollNum];
}
// 達成状況を格納する辞書を初期化
achievedResulst = new Dictionary<int, int>();
foreach (int pips in dice){
achievedResulst.Add(pips, 0);
}
}
void OutputDiceResults(){
// 処理開始のメッセージ
Debug.Log("***** 少ない試行回数での確認を開始 *****");
// CSVファイルのヘッダを出力
StreamWriter sw;
FileInfo fi;
string fineName = Application.dataPath + "/Resources/Csv/RandomLessSample/dice_output.csv";
fi = new FileInfo(fineName);
sw = fi.CreateText();
InitializeArrays();
for (int userIndex = 0; userIndex < results.Length; userIndex++){
for (int rollIndex = 0; rollIndex < rollNum; rollIndex++){
int pips = RollADice();
results[userIndex][rollIndex] = pips;
}
// 結果の文字列を出力
sw.WriteLine(OutPutLine(userIndex));
}
// 達成人数を出力
sw.WriteLine("***** summary *****");
sw.WriteLine("ドロップアイテムの種類, 人数, 確率");
foreach (KeyValuePair<int, int> pair in achievedResulst){
System.Text.StringBuilder sb = new System.Text.StringBuilder();
// ドロップアイテムの種類
sb.Append(pair.Key).Append("種類,");
// 人数
sb.Append(pair.Value).Append(",");
// 確率
float prob = 1.0f * pair.Value / userNum;
sb.Append(prob);
sw.WriteLine(sb.ToString());
}
string summary = "6種類のドロップを達成した人数は " + achievedResulst[dice.Length] + " 人でした。";
sw.WriteLine(summary);
Debug.Log(summary);
// Streamを閉じて書き込み
sw.Flush();
sw.Close();
// 処理開始のメッセージ
Debug.Log("***** 乱数の偏りの確認を終了 *****");
}
int RollADice(){
// 乱数の範囲指定で配列のインデックスを取得する
int index = Random.Range(0, dice.Length);
// サイコロの目を取得する
int pips = dice[index];
return pips;
}
string OutPutLine(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(CheckAchieved(userIndex).ToString());
return sb.ToString();
}
bool CheckAchieved(int userIndex){
bool isAchieved = false;
// 達成状況確認の辞書
Dictionary<int, bool> achievedDict = new Dictionary<int, bool>();
foreach (int pips in dice){
achievedDict.Add(pips, false);
}
// 辞書に結果を格納
foreach (int pips in results[userIndex]){
// 各ユーザーの配列を確認し、辞書内で出た目に一致するキーの値をtrueにする
achievedDict[pips] = true;
}
// 辞書内全てのキーの値がtrueなら達成
int trueCount = 0;
foreach (KeyValuePair<int, bool> pair in achievedDict){
if (pair.Value){
trueCount++;
}
}
if (achievedResulst.ContainsKey(trueCount)){
achievedResulst[trueCount]++;
}
if (trueCount == dice.Length){
isAchieved = true;
}
return isAchieved;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment