見出し画像

IchigoJam でインチキルーレット

某団体競技で、かなりの疑惑の判定が行われたらしい。見てないけど。
その中で使われたデジタルルーレットにも、疑惑の目が向けられているらしい。

そこで、今回は IchigoJam でインチキルーレットを作ってみた。

※IchigoJamはjig.jpの登録商標です。

仕様

1~6のキーを押すと、ルーレットがスタートする。
そして、必ず押したキーに対応する候補で止まる。
(実行の中断や外部からのメモリの書き換えなど、通常の実行から外れる行為が行われた場合は除く)
候補およびその数は、プログラムを書き換えることで変更可能。

実装

値としての文字列を用いるため、IchigoJam 1.2系以降のみに対応している。

10 ' インチキ ルーレット
20 N=6
30 LET[0],"ミケネコ","トラネコ","シャムネコ","クロネコ","ブチネコ","ペルシャネコ"
40 IF VER()>=13224 W=POS(3):H=POS(4) ELSE W=32:H=24
50 D=1+(N*2-1<=H):A=N*D-(D-1):P=(H-A)/2:S=0
60 FOR I=0 TO N-1
70 L=LEN([I]):IF L>S S=L
80 NEXT
90 X=(W-S-1)/2
100 CLS:CLP
110 FOR I=0 TO N-1
120 LOCATE X+1,P+D*I:PRINT STR$([I]);
130 NEXT
140 C=0:F=0:M=0:S=0:B=0
150 LOCATE X,P+D*C:PRINT CHR$(#E1);:LOCATE 0,H-1
160 IF F+M+S=0 GOTO 200
170 IF F>0 T=5:F=F-1 ELSEIF M>0 T=15:M=M-1 ELSE T=40:S=S-1
180 BEEP 10,2:WAIT T:LOCATE X,P+D*C:PRINT " ";
190 C=(C+1)%N:GOTO 150
200 IF B=0 GOTO 230
210 IF B<0 PLAY "L16O5GAB":B=3
220 WAIT 10:LOCATE X,P+D*C:PRINT " ";:WAIT 10:B=B-1:GOTO 150
230 CLK
240 K=INKEY():IF 49<=K AND K<49+N GOTO 260
250 WAIT 1:GOTO 240
260 F=30+RND(31):M=10+RND(11):S=3+RND(4):B=-1
270 E=(C+F+M+S)%N:F=F+(K-49-E+N)%N
280 GOTO 150

このプログラムは、CC BY 4.0 でライセンスする。

OneFiveCrowd で実行する (非公式、通常の速度)
IchigoJam web で実行する (公式、低速)

解説

候補の設定

20 N=6
30 LET[0],"ミケネコ","トラネコ","シャムネコ","クロネコ","ブチネコ","ペルシャネコ"

変数 N で、候補の数を設定する。
そして、配列の先頭から具体的な候補 (のアドレス) を格納する。

配置位置の決定

40 IF VER()>=13224 W=POS(3):H=POS(4) ELSE W=32:H=24
50 D=1+(N*2-1<=H):A=N*D-(D-1):P=(H-A)/2:S=0
60 FOR I=0 TO N-1
70 L=LEN([I]):IF L>S S=L
80 NEXT
90 X=(W-S-1)/2

まず、画面の幅 W と高さ H を取得する。

次に、画面の高さと候補の数から、候補の配置を開始する位置 P と 配置の間隔 D を計算する。
配置の間隔 D は、1行ずつあけて画面内に配置できる場合は1行ずつあけて配置し、そうでない場合は各行に配置するように設定する。
そして、配置に用いる行数 A を計算し、中央に来るように配置を開始する縦位置 P を決定する。

最後に、候補を表す文字列の最大の長さを求め、(ルーレットの選択を表す矢印の分も考えて) 中央に配置するように配置する横位置 X を決定する。

候補の描画

100 CLS:CLP
110 FOR I=0 TO N-1
120 LOCATE X+1,P+D*I:PRINT STR$([I]);
130 NEXT

画面を初期化し、計算した配置に基づいて候補の名前を画面に配置する。

パラメータの初期化

140 C=0:F=0:M=0:S=0:B=0

ルーレットのパラメータを初期化する。
それぞれ以下の意味である。

  • C:ルーレットで選択している要素

  • F:ルーレットが高速で動く残り回数

  • M:ルーレットが中速で動く残り回数

  • S:ルーレットが低速で動く残り回数

  • B:ルーレットが点滅する残り回数

ルーレットの表示

150 LOCATE X,P+D*C:PRINT CHR$(#E1);:LOCATE 0,H-1

選択している要素 C の情報に基づき、選択している要素の左に矢印を表示する。
そして、停止時の見栄えを考え、カーソルを一番下の行に移動する。

ルーレットの移動

160 IF F+M+S=0 GOTO 200
170 IF F>0 T=5:F=F-1 ELSEIF M>0 T=15:M=M-1 ELSE T=40:S=S-1
180 BEEP 10,2:WAIT T:LOCATE X,P+D*C:PRINT " ";
190 C=(C+1)%N:GOTO 150

移動回数 F・M・S のいずれかが正のとき、この処理を行う。
どれが正かによって、移動の間隔 T を設定する。さらに、移動回数を減らす。
そして、音を鳴らし、設定した間隔の待機を行う。その後、表示した矢印を消去する。
最後に、選択している要素を次に進め、次の処理に移る。

ルーレットの点滅

200 IF B=0 GOTO 230
210 IF B<0 PLAY "L16O5GAB":B=3
220 WAIT 10:LOCATE X,P+D*C:PRINT " ";:WAIT 10:B=B-1:GOTO 150

ルーレット停止時の演出を行う。
まず、ルーレットをスタートさせてから最初の実行時 (B が負のとき) には、メロディーを鳴らし、点滅回数を設定する。
その後は、矢印を点滅させながら、点滅回数を減らしていく。

ルーレットの開始

230 CLK
240 K=INKEY():IF 49<=K AND K<49+N GOTO 260
250 WAIT 1:GOTO 240
260 F=30+RND(31):M=10+RND(11):S=3+RND(4):B=-1
270 E=(C+F+M+S)%N:F=F+(K-49-E+N)%N
280 GOTO 150

まず、ルーレット中に押したキーでルーレットが再スタートしないよう、キーバッファをクリアする。
次に、キー入力を受け付ける。

押されたキーが候補に対応する数字であれば、ルーレットの移動回数を設定し、ルーレットをスタートさせる。
まずは普通に乱数で各速度での移動回数を設定し、続いてインチキ用の補正を行う。
インチキは、今の移動回数で止まるはずの候補 E を求め、そこから止めるべき候補に移動するための回数を移動回数に加えることで行う。

この補正処理 (270行目) を消すことで、通常の (インチキを行わない) ルーレットとしても使用可能である。

おわりに

IchigoJam 上で、止める候補を指定できるルーレットを実装できた。

この記事は、冒頭で言及した競技において不正や不公平な審判が行われたか否かを議論するものではなく、この記事で紹介したプログラムは冒頭で言及した競技とは関係がない。


この記事が気に入ったらサポートをしてみませんか?