この記事、何?
この前、without Visual StudioでC#コンパイルできるだよね、って記事を書いた。
だったら何かちょっとした計算をさせたくなった。
手になじむまでは、最初の public stringstatic void string argsあたりでつまずくので、なんか動くコードを上げておきたかったから。
(※追記※ ほら、つまずいてるし。。。)
じゃあ、しばらく前からやってるソシャゲのガチャを計算してみた。
・・・いや、決してゲームアディクトというわけではなく。。。
どういう人向け?
デレステが好きな人向け
まあ、C#のコードでちょっとした計算をさせたい人向け。
まあ、たまたま目の前にあった端末にpython入ってないこともあるけど、今どきのWindowsならcsc.exeはあるでしょ、多分。
これあれば中身いじってどこででもC#でexe作って何か計算できるな、と。
参考URL
■乱数を生成する
https://dobon.net/vb/dotnet/programing/random.html
■LINQ とは
https://ufcpp.net/study/csharp/sp3_linq.html
■アイドルマスター シンデレラガールズ スターライトステージ
https://cinderella.idolmaster.jp/sl-stage/
とりあえず何を計算したいかの軽い説明
たまに無償で引けるガシャなどでレアリティ「R」が手に入る。同じ子のRを重ねると☆1が☆2、☆3とかって増える。
で、10枚手に入れるとRの上限の☆10ができる。ちょっとうれしい。
全部で103種類あるけど、いつになったらそろうのか、という話。
なので、ガシャ数を引数にシミュレートしてどれくらい出るか試してみたい。
コーディング方針
初期条件
まあまあそろったので、残り44人。
すでに9枚持っているのが9人、8枚が9人、7枚が11人・・・という状態なのでこんな。
//現在の数: 9人 -> 2人 (8種類で合計44人)
int[] current = { 9, 9, 11, 7, 3, 2, 1, 2 };
ざっくりPS
C#の乱数使って0以上103未満の数を取得して103種類取る。これがガシャの試行に相当する。
上記の44人を配列を作って、44人の初期☆数を入れておいて、その子の整数が来たらincrementする。
で、最後に☆10に届いてない子のリストを出す。
できあがり
using System;
using System.Linq;
public class Calc
{
public static void Main(string[] args)
{
//繰り返し数を引数から取得(なければ0)
int iteration = 0;
if (args.Length == 1)
{
int.TryParse(args[0], out iteration);
if (iteration < 0) { iteration = 0; }
}
Console.WriteLine("繰り返し数 = " + iteration.ToString());
//現在の数: 9人 -> 2人 (8種類で合計44人)
int[] current = { 9, 9, 11, 7, 3, 2, 1, 2 };
//44人分の空配列
int[] r = new int[current.Sum()];
// 9人 -> 2人 で8回ループして44人の現在保持数を設定
int startRemain = 9;
int idx = 0;
for (int i = 0; i < current.Length; i++)
{
for (int tmp = 0; tmp < current[i]; tmp++)
{
r[idx + tmp] = startRemain;
}
startRemain--;
idx += current[i];
}
var rand = new Random();
//ガシャを引く。。。
for (int i = 0; i < iteration; i++)
{
//対象内の誰かだったら☆数を++
int tmp = rand.Next(103);
if (tmp < current.Sum())
{
r[tmp]++;
}
}
//結果発表♪
int remain = 0;
for (int i = 0; i < r.Length; i++)
{
int tmp = r[i];
//☆10に届いてない分だけ表示
if (tmp < 10)
{
Console.WriteLine((i + 1).ToString() + "人目: ☆" + r[i].ToString());
remain++;
}
}
Console.WriteLine("残り" + remain.ToString() + "人");
}
}
コンパイル
これ参照。
■C#手遊び(Compiler w/o Visual Studio)
https://qiita.com/siinai/items/8a325ad4eade1a2f6e9e
ぶっちゃけ、csc.exe code.cs だけでOK。
実行結果
初期値確認のための0回と、200回、500回、1000回(を何度か)の結果がこれ。
C:\projects\qiita\draft\21>
C:\projects\qiita\draft\21>calc
繰り返し数 = 0
1人目: ☆9
2人目: ☆9
3人目: ☆9
4人目: ☆9
5人目: ☆9
6人目: ☆9
7人目: ☆9
8人目: ☆9
9人目: ☆9
10人目: ☆8
11人目: ☆8
12人目: ☆8
13人目: ☆8
14人目: ☆8
15人目: ☆8
16人目: ☆8
17人目: ☆8
18人目: ☆8
19人目: ☆7
20人目: ☆7
21人目: ☆7
22人目: ☆7
23人目: ☆7
24人目: ☆7
25人目: ☆7
26人目: ☆7
27人目: ☆7
28人目: ☆7
29人目: ☆7
30人目: ☆6
31人目: ☆6
32人目: ☆6
33人目: ☆6
34人目: ☆6
35人目: ☆6
36人目: ☆6
37人目: ☆5
38人目: ☆5
39人目: ☆5
40人目: ☆4
41人目: ☆4
42人目: ☆3
43人目: ☆2
44人目: ☆2
残り44人
C:\projects\qiita\draft\21>calc 200
繰り返し数 = 200
3人目: ☆9
8人目: ☆9
10人目: ☆9
14人目: ☆9
17人目: ☆8
19人目: ☆8
20人目: ☆8
21人目: ☆8
22人目: ☆9
23人目: ☆9
24人目: ☆8
25人目: ☆8
26人目: ☆7
28人目: ☆9
29人目: ☆9
30人目: ☆9
31人目: ☆8
32人目: ☆9
33人目: ☆6
34人目: ☆8
35人目: ☆8
36人目: ☆9
37人目: ☆9
38人目: ☆7
39人目: ☆6
40人目: ☆6
41人目: ☆4
42人目: ☆5
43人目: ☆5
44人目: ☆2
残り30人
C:\projects\qiita\draft\21>calc 500
繰り返し数 = 500
11人目: ☆8
23人目: ☆9
29人目: ☆9
31人目: ☆8
34人目: ☆8
37人目: ☆8
41人目: ☆9
42人目: ☆6
43人目: ☆9
44人目: ☆3
残り10人
C:\projects\qiita\draft\21>calc 1000
繰り返し数 = 1000
残り0人
C:\projects\qiita\draft\21>calc 1000
繰り返し数 = 1000
42人目: ☆7
43人目: ☆8
残り2人
C:\projects\qiita\draft\21>calc 1000
繰り返し数 = 1000
44人目: ☆8
残り1人
C:\projects\qiita\draft\21>calc 1000
繰り返し数 = 1000
44人目: ☆9
残り1人
C:\projects\qiita\draft\21>calc 1000
繰り返し数 = 1000
42人目: ☆9
残り1人
C:\projects\qiita\draft\21>calc 1000
繰り返し数 = 1000
残り0人
C:\projects\qiita\draft\21>calc 1000
繰り返し数 = 1000
42人目: ☆5
残り1人
C:\projects\qiita\draft\21>calc 1000
繰り返し数 = 1000
44人目: ☆9
残り1人
C:\projects\qiita\draft\21>calc 1000
繰り返し数 = 1000
43人目: ☆8
残り1人
コーディング中の感想
pythonもそうだったけど、些細な書きミスはcsc.exeが「〇行目の〇文字目がおかしいです」って言ってくる。
だから、ほとんどの場合、一目で修正方法に気づく。
今回、0ByteのテキストファイルをVisual Studio Codeで開いて編集した。
ほんの少しIntelliSenseも利くし、これくらいの計算タスクならVisual Studio Codeでいいな、と思った。
統計的な見地(のふりをしたゲーム観点)
へぇ・・・200回くらいじゃまだまだ、で、500回くらいでかなり減った感じ。
1000回もすればすでに終わっているか最後の一人とかそんな感じか・・・なるほど。
まあ、大体そんな感じかなぁ・・・と思っていた通り。どちらかというときもち早いかも。
けど、やっぱりガシャは闇だよね。
500回試したログで、ほぼ全員☆8か☆9になっているのに、44人目が☆3だって。
初期値(=現状)が最小☆2だから、よりにもよって一番枚数が必要な子が500回引いて1枚しか来てないということ。
10回くらい繰り返した1000回の試行の一つにも「42人目: ☆5」ってあるし。
いやぁ・・・リアルにこれだったら長くやきもきしそう。
あっ、そういうことじゃなくて、あとで検定かけてみましょう。
上記例が極めてまれなのかどうか。
今後
今回、Sum()ひとつだけどLinq入れてみた。
とりあえず動くべたコード書いてからリファクタリングしてたら、そういう機能ありそうだなぁ・・・と思って調べてみた。
Linqいいね。SQLに近い書き方で「あれここーして、それからあーやって」ってしゃべる感じでかけそう。
もっと攻略しよう。
あと、Python慣れしたいのでpython手遊びとして、書いてみようかなぁ?
と、だいぶたって、C#少し慣れたら改めてリファクタリング検討してみたい。
もう少しましになりそうな気がする。