C#

米国政府が1億5000万円かけたあのアプリをC#で再現してみた(random)

先日アメリカ政府の関連機関が1.5億円払って作ったというiPadアプリがちょっと話題になりました。そのアプリは空港のセキュリティチェック時に列を右に左に振り分けるというもの。

画面をタップして表示された矢印に従い、あなたは右~

YourR画面をタップして表示された矢印に従い、あなたは左~

YourL

動画を見てもらうとわかりやすいです。

さてこのアプリの名前は「TSA Randomizer」。TSA(アメリカ国土安全保障省の運輸保安庁認定施錠機構の総称)のランダマイザー。つまりランダムデータ生成装置ですね。

[su_heading]今回はこの「Randomizer」をC#で再現してみます。[/su_heading]

 

C#で乱数(ランダムな数値)を取得する

C#での乱数(疑似乱数)はSystem.Randomクラスを使用することで取得することができますのでまずはボタンタップで乱数を取得。その乱数が偶数なら左、奇数なら右。向きに合わせた画像を画面に表示して…

    private void button1_Click(object sender, EventArgs e)
    {
        Random rand = new System.Random();
        
        int i = rand.Next();             // 0以上の乱数
        if ((i % 2) == 0){
            panel1.BackgroundImage = RanArrow.Properties.Resources.Left;
        }
        else{
            panel1.BackgroundImage = RanArrow.Properties.Resources.Right;
        }
    }

…あとは、にこやかに誘導する。以上!できちゃいました。

Action01Action02

 

C# System.Randomクラス

再現がすんなりと出来てしまったので、C#のSystem.Randomクラスについてもう少しみてみます。この乱数の生成には時間に依存する規定のシード値(種となる値)を使用しRandomクラスのインスタンスを初期化します。そして、Next()メソッドで0以上のランダムな整数を取得しています。(数値の範囲を絞ることも可能)

    Random rand = new System.Random();
    
    int a = rand.Next();             // 0以上の乱数
    int b = rand.Next(500);          // 0~500までの乱数を取得する場合
    int c = rand.Next(10, 100);      // 10~100までの乱数を取得する場合

 

C# System.Randomクラスの注意点

乱数(疑似乱数)と初めに書いたようにこの乱数は疑似であって厳密な乱数というわけではありません。シード値に同じ数値を入れて初期化した場合、生成される乱数は予測できるものとなってしまいます。そのテストとして先ほどのコードを以下のように書き換えてみました。施行3回とも同じ数値となっています。

    private void button1_Click(object sender, EventArgs e)
    {
        for (int i = 0; i < 50; i++)
        {
			// 引数に100を指定
            Random rand = new System.Random(100);
            
            for (int j = 0; j < 10; j++)
            {
                Console.Write("{0} ", rand.Next(50, 100));
            }
        }
    }

実行結果(一部抜粋)

	//ボタンクリック 1回目
	98 57 83 95 67 97 85 80 67 57 
	98 57 83 95 67 97 85 80 67 57 
	98 57 83 95 67 97 85 80 67 57 

	//ボタンクリック 2回目
	98 57 83 95 67 97 85 80 67 57 
	98 57 83 95 67 97 85 80 67 57 
	98 57 83 95 67 97 85 80 67 57 

	//ボタンクリック 3回目
	98 57 83 95 67 97 85 80 67 57 
	98 57 83 95 67 97 85 80 67 57 
	98 57 83 95 67 97 85 80 67 57 

 

C# System.Randomクラス 引数なしでは?

System.Randomクラスで引数なしの場合は時間に依存するシード値としてEnvironment.TickCountがシード値として使われます。システムタイマーから得られる値をシード値として使用しているのでその数値が異なるタイミングであれば生成される数値は異なります。

    private void button1_Click(object sender, EventArgs e)
    {
        for (int i = 0; i < 50; i++)
        {
			// 引数に100
            Random rand = new System.Random();
            
            for (int j = 0; j < 10; j++)
            {
                Console.Write("{0} ", rand.Next(50, 100));
            }
            Console.WriteLine(Environment.TickCount);
        }
    }

実行結果(一部抜粋)

	// 出力結果
	88 64 99 79 52 83 73 72 70 65 554286060
	88 64 99 79 52 83 73 72 70 65 554286060
	88 64 99 79 52 83 73 72 70 65 554286060
	98 69 83 60 52 87 67 99 62 86 554286091	// TickCountが変わったタイミング
	98 69 83 60 52 87 67 99 62 86 554286091
	98 69 83 60 52 87 67 99 62 86 554286091
	98 69 83 60 52 87 67 99 62 86 554286091

TickCountが変わるより早い速度で乱数を用いる場合には注意が必要ですが、今回再現したC#版「TSA Randomizer」では、画面タップ(ボタンクリック)のタイミングで乱数を生成しているので、得られる疑似乱数は左右を振り分けるには十分ランダムな数値になりますね。

無事、噂のランダマイザーがC#で再現できました。あとは1.5億円での受注を再現するのみです!

 

 

タイトルとURLをコピーしました