抽選用ソフト
このプログラムは大きく分けて2つの処理がほぼ同時に進行しています。1つはタイマー割り込み、1つはボタンを押してからの処理です。Windowsになって複数の処理がほぼ同時に動けるようになりました(ほぼとかいたのは、厳密に言うと短い時間でそれぞれの処理を少しずつ行っていて、人がみると同時に動いているように見えるからです)。
抽選ボタンを押すと当選発表用パソコンに抽選中(指令「9」)を送ります。タイマー割り込みを使って約4秒の間(4秒という数値は体験的に出した数値です)ランダムで抽選データを抽出します。時間が来たときの最終データを当選発表用パソコンへ送り、処理を終了します。
(1)タイマー割り込み
具体的なコードは、次のとおりです。
//********************************************* //タイマー割り込み200msごとにこの処理が動く //********************************************* private void timer1_Tick(object sender, EventArgs e) { int i,j; //抽選開始ボタンが押された時 if (timer_sw == 1) { count++; if (count > 22) { //終了処理 timer_sw = 9; //画像表示 this.pictureBox1.Image = Image.FromFile(Application.StartupPath + "\\img\\" + "終了.bmp"); return; } //0-99までのランダム。プログラムの開始時に //Random rnd = new Random();の宣言が必要 i = rnd.Next(100); //0 特賞1% 99が出たとき //1 1等5% 98 97 96 95 94 が出たとき //2 2等10%80-89が出たとき //3 3等20%60-79が出たとき //8 4等64%その他 atari_sw = 8; if (i == 99) { atari_sw = 0; } else { if (i <= 98 && i >= 94) { atari_sw = 1; } else { if (i >= 80 && i <= 89) { atari_sw = 2; } else { if (i >= 60 && i <= 79) { atari_sw = 3; } } } } //画像表示 回転0.bmp から 回転3.bmpまでの画像を順次表示 if (count == 22) { j = 0; } else { j = (count - 1) % 4; } this.pictureBox1.Image = Image.FromFile(Application.StartupPath + "\\img\\"+"回転"+j.ToString("0")+".bmp"); } if (timer_sw == 0) { this.pictureBox1.Image = Image.FromFile(Application.StartupPath + "\\img\\" + "待機.bmp"); } //終了画像表示を少し長く表示するため if (timer_sw == 8) timer_sw = 7; if (timer_sw == 7) timer_sw = 6; if (timer_sw == 6) timer_sw = 5; if (timer_sw == 5) timer_sw = 4; if (timer_sw == 4) timer_sw = 3; if (timer_sw == 3) timer_sw = 2; if (timer_sw == 2) timer_sw = 0; }
タイマー割り込みとは、「指定した時間(ms/ミリ秒)ごとにこの処理ルーチンを動かす」ということです。今回200msごとに処理をするよう設定しました。4400ms間(約4秒間強)乱数を出したいので、「4400ms/200ms=22」で22回この処理を動かすことになります。
2つの処理の会話のため変数を作りました。
- timer_sw
通常は0をセットしておきます。抽選ボタンが押されたらボタン処理側で1にセットします。タイマー処理側は、22回まわって終わったら9にします。ボタン処理側は9を見て抽選結果を表示用パソコンに送ります。送ったあと、8をセットします。タイマー割り込み側では8→2までダウンさせ、送ったときの画像を保持させます。2になると次は0にして、タイマー割り込みは待機の画像になります。 - atari_sw
今回は8(四等)、3(三等)、2(二等)、1(一等)、0(特賞)にしています。 - count
抽選中のカウント。22回をカウントします
タイマー割り込みの処理の内容説明をします。
プログラム開始時はtimer_swは0になっています。
もし、timer_sw=0なら「待機.bmp」を画面に表示します。抽選ボタンが押されるとtimer_sw=1になり、count変数も0になります。ここからcountをUPして22が来るまで、「回転0.bmp」から「回転3.bmp」までを順に表示します。このときに毎回、ランダム変数で抽選データを設定しておきます。
今回は当たりを%で出すようにしました。特賞(1%) 一等(5%) 二等(10%) 三等(20%) 四等(64%)となります。0-99までのランダム変数(100と指定すると0-99までの数値を返してくれます)にしたので、99が出ると特賞、94から98(5種)が出ると一等、80から89(10種)が出ると二等、60から79(20種)が出ると三等、その他(64種)がでると四等としました。これをatari_swに設定します。
22回終わると、timer_sw=9にして抽選ボタン処理に連絡します。抽選ボタン処理は結果を送ったあと8に設定するので、「終了.BMP」を表示したまま8→7→→→2とカウントダウンして、2になったとき0を設定します。
(2)抽選ボタンの処理
抽選ボタンの処理は、次のとおりです。
具体的なコードは、次のとおりです。
//抽選ボタン private void button1_Click(object sender, EventArgs e) { if (timer_sw == 1) return; //二度押し防止 //RS232C OPEN SerialPort port = new SerialPort("COM1", 9600, Parity.None, 8, StopBits.One); port.DtrEnable = true; port.RtsEnable = true; port.Open(); //抽選開始を知らせる port.Write("9\n"); //開始=9 timer_sw = 1; count = 0; while (true) { Application.DoEvents(); if (timer_sw == 9) break; } //抽選データを パソコンへ送る port.Write(atari_sw.ToString() + "\n"); timer_sw = 8; //RS232C クローズ port.Close(); }
抽選ボタンの処理の内容説明をします。
まず、抽選ボタンを押して抽選中にまた押されるとこまるので、変数timer_swが1の時は処理をしません。
次にRS232Cのオープンです。オープンした後、9(抽選開始)を表示パソコンに知らせます。ここからはタイマー割り込みで変数timer_swが9になるまでwhile文で待ちます。このループの中に入れているApplication.DoEvents
メソッドは、ループ処理中に画面終了(画面右上の[×]を押したとき)や他のソフトを動かすなどの処理があるときはWindowsに「同時に動かしてください」という指令になります。
変数timer_swが9の状態でwhileループを抜けると、変数atari_swのデータ0,1,2,3,8を送り、RS232Cをクローズして終わります。