IchigoJamでズンドコキヨシ


IchigoJamで「ズンドコキヨシ」を実装してみた。

背景

「IchigoJam」とは

BASICでプログラミングができるパソコンである。

こどもパソコン IchigoJam - はじめてのプログラミングパソコン(1500円)

※「IchigoJam」はjig.jpの登録商標

「ズンドコキヨシ」とは

「ズン」か「ドコ」をランダムに繰り返し出力していき、
「ズン」「ズン」「ズン」「ズン」「ドコ」の順に並んだら
「キ・ヨ・シ!」と出力して終了する、というプログラムである。

元ネタ

まとめ

ズンドコキヨシまとめ - Qiita

とりあえず、コードと動作を見ていただこう

シンプル版

普通のテキストで出力する。

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において、「ズンドコキヨシ」を実装した。
単純にテキストで出力するだけでなく、「キ・ヨ・シ!」を大きく表示するなどの工夫をしたバージョンも作った。