LoginSignup
0

More than 5 years have passed since last update.

C#手遊び (ソシャゲのガチャ計算:ほんのちょっとLinq)

Last updated at Posted at 2019-02-17

この記事、何?

この前、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#少し慣れたら改めてリファクタリング検討してみたい。
もう少しましになりそうな気がする。

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0