こんにちはKIMTECHです。

前回までに抽選部分マイコンのループ以外の3つの部分の説明を行いました。
ざっと繰り返すと、定義部分でどんな機能を使うか定義し、変数初期化部分では変数の定義・初期化、LOOP内は本体で抽選、関数群はLOOP内で指示された処理を行ないます。
1-79行 定義部分
81-94行 変数初期化部分
96ー1445行 LOOP
1447-2156行 関数群
注;プログラムの一部が正しく表示されず、//*1-4 ブログ最後尾に参照 となって、最後尾に一覧になっています。
今回は一番新しい”クランキーチャレンジを搭載したドラゴンハナハナを作ってみた”のプログラムで説明を行います。
https://github.com/kimtech806/hanatika/blob/main/dra_cra_Ver.txt
C++のif文、switch文、while文などを使用します。文法・制御文・関数については説明しません。
Arduino日本語リファレンス
http://www.musashinodenpa.com/arduino/ref/
等で勉強することをお勧めします。
今回はこのプログラムの本体のループについて説明を行います。まずプログラムの動作する基本ルールですが、一番上から始まって下に向かって進みます。そして"loop(){ }"内の{ }の中の内容をひたすら上から下へ繰り返されます。一番最後の関数は、必要に応じて呼び出されて、作業が終わったら元のループ内の位置に戻ります。
試しに1-94行の内容を切り取って、プログラムの最後にコピーしてみてください。IDEでコンパイルするとエラーが出るはずです。プログラムはタスクの順番、流れを考えて作らないと成功しないものです。
では本題ですが、LOOP内で行われている抽選、まず基本的な抽選の仕組みと、追加部分(確変処理)について整理しなければなりません。
KIMTECH沖スロ機械では、4号機的複雑な抽選を行うために主に4つの追加部分を持っており、基本的な抽選の仕組みに4つの追加部分を組あわして制作しています。
1、テーブル
2つの大テーブルと、その中に複数の小テーブルを持ち、それらを移行する事で複雑な処理を行なう。
2、ST
大当たり後、50回転まで高確などの処理ができる。(変数を工夫すれば、確変確定50ゲームで後は1/20で転落抽選も可能。)
3,ゲート(門)
変数が有るか無いか、何個以上あるか、で別の抽選処理を行なう処理。
4,分母
確率の分母を下げる事で確変処理を行なう。
これらは今回は説明しません。
ループ内の役割分け ループ内 96-1445行
1、トリガーの受信と抽選乱数の生成、大テーブル用の数値の取得 98-119行
レバーやLFOの信号を受信すると指定された範囲内の乱数を生成して、変数”moti”に代入します。(トリガーの受信と乱数の生成)
アナログリードPIN A0(データ機下段から指示)から数値を取得して、変数”s_set”に代入します。(大テーブル用の数値の取得)
2,大テーブル(低確、盤面LEDは緑色に表示。)121ー555行
ボーナス後、データ機下段から指定されたゲーム数を超えたゲームの抽選を行う。いわゆる低確テーブル。

(LED右 緑が点灯で”低確テーブル”)
3,大テーブル(高確、盤面LEDは橙色に表示。)560ー1438行
ボーナス後、データ機下段から指定されたゲーム数以内のゲームの抽選を行う。いわゆる高確テーブル。

(LED右 橙が点灯で”高確テーブル”)
4、抽選乱数(変数”moti”)、小テーブル(変数”vmode”)の初期化。 1439-1444行
では先に基本的なループの動作をプログラムを指し示しながら解説します。プログラムを読みながら理解することが重要です。
基本的動作には”待機”と”トリガー受信”があります。
”待機”(いつでもトリガーを受信できる状態、盤面LED青色が点灯)
電源を点けて何もしなければ常にこの状態です。盤面LED(GPIO5ピン)がずっと青色に点灯しています。

(LED左 青が点灯で”待機”)
1,初期設定では抽選乱数の変数”moti”は”0”に指定されています。トリガーが無いと抽選乱数が生成されませんので”0”のままです。
2,118行の大テーブル変数”s_set”の数値に従い、大テーブル低確(121-555行)か大テーブル高確(560ー1438行)の、どちらか一方のタスクのみを行います。今回は大テーブル低確(121-555行)に入ります。
3,子テーブル変数”vmode”初期値”0”に従い、358-554行の小テーブル”0”に入ります。そして抽選乱数の変数”moti”は”0”ですので、
360-363行
if(moti ==0){//低確 215 1/304 高確 1/242
// reset
s_reset();
}
"moti"が0であれば{ }内を実行、の指定された関数処理が呼び出されます。
1802ー1812行
void s_reset(){
digitalWrite(3,LOW);
digitalWrite(4,LOW);
digitalWrite(5,HIGH); //青色LED点灯
digitalWrite(6,LOW);
digitalWrite(7,LOW);
digitalWrite(8,LOW);
digitalWrite(9,LOW);
play(0x00);
delay(30);
}
GPIO5ピンのみを点灯して後は全て消灯、音の初期化を指定という処理です。
4、そして抽選乱数(変数”moti”)、小テーブル(変数”vmode”)を”0”に初期化。 1439-1444行の内容が行われ(どちらも元々”0”なので変化なし。)またループ先頭の96行に戻り、永遠にこの処理が繰り返されます。
多分、一秒間に100回程度はこの処理が行われているでしょう、”待機”ですので高速処理でトリガーを待っているだけの状態です。
”トリガー受信”(GPIO 2ピンにトリガーを入れると発動、盤面LED青色が消灯)
電源を入れて”待機”の処理が高速でループしていますが、トリガーを感知すると以下の動作が行われます。

(LED左 青が消灯で”抽選”)
1,98行のタスクが行われる際にGPIO 2ピンがトリガーを感知すると、98-117行の処理 変数”adata”初期値0に1が代入され、以下adataが1以上なら変数”moti”初期値”0”に1-65536のランダムな数字が一つ代入、ここでは例えで"10000"の数字を代入値とします、そして最後にadataが0に初期化されます。
stateD = digitalRead(2); // read
if ( stateD == 1 && stateF == 0 ) // plus count
adata++;
stateF = stateD;
delay(10);
switch(i){
case 0:
if(adata>=1){
moti = random(1,65537);
}
break;
case 1:
if(adata>=1){
moti = random(1,51561);
}
break;
}
if( adata >= 1){
adata -= 1;
}
2,118行の大テーブル変数”s_set”の数値に従い、大テーブル低確(121-555行)か大テーブル高確(560ー1438行)の、どちらか一方のタスクのみを行います。今回は大テーブル低確(121-555行)に入ります。
3,子テーブル変数”vmode”初期値”0”に従い、358-554行の小テーブル”0”に入ります。そして抽選乱数の変数”moti”は”10000”ですので、
411-413行
else if*1{ //*1 ブログ最後尾に参照
n_loss();
}
"moti"が9000から13000であれば{ }内を実行、の指定された関数処理が呼び出されます。
1813ー1832
void n_loss(){ //低テーブル用
digitalWrite(11,LOW);
digitalWrite(3,LOW);
digitalWrite(4,LOW);
digitalWrite(5,LOW); //青色LED消灯
digitalWrite(6,HIGH); //回転数 オン
digitalWrite(7,LOW);
digitalWrite(8,LOW);
digitalWrite(9,LOW);
play(0x07);//レバー音再生
delay(1200);//レバー音再生時間
v_blank();//液晶画面消灯
delay(200);
play(0x08);//BET音再生
delay(800);//BET音再生再生時間
digitalWrite(11,LOW);
big_p = 0;
reg_p = 0;
stc = 0;
}
GPIO5ピンを消灯、GPIO6ピン回転数オン(データ機上・下に送られゲーム数が加算されます)、レバーとBETの音楽を流す処理をしています。この処理はハズレの処理になります。
4、そして抽選乱数(変数”moti”)、小テーブル(変数”vmode”)を”0”に初期化。 1439-1444行
の内容が行われ(変数”moti”は”10000”から”0”へ、変数”vmode”は元から”0”なので変化なし。)またループ先頭の96行に戻り、”待機”の処理が繰り返されます。
この3,の際に、”moti”が"950"なら
367-370
else if*2{ //*2 ブログ最後尾に参照
n_loss();
vmode = 1;
}
"moti"が947から960以内であれば{ }内を実行、の指定された関数処理が呼び出されます。
先ほどのn_loss(); ハズレが発動し、
vmode = 1; で小テーブルが1ボーナス準備(224-355行)に変わり、次ゲームでボーナス告知という事になります。
つまり65536通りの総乱数の内、当たりの数が何個あるかで大当たりの確率が決まるという事です。例えば当り数が"300"存在すれば1/218となります。
その数を
else if*3{ // *3 ブログ最後尾に参照
の数字の部分に割り振っていきます。
else if*4{ //*4 ブログ最後尾に参照
と一気に300割り振ることも可能ですが、アルドゥイーノの乱数は結構偏りがあるので、極端に固めると当たり過ぎたり全然当たらなかったりと不安定です。
KIMTECHはいつも5段階位に分けて配置しています、総乱数が65536通りもありますからね。
今回の内容だけで単純なAタイプの沖スロが出来ました。次回のテクニック編で、上の4つの追加部分を組み合わせた複雑な抽選処理方法を説明します。
最後に基本的なループ内の動作をまとめると
● 電源を入れると自動的に”待機”の処理を高速で繰り返します。(青色LEDが点灯)
● トリガーを入れると、乱数を一つ取得。”moti”へ代入。
● 指定された大テーブルの中の小テーブルにて、””motiに割り振られた処理を行なう。 (青色LEDが消灯)
● ループ最終で乱数と小テーブルの変数が初期化。
● 乱数が初期化され”0”に戻ることにより、自動的に”待機”の処理を高速で繰り返す状態に戻ります。(青色LEDが点灯) 以下繰り返しです。
基本の動きはこんな感じです。同じようなふるまいを他の電子工作などでさせたい場合にも参考になると思いますので、よかったらプログラムを全文読んでみてください。
では今回の内容は以上です。ご視聴ありがとうございました。











