C#でビンゴゲームのシミュレーション

#C#でビンゴゲームのシミュレーションを行いました
ランダムに数字を選びビンゴカードを5万枚作り、ビンゴゲームをシミュレーションしました。
ビンゴカードは左の列から、B列、I列、N列、G列、O列といい、それぞれ数字の範囲が
1～15、16～30、31～45、46～60、61～75と決まっています。
カードの数字の配列を2次元配列で表しました。

##ビンゴマシーンクラス

名称は分かりませんが、ハンドル回してガラガラガラして、数字の書かれたボールを出す、あのマシーン。
それを一つのクラスにしましたので、ライブラリー化することもできますし、コピーして、プロジェクトの一部にもできます。

```BingoMachine.cs
using System.Collections.Generic;

namespace CsBingoTest
{
    class BingoMachine
    {
        private List<int> number_list = new List<int>(75);
        public BingoMachine(System.Random rnd)    //コンストラクターでRandomを引数にするのは、短時間に複数のRandomインスタンスを生成すると、Next()実行時に同じ数字が返されるため。
        //従って、呼び出し元であらかじめ用意したRandomインスタンスを引数に渡して、複数のBingoMachineインスタンスを短時間に生成する場合は、共通のRandomインスタンスを引数に渡してください。
        {
            var list = new List<int>(75);
            int l;

            for(int i = 1; i <= 75; i++)
            {
                list.Add(i);
            }

            for (int i = 0; i < 75; i++)
            {
                l = rnd.Next(0, 75 - i);

                number_list.Add(list[l]);
                list.RemoveRange(l, 1);
            }
        }

        public int rolling()      //ビンゴを、ハンドル回してガラガラガラ～。出た数字を返します。
        {
            if (number_list.Count <= 0) { return 0; }

            int num = number_list[0];

            number_list.RemoveRange(0, 1);

            return num;
        }
    }
}
```

##ビンゴカードクラス

コードは以下の通りです。

```BINGO.cs
namespace CsBingoTest
{
    class BINGO
    {
        /// <summary>
        /// ビンゴカードの数字
        /// </summary>
        private int[,] num = new int[5, 5] { { 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0 } };
        /// <summary>
        /// ビンゴカードに穴が開いたかどうかを記録
        /// </summary>
        private bool[,] b = new bool[5, 5] { { false, false, false, false, false }, { false, false, false, false, false }, { false, false, true, false, false }, { false, false, false, false, false }, { false, false, false, false, false } };
        public BINGO(System.Random rnd)    //コンストラクターでRandomを引数にするのは、短時間に複数のRandomインスタンスを生成すると、Next()実行時に同じ数字が返されるため。
            //従って、呼び出し元であらかじめ用意したRandomインスタンスを引数に渡して、複数のBINGOインスタンスを短時間に生成する場合は、共通のRandomインスタンスを引数に渡してください。
        {
            int i;
            bool c;
            int num_p;
            int num_bingo_p;

            for (num_bingo_p = 0; num_bingo_p < 5; num_bingo_p++)
            {
                num_p = 0;
                while (num_p < 5)
                {
                    c = false;
                    i = rnd.Next(1, 15);
                    
                    for (int j = 0; j < 5; j++)
                    {
                        if (num[num_bingo_p, j] == i + (15 * num_bingo_p))
                        {
                            c = true;
                        }
                    }
                    if (!c)
                    {
                        num[num_bingo_p, num_p] = i + (15 * num_bingo_p);
                        num_p++;
                    }
                }
            }
        }
        public void push(int number)        //ビンゴカードに穴を開ける関数です。intを渡すと、その数値があれば、穴を開けます。
        {
            int bingo = 0;
            if (1 <= number && number <= 15) bingo = 0;
            else if (16 <= number && number <= 30) bingo = 1;
            else if (31 <= number && number <= 45) bingo = 2;
            else if (46 <= number && number <= 60) bingo = 3;
            else if (61 <= number && number <= 75) bingo = 4;

            for(int i = 0; i < 5; i++)
            {
                if (num[bingo, i] == number)
                {
                    b[bingo, i] = true;
                }
            }
        }
        public bool isBingo    //ビンゴしたかどうかを返します。
        {
            get
            {
                bool bng = false;
                for(int i = 0; i < 5; i++)
                {
                    if (b[i, 0] && b[i, 1] && b[i, 2] && b[i, 3] && b[i, 4])
                    {
                        bng = true;
                    }
                    if (b[0, i] && b[1, i] && b[2, i] && b[3, i] && b[4, i])
                    {
                        bng = true;
                    }
                }
                if (b[0, 0] && b[1, 1] && b[2, 2] && b[3, 3] && b[4, 4])
                {
                    bng = true;
                }
                if (b[0, 4] && b[1, 3] && b[2, 2] && b[3, 1] && b[4, 0])
                {
                    bng = true;
                }
                return bng;
            }
        }
        public bool dummy = false;    //何かのフラグにしてください。今回は、ビンゴした後にisBingoプロパティを参照したかどうかのフラグに使用してます。
    }
}
```

##メインプログラム

```Program.cs
namespace CsBingoTest
{
    class Program
    {
        static void Main(string[] args)
        {
            int bingo_card = 50000;      //ビンゴカードの枚数

            System.Random rnd = new System.Random();
            BingoMachine bingoMachine = new BingoMachine(rnd);
            BINGO[] bingo = new BINGO[bingo_card];

            for(int i = 0; i < bingo_card; i++)
            {
                bingo[i] = new BINGO(rnd);       //ビンゴカードの枚数分newする
            }

            int n;
            int loop = 1;      //繰返し回数
            int bingoed_num = 0;   //1回あたりのビンゴした数
            bool isAllBingo = false;

            while (!isAllBingo)     //全てのカードがビンゴするまで繰り返す
            {
                isAllBingo = true;
                n = bingoMachine.rolling();
                System.Console.Write(loop.ToString("00") + "=>" + n.ToString("00") + "::");

                for (int i = 0; i < bingo_card; i++)
                {
                    if (!bingo[i].isBingo) bingo[i].push(n);

                    if (!bingo[i].isBingo) isAllBingo = false;
                    if (bingo[i].isBingo && (!bingo[i].dummy))
                    {
                        System.Console.Write(i.ToString() + ",");
                        bingo[i].dummy = true;
                        bingoed_num++;
                    }
                }
                System.Console.Write("\n(" + bingoed_num.ToString() + ")\n");
                bingoed_num = 0;
                loop++;
            }
            System.Console.WriteLine("ALL BINGO!!!");
        }
    }
}
```

##実行結果

実行結果は
`回数=>出た数字::ビンゴしたカード番号...
(ビンゴしたカードの数)`
となります。
ビンゴしたカードの番号も含めて全部ここに載せられないので、それを省いた実行結果を載せます。

```
01=>39::
(0)
02=>44::
(0)
03=>59::
(0)
04=>28::
(0)
05=>02::
(0)
06=>19::
(0)
07=>05::
(0)
08=>56::
(0)
09=>70::
(38)
10=>04::
(13)
11=>63::
(59)
12=>07::
(30)
13=>60::
(0)
14=>42::
(15)
15=>48::
(79)
16=>20::
(106)
17=>33::
(81)
18=>32::
(210)
19=>13::
(123)
20=>61::
(270)
21=>08::
(271)
22=>36::
(526)
23=>38::
(1056)
24=>58::
(334)
25=>51::
(315)
26=>27::
(544)
27=>35::
(1796)
28=>62::
(747)
29=>46::
(664)
30=>37::
(2628)
31=>50::
(748)
32=>53::
(1150)
33=>49::
(1806)
34=>21::
(1116)
35=>30::
(0)
36=>55::
(2847)
37=>31::
(3270)
38=>41::
(4480)
39=>73::
(1019)
40=>11::
(980)
41=>15::
(0)
42=>03::
(1124)
43=>66::
(1249)
44=>09::
(1419)
45=>26::
(1457)
46=>18::
(1408)
47=>74::
(1454)
48=>14::
(1795)
49=>65::
(1381)
50=>10::
(1928)
51=>67::
(1173)
52=>43::
(2194)
53=>52::
(1135)
54=>24::
(843)
55=>71::
(723)
56=>06::
(998)
57=>12::
(1103)
58=>01::
(1295)
ALL BINGO!!!
```

5万枚あれば4，5回でビンゴするカードがあるかと思いましたが、この結果だけを見ると、9回目で初ビンゴしてます。
5万枚では、試行回数が少ないんでしょうか・・・？

100万枚でやってみました。

```
01=>41::
(0)
02=>29::
(0)
03=>57::
(0)
04=>72::
(0)
05=>34::
(0)
06=>13::
(86)
07=>62::
(101)
08=>07::
(186)
09=>71::
(197)
10=>01::
(261)
11=>08::
(287)
12=>31::
(100)
13=>54::
(1293)
14=>49::
(1259)
15=>36::
(1314)
16=>47::
(1264)
17=>64::
(1706)
18=>70::
(2152)
19=>60::
(0)
20=>45::
(0)
21=>56::
(2578)
22=>26::
(10563)
23=>63::
(6695)
24=>46::
(7298)
25=>43::
(5735)
26=>48::
(12245)
27=>44::
(11602)
28=>59::
(21239)
29=>03::
(10843)
30=>38::
(20937)
31=>39::
(34767)
32=>18::
(26361)
33=>16::
(25754)
34=>52::
(39070)
35=>33::
(49750)
36=>30::
(0)
37=>42::
(70401)
38=>58::
(50462)
39=>06::
(20437)
40=>11::
(21605)
41=>32::
(85085)
42=>75::
(0)
43=>51::
(61492)
44=>02::
(20007)
45=>21::
(26974)
46=>04::
(25796)
47=>68::
(23087)
48=>15::
(0)
49=>67::
(23771)
50=>10::
(31118)
51=>22::
(29049)
52=>17::
(26591)
53=>25::
(24902)
54=>66::
(23739)
55=>28::
(22290)
56=>12::
(24574)
57=>40::
(25629)
58=>09::
(19526)
59=>24::
(10119)
60=>65::
(8662)
61=>37::
(13365)
62=>05::
(7450)
63=>14::
(8226)
ALL BINGO!!!
```

6回目で86枚ビンゴしてます。非常に低い確率だと分かります。
5回目でビンゴする確率はもっともっと低いのでしょう。
4回目でのビンゴは、もっともっともっともっともっと確率が低いのかもしれません。