ORANGE pico で「こずめぐ」みたいなやつスロット

[ORANGE pico](http://www.picosoft.co.jp/orange/) で「こずめぐ」みたいなやつがスロット形式で出てくるやつを作ってみた。

「こず」「めぐ」「つづ」「さや」「かほ」「るり」「さち」
の7種類からスロット形式で2種類を選び、「こずめぐ」みたいな文字列を作り出す。
同じものは選ばず、必ず2種類を選ぶようにした。

# プログラム

```
10 mptr 0
20 mdata 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,63,240,0,0,255,254,0,3,255
30 mdata 255,128,7,224,31,224,15,192,3,240,15,0,0,248,6,0,0,120,0,0,0,120,0,0,0,248,0,0,1,240
40 mdata 0,0,3,224,0,0,1,192,0,0,0,0,0,0,0,0,0,0,0,0,12,0,0,0,31,0,0,0,15,128
50 mdata 0,0,7,224,0,0,3,254,0,0,1,255,255,248,0,63,255,252,0,3,255,252,0,0,0,0,0,0,0,0
60 mdata 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,8,0,0,135,28,0,1,199,28,0,1
70 mdata 199,156,0,1,195,12,0,1,192,0,0,1,192,0,15,255,255,192,31,255,255,224,15,255,255,224,0,1,192,0
80 mdata 0,31,192,0,0,63,192,0,0,127,192,0,0,255,192,0,0,243,192,0,0,227,192,0,0,227,192,0,0,231
90 mdata 192,0,0,255,128,0,0,255,128,0,0,127,0,0,0,15,0,0,0,31,0,0,0,62,0,0,0,124,0,0
100 mdata 0,124,0,0,0,48,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
110 mdata 0,0,4,0,0,0,14,0,0,0,14,0,1,0,14,0,3,128,15,0,3,128,7,0,3,128,7,135,255,128
120 mdata 3,255,255,192,3,255,255,224,3,254,7,240,7,240,15,120,15,240,15,56,15,120,30,56,30,60,62,60,30,60
130 mdata 60,28,28,31,248,28,28,15,240,28,30,15,240,28,15,63,192,28,15,255,192,28,7,253,240,12,3,240,254,0
140 mdata 0,0,127,0,0,0,31,0,0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
150 mdata 0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,30,0,0,0,126,0,0,0,252,0,0,3,240,0
160 mdata 0,7,224,8,0,31,129,28,0,63,3,156,0,124,3,156,0,248,3,140,1,240,1,128,3,224,0,0,7,192
170 mdata 0,0,7,128,0,0,7,192,0,0,3,248,0,0,0,252,0,0,0,127,0,0,0,15,192,0,0,7,240,0
180 mdata 0,1,252,0,0,0,126,0,0,0,31,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
190 mdata 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,0,0,0,0,0
200 mdata 31,255,0,0,63,255,192,0,31,255,248,0,0,1,252,0,0,0,126,0,0,0,15,0,0,0,7,128,0,0
210 mdata 3,128,0,0,3,192,0,0,1,192,0,0,1,192,0,0,1,192,0,0,1,192,0,0,3,192,0,0,7,192
220 mdata 0,0,7,128,0,0,15,0,0,0,30,0,0,0,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
230 mdata 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,0,0,0,0,24
240 mdata 0,0,4,60,0,0,14,30,0,0,15,14,0,0,7,6,32,0,3,0,127,255,128,0,127,255,224,0,63,255
250 mdata 248,0,0,0,252,0,0,0,62,0,0,0,14,0,0,0,15,0,0,0,7,0,0,0,7,0,0,0,7,0
260 mdata 0,0,7,0,0,0,7,0,0,0,7,0,0,0,7,0,0,0,15,0,0,0,63,0,0,0,126,0,0,0
270 mdata 124,0,0,0,112,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
280 mdata 0,0,0,0,0,6,0,0,0,15,0,0,0,7,0,0,0,7,128,0,0,3,192,0,0,3,255,0,0,255
290 mdata 255,128,15,255,255,128,31,254,224,0,15,128,224,0,0,0,240,0,0,0,112,0,0,0,120,0,0,0,56,0
300 mdata 0,0,60,0,0,3,252,0,0,7,252,0,4,3,252,0,15,0,0,0,15,128,0,0,7,240,0,0,3,248
310 mdata 0,0,0,255,0,0,0,31,255,192,0,15,255,224,0,1,255,224,0,0,0,0,0,0,0,0,0,0,0,0
320 mdata 0,0,0,0,0,0,0,0,0,1,0,0,0,3,128,0,0,3,131,192,1,3,143,224,3,131,255,240,3,193
330 mdata 255,120,1,239,252,56,1,255,224,60,3,255,224,60,7,248,224,60,15,248,96,60,14,56,0,24,0,60,0,0
340 mdata 0,28,0,0,0,28,0,0,0,30,0,0,0,15,0,0,0,7,0,0,0,7,0,0,0,7,128,0,0,3
350 mdata 128,0,0,3,192,0,0,1,192,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
360 mdata 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,3,128,0,0,7,129,0,0,7
370 mdata 131,192,31,255,3,192,63,255,1,224,63,254,0,224,24,31,128,240,0,31,192,112,0,63,224,48,0,60,240,0
380 mdata 0,120,120,0,0,112,56,0,0,112,60,0,0,240,28,0,0,240,28,0,0,224,28,0,1,224,28,0,1,224
390 mdata 28,0,3,192,60,0,7,194,124,0,7,135,120,0,3,7,240,0,0,7,224,0,0,3,224,0,0,0,0,0
400 mdata 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,7,3
410 mdata 255,224,15,7,255,240,14,7,255,240,14,3,15,0,14,0,15,0,14,0,14,0,14,0,14,0,14,4,14,0
420 mdata 14,15,255,240,30,15,255,248,28,7,255,248,28,0,14,0,28,0,14,0,28,0,14,0,28,0,14,0,28,0
430 mdata 254,0,28,1,254,0,28,3,255,0,28,67,143,128,30,227,143,192,15,227,223,240,15,225,254,248,7,225,252,124
440 mdata 3,192,248,30,0,0,0,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255
450 mdata 224,0,1,255,254,0,0,255,255,0,0,0,127,0,0,3,254,0,0,7,240,0,0,15,192,0,0,63,0,0
460 mdata 0,254,0,0,1,248,0,0,3,224,0,0,3,254,0,0,3,255,224,0,1,255,240,0,0,3,248,0,0,0
470 mdata 56,0,0,0,60,0,0,0,28,0,0,62,28,0,0,255,156,0,1,255,220,0,1,243,252,0,1,225,252,0
480 mdata 0,255,252,0,0,255,248,0,0,127,224,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
490 mdata 0,0,0,0,1,0,0,48,3,128,0,120,3,128,0,120,3,128,0,112,3,128,0,112,3,128,0,112,3,128
500 mdata 0,112,3,128,0,112,3,128,0,112,3,128,0,112,3,128,0,124,3,128,0,126,3,128,0,126,7,128,0,124
510 mdata 7,128,0,60,7,0,0,0,15,0,0,0,31,0,0,0,30,0,0,0,60,0,0,0,60,0,0,0,120,0
520 mdata 0,0,248,0,0,0,240,0,0,1,224,0,0,3,224,0,0,7,192,0,0,7,0,0,0,0,0,0,0,0
530 mdata 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,14,0,0,0,15,0,0,0,7,128,0
540 mdata 0,3,128,0,0,7,255,128,31,255,255,192,63,255,255,192,31,254,224,0,0,0,240,0,0,0,112,0,0,0
550 mdata 120,0,0,0,56,0,0,0,56,0,0,0,56,0,0,3,56,0,0,7,252,0,0,3,252,0,16,1,248,0
560 mdata 56,0,0,0,60,0,0,0,30,0,0,0,15,0,0,0,7,192,0,0,3,240,0,0,1,255,255,224,0,127
570 mdata 255,240,0,31,255,240,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,14,0,0
580 mdata 0,14,0,0,0,14,0,0,0,14,31,0,0,15,255,128,7,255,255,128,15,255,248,0,7,255,0,0,0,14
590 mdata 0,0,0,30,0,0,0,30,0,0,0,28,0,0,0,31,252,0,0,31,255,0,0,15,255,128,0,0,7,192
600 mdata 0,0,1,192,0,0,1,224,0,0,0,224,0,0,0,224,0,0,0,224,0,0,0,224,0,0,3,224,0,24
610 mdata 127,224,0,63,255,192,0,31,254,0,0,15,224,0,0,0,0,0,0,0,0,0
620 for i=0 to 32*4-1
630 mdata &HFF
640 next
650 black=rgb(0,0,0):white=rgb(255,255,255):start=32:stop0=28:stop1=29:psize=32
660 cls:select0=0:select1=1:stopped0=1:stopped1=1:drawn0=-1:drawn1=-1
670 if drawn0==select0 then goto 730
680 gput 160-psize*2,100-psize/2,psize,psize*psize/4*7,black
690 gput 160-psize,100-psize/2,psize,psize*psize/4*7,black
700 gput 160-psize*2,100-psize/2,psize,psize*psize/4*select0,white
710 gput 160-psize,100-psize/2,psize,psize*psize/4*select0+psize*psize/8,white
720 drawn0=select0
730 if drawn1==select1 then goto 790
740 gput 160,100-psize/2,psize,psize*psize/4*7,black
750 gput 160+psize,100-psize/2,psize,psize*psize/4*7,black
760 gput 160,100-psize/2,psize,psize*psize/4*select1,white
770 gput 160+psize,100-psize/2,psize,psize*psize/4*select1+psize*psize/8,white
780 drawn1=select1
790 pause 20
800 k=inkey()
810 if k==start && stopped0 && stopped1 then stopped0=0:stopped1=0
820 if k==stop0 then stopped0=1
830 if k==stop1 then stopped1=1
840 if stopped0 && stopped1 then goto 800
850 if stopped0 then select1=(select1+1)%7:select1=(select1+(select1==select0))%7:goto 670
860 if stopped1 then select0=(select0+1)%7:select0=(select0+(select1==select0))%7:goto 670
870 select0=(select0+1)%7:select1=(select1+1)%7:select1=(select1+(select1==select0))%7:goto 670
```

このプログラムは、[CC0 1.0](https://creativecommons.org/publicdomain/zero/1.0/deed.ja) でライセンスする。

# 操作方法

* スペースキー：スロットの回転を開始する
* 左矢印キー：左側の回転を止める
* 右矢印キー：右側の回転を止める

# 実行結果例

<iframe width="640" height="480" src="https://www.youtube.com/embed/pWEAUulUvv8?si=hO8p-HsW-9he-F2l" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe>

# 解説

## 10～640行目：文字データの用意

`gput` コマンドで使用する文字データを用意する。
文字データ (画像データ) は、以下の形式である。

* 画像の上から下の順番でバイトを並べる
* 同じ行では、画像の左から右の順番でバイトを並べる
* 1バイトの中では、MSBが左、LSBが右に対応する
* 「1」のビットが描画するピクセルを、「0」のビットが描画しないピクセルを表す

さらに、文字の消去用の「全部描画する」データも用意する。

## 650行目：パラメータの用意

描画色、操作用のキーコード、使用する文字のサイズの情報を用意する。

## 660行目：状態の初期化

現在選択されている文字、回転が停止中か、現在描画されている文字の情報を初期化する。

## 670～790行目：文字の描画

選択されている文字が更新されている場合、描画されている文字を消去し、新しく選択された文字を描画する。
そして、描画した文字の情報を更新する。

## 800～830行目：操作の受付

キー入力を受け取り、あらかじめ設定されたキーコードの場合はそれに応じて回転の開始や停止を行う。

## 840～870行目：回転

停止していない部分を回転させる。
回転した結果他方と選択が被る場合は、さらに1段階回転させることにより重複を回避する。

# 今回新たに発見した罠

## mdataコマンドで指定するデータ列の長さには制限がある

公式のコマンド一覧では、

> ```
> mdata データ列 
> ```

と書かれており、「データ列」の長さの制限は書かれていない。

しかし、実際に `mdata` コマンドを使用してみると、データを30個指定した

```
mdata 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,0,0,0,0,0
```

(65文字) はエラーにならずに実行できたが、データを1個増やして31個にした

```
mdata 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,0,0,0,0,0,0
```

(67文字) は「Formula too cmplex」が出てしまった。

したがって、`mdata` コマンドでは1回につきデータを30個までしか指定できないと考えられる。
データ30個では、1個のデータ (区切りのカンマを除く) を3文字で表しても125文字であり、勝手に文字が消される長さである256文字までにはまだかなり余裕がある。
それにもかかわらずこの数を超えるデータが受け付けられないというのは、厳しい制限であるという印象が強い。