LoginSignup
0
1

More than 3 years have passed since last update.

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

Posted at

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回目でのビンゴは、もっともっともっともっともっと確率が低いのかもしれません。

0
1
0

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
1