Help us understand the problem. What is going on with this article?

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動画)

シンプル版の実行結果 (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動画)

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

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした