IchigoJamで「ズンドコキヨシ」を実装してみた。
背景
「IchigoJam」とは
BASICでプログラミングができるパソコンである。
こどもパソコン IchigoJam - はじめてのプログラミングパソコン(1500円)
※「IchigoJam」はjig.jpの登録商標
「ズンドコキヨシ」とは
「ズン」か「ドコ」をランダムに繰り返し出力していき、
「ズン」「ズン」「ズン」「ズン」「ドコ」の順に並んだら
「キ・ヨ・シ!」と出力して終了する、というプログラムである。
元ネタ
Javaの講義、試験が「自作関数を作り記述しなさい」って問題だったから
— てくも❂ (@kumiromilk) 2016年3月9日
「ズン」「ドコ」のいずれかをランダムで出力し続けて「ズン」「ズン」「ズン」「ズン」「ドコ」の配列が出たら「キ・ヨ・シ!」って出力した後終了って関数作ったら満点で単位貰ってた
まとめ
とりあえず、コードと動作を見ていただこう
シンプル版
普通のテキストで出力する。
10 'ズンドコキヨシ (シンプル)
20 Z=0
30 WAIT 30
40 IF RND(2)=0 GOTO 80
50 PRINT "ズン ";
60 Z=Z+1
70 GOTO 30
80 PRINT "ドコ ";
90 IF Z>=4 GOTO 120
100 Z=0
110 GOTO 30
120 WAIT 30
130 PRINT "キ・ヨ・シ!"
実行結果 (YouTube動画)
豪華版
- 「ズン」「ドコ」「キ・ヨ・シ!」の出力に合わせて音を鳴らす。
- 最初、または「ドコ」の次の「ズン」の後は待ち時間を2倍にする。
- 「キ・ヨ・シ!」を大きい文字で表示する。
10 'ズンドコキヨシ (オトツキ)
20 LET[80],#B7,#D6,#BC,#A5,#21
30 CLS:?"LOADING...":LC 0,2
40 ?"[":LC 21,2:?"]":LC 1,2
50 FORI=0TO4:S=I*16:C=[80+I]*8
60 FORJ=0TO15:[S+J]=#80:NEXT
70 FORJ=0TO63:T=S+J/16*4+J%8/2
80 B=PEEK(C+J/8)>>(7-J%8)&1
90 D=(3*(J%16>7)+1)*(J%2+1)
100 [T]=[T]|B*D:IFJ%16=15?"#";
110 NEXT:NEXT:CLS:X=0:Y=0:Z=0
120 X=X+1:IFX>8:X=1:Y=Y+1
130 IFY>18:SCROLL0:Y=Y-1:LC0,Y
140 IFRND(2)=0GOTO180
150 ?"ズン ";:BEEP40,7
160 WAIT30+30*(Z=0)
170 Z=Z+1:GOTO120
180 ?"ドコ ";:BEEP25,5:WAIT15
190 BEEP25,5:WAIT15
200 IFZ<4:Z=0:GOTO120
210 BEEP10,5:X=0:C=0:GOSUB280
220 X=4:C=48:GOSUB280:WAIT10
230 BEEP10,5:X=8:C=16:GOSUB280
240 X=12:C=48:GOSUB280:WAIT10
250 BEEP10,5:X=16:C=32:GOSUB280
260 X=20:C=64:GOSUB280:WAIT10
270 LC0,Y+5:END
280 A=#920+Y*32+X:P=C:FORI=0TO3
290 POKEA,[P],[P+1],[P+2],[P+3]
300 A=A+32:P=P+4:NEXT:RETURN
実行結果 (YouTube動画)
仕組み
「ズンドコキヨシ」本体 (シンプル版・豪華版共通)
乱数の値に応じて「ズン」または「ドコ」を出力する。
IchigoJamの標準で出せる文字では、濁点は1文字として出力することになるため、「ズン」「ドコ」いずれも3文字である。
さらに、今回使用しているバージョンのIchigojamの画面は横32文字×縦24文字である。
そのため、空白を1文字入れ、1ワードを4文字で出力すると、きれいに表示できる。
「ズン」を表示したら、カウンタを1増やす。
「ドコ」を表示したら、カウンタの値をチェックする。
カウンタの値が4以上であれば「キ・ヨ・シ!」を出力する処理に移り、そうでなければカウンタを0に戻す。
大きな文字の表示 (豪華版)
フォントを読み取り、表示用の表現に変換する
IchigoJamで扱う文字は、8×8ドットである。
PEEK(仮想アドレス)
関数を用いることで、メモリの値(バイト)を読み取ることができる。
IchigoJamで表示する文字コードC
の文字のフォントは、仮想アドレス8*C
からの8バイトに格納されている。
このフォントは、最初(下位)のバイトが一番上の行、最後(上位)のバイトが一番下の行である。
各行は1バイトで表され、一番左が最上位ビット(MSB)、一番右が最下位ビット(LSB)である。
各ビットは0が黒、1が白を表す。
IchigoJamでは、文字コード128+n
(n=0~15) が描画用の文字となっている。
これらの文字は、8×8の文字の領域が縦横各2分割されてn
の各ビットに対応し、
下位ビットから順に左上、右上、左下、右下である。
こちらも0が黒、1が白となっている。
これらを踏まえると、フォントから描画用の文字を用いた表示用の表現に変換できる。
表示用の表現は、4文字×4文字の16文字である。
豪華版のコード中では、70行目~110行目で変換処理を行っている。
その中でも点の変換を行っている部分は
T=S+J/16*4+J%8/2
B=PEEK(C+J/8)>>(7-J%8)&1
D=(3*(J%16>7)+1)*(J%2+1)
[T]=[T]|B*D
である。
変換する点の情報は、C, S, J
で表される。
C
は、変換するフォントの先頭の仮想アドレスである。
S
は、表示用の表現を格納する配列の先頭の添字である。
J
は、変換する点の位置であり、上から下、行の中では左から右の順番である。
変換に用いる情報は、T, B, D
で表される。
T
は、表示用の表現(出力)中の変換する点がある文字の位置(添字)である。
B
は、フォント(入力)の中の変換する点の情報である。
D
は、表示用の表現(出力)中の文字の中の変換する点を表すビットである。
それぞれの変換を詳しく見ると、
T= 変換先の位置は
S 出力位置の指定
+J/16*4 + 点の縦位置 (2行=16点ごとに動き、1行=4文字分ずれる)
+J%8/2 + 点の横位置 (1行=8点周期で動き、2点で1文字ずれる)
B= 変換元のビットは
PEEK(C+J/8) 8点ごとに1行動く位置を用いて取得するフォントのバイトから
>>(7-J%8)&1 8点周期で左から動く位置を用いて取得する
D= 変換先のビットは
(3*(J%16>7)+1) 2行セットのうち下の行なら4か8、上の行なら1か2
*(J%2+1) 2列セットのうち左なら1か4、右なら2か8
[T]=[T]|B*D 変換元のビットが1なら、変換先にビットを加える
となっている。
表示用の表現を出力する
メモリの仮想アドレス#900~#BFF
(十六進数の900~BFF) がVRAMであり、
ここに書き込んだ値を文字コードとして解釈することで画面に表示される文字が決定される。
POKE 書き込み先の仮想アドレス,書き込む値[,書き込む値[,...]]
命令により、メモリに書き込むことができる。
出力を行っているのは、豪華版の280行目~300行目である。
変数Y
に「ズン」や「ドコ」を表示している位置が格納されているため、
その1行下、すなわち32文字先から出力をする。
A
に書き込むVRAMのアドレス、P
に書き込むデータがある配列の添字を格納する。
1行に4文字を出力し、次の行に行く。
素早く出力できるように、1文字ずつ出力するのではなく、
連続した領域に1回で書き込めるPOKE
の性質を用い、1行の4文字をまとめて書き込んでいる。
まとめ
BASICが実行できるパソコンであるIchigoJamにおいて、「ズンドコキヨシ」を実装した。
単純にテキストで出力するだけでなく、「キ・ヨ・シ!」を大きく表示するなどの工夫をしたバージョンも作った。