MSX0のプログラミングメモ

MSX0 Stackに関して、私がつくった簡単なBASICプログラムや、プログラミングのメモなどを載せていきます

MSX0でミニクイズ

概要

MSX0のタッチパネルに対応した、4択ミニクイズのプログラムです。

MSX0ミニクイズアプリのタイトル画面
MSX0ミニクイズアプリのクイズ画面

タイトル画面と、クイズ画面と、解説画面があります。
緑のボタンをタッチパネルで押せます。
(キーボードでも、1〜4のキーと、スペースキーで操作できます)

全部で15問あります。
BASICプログラムは下にありますが、今回はクイズデータが別ファイルでありますので、そちらも必要です(ファイル名:quiz.txt)。

ですが、クイズデータのテキストを見るとネタバレになるので、今回はディスクイメージも用意しましたw
https://data.hellotocky-msx.net/blogdata/msx0_quiz/quiz.dsk
(クイズの内容に誤りがあったら、そっと教えてくださいw)

プログラムの中で使えそうなところがあったら、自由に使っていただいて結構です。
またプログラム全体の転載は、このブログのURLも紹介していただければOKです(出典が明らかになれば)。

テキストファイルも好きに書き換えていただいて構いません。

1行目がタイトル、
2行目がクイズ本文、
3行目が選択肢(半角スペース3つで区切る)
4行目が解説、
5行目が正解の選択肢の番号(1~4)
6行目以降は、2~5行目の繰り返しです。
問題数は最大で15問までにしていますが、これを超える場合は、プログラムの20行目のQZ$, Q1$, AN, KA$の個数(15となってるところ)を変えてください。あと2行目の4000というところも、文字列領域が足りなくなったら増やしてください。

プログラム

(すみません、初出時よりもちょっとだけ変えました。360〜363行目を分割、1015行目と1115行目の処理をPLAY文への置き換え)

2 CLEAR 4000:DEFINT A-Z
10 _KANJI0:WIDTH32:SCREEN5:COLOR 1,15,15
20 DEFINT A-Z:DIM BX(5),BY(5),BW(5),BH(5),BV(5),BC(5), BE(1,5),BD(3), QZ$(15),Q1$(15),AN(15),KA$(15), R(2),G(2),B(2)
30 BM=5:BS=2
40 RESTORE 9000:FOR I=0 TO BM-1:READ BX(I), BY(I), BW(I),BH(I), BV(I),BC(I):NEXT I
50 RESTORE 9200:FOR I=0 TO BS-1:FOR J=0 TO BM-1:READ BE(I,J):NEXT J,I
60 LINE(0,0)-(255,211),15,BF
70 RESTORE 2000:FOR I=0 TO 1: READ R(I),G(I),B(I): NEXT I
80 FOR I=2 TO 2+BM-1:COLOR=(I,R(0),G(0),B(0)):NEXT I
90 OPEN "QUIZ.TXT" FOR INPUT AS #1:QM=0:INPUT #1, TT$
91 LOCATE 10,10:PRINT"NOW LOADING..."
92 INPUT #1, QZ$(QM), Q1$(QM), KA$(QM), AN(QM): QM=QM+1:IF EOF(1)=0 GOTO 92
94 CLOSE #1
99 C=0:BB=-1
200 ' title
210 CLS:LOCATE 0,4:PRINTTT$:T$=" スタート":GOSUB 1200:GOSUB 1300
220 PLAY "v12l32o6cde":TIME=0:FOR I=0TO1:I=-(TIME>20):NEXT I
300 ' main
310 QI=0:SC=0
320 COLOR1,15,15:LINE(0,0)-(255,211),15,BF
330 FOR I=0 TO 3:LINE(BX(I),BY(I))-STEP(BW(I),BH(I)),I+2,BF:NEXT I
340 FOR I=2 TO 2+5-1:COLOR=(I,R(0),G(0),B(0)):NEXT I
350 LOCATE 0,1:PRINTQZ$(QI):COLOR1,2
360 LOCATE 2,6:PRINT "①";:GOSUB 400
361 LOCATE 18,6:COLOR1,3:PRINT"②";:GOSUB 450
362 LOCATE 2,10:COLOR1,4:PRINT"③";:GOSUB 450
363 LOCATE 18,10:COLOR1,5:PRINT"④";:GOSUB 450
370 GOTO 500
400 ' cut select start
410 ST=1
450 ' print select one
460 EN=INSTR(ST, Q1$(QI), "   "):IF EN>0 THEN PRINTMID$(Q1$(QI),ST,EN-ST):ST=EN+3 ELSE PRINTMID$(Q1$(QI),ST)
470 RETURN
500 ' touch pad loop
510 BP=0:GOSUB 8000
520 IF BT=-1 GOTO 510
530 IF AN(QI)=BV(BT) THEN SC=SC+1:GOSUB 1000 ELSE GOSUB 1100
540 GOSUB 8000:IF BT<>-1 GOTO 540 ' wait key up
550 COLOR9,15:CLS:LOCATE0,0:PRINT"*解説*":COLOR1:LOCATE0,2:PRINTKA$(QI);
560 QI=QI+1:IF QI<QM THEN T$=" 次の問題へ" ELSE T$="  採点へ"
570 GOSUB 1200:GOSUB 1300
580 IF QI>=QM THEN 800
590 GOTO 320
800 ' finish
810 GOSUB 8000:IF BT<>-1 GOTO 810 ' wait key up
820 COLOR 1,15:CLS:LOCATE 5,3:PRINT"全問終了":LOCATE 3,5:PRINT"スコア:";SC;"(全";QM;"問)"
830 IF SC=QM THEN COLOR 9,15:LOCATE 4,7:PRINT"すごい!満点おめでとう!"
840 T$="  終了":GOSUB 1200:GOSUB 1300
890 END
1000 ' sound seikai
1010 LINE(92,90)-(163,120),9,BF:COLOR 15,9:LOCATE 13,6:PRINT"正解!"
1015 PLAY"v12o6ecec8"
1020 TIME=0:FOR I=0 TO 1:I=-(TIME>100):NEXT I
1040 RETURN
1100 ' sound bubu-
1110 LINE(92,90)-(171,120),7,BF:COLOR 15,7:LOCATE 13,6:PRINT"はずれ!"
1115 PLAY"v12o3c16r32c4"
1120 TIME=0:FOR I=0 TO 1:I=-(TIME>100):NEXT I
1140 RETURN
1200 ' draw next button, input=T$
1210 LINE(BX(4),BY(4))-STEP(BW(4),BH(4)),6,BF:COLOR 1,6:LOCATE 10,12:PRINTT$;
1220 RETURN
1300 ' wait press next button
1310 BP=1:GOSUB 8000:IF BT=-1 GOTO 1310
1320 RETURN
2000 DATA 1,6,1, 2,3,7   :'color
8000 ' touch pad loop
8010 BT=-1:BD(1)=BD(0):BD(0)=PAD(4)
8020 IN$=INKEY$:IF IN$="Q" THEN END
8030 IF IN$="" THEN8040
8031 IN=ASC(IN$):I=0:
8032 IF BE(BP,I) AND BC(I)=IN THEN BT=I:BD(0)=-1:BD(2)=BT:GOSUB8200:RETURN ELSE IF I<BM-1 THEN I=I+1:GOTO 8032
8040 IF BD(1)=-1 AND BD(0)=0 THEN GOSUB 8400:RETURN
8050 IF BD(0)=0 THEN RETURN
8060 X=PAD(1):Y=PAD(2):I=0
8070 IF BE(BP,I)<>0 AND BX(I)<=X AND X<=BX(I)+BW(I) AND BY(I)<=Y AND Y<=BY(I)+BH(I) THEN BT=I:GOTO8090
8080 IF I<BM-1 THEN I=I+1:GOTO 8070 ELSE RETURN
8090 IF BD(2)<>BT THEN GOSUB 8400
8100 BD(2)=BT:GOSUB 8200:RETURN
8200 ' key down
8210 COLOR=(BT+2,R(1),G(1),B(1))
8390 RETURN
8400 ' key up
8410 IF BD(2)<>-1 THEN COLOR=(BD(2)+2,R(0),G(0),B(0))
8590 RETURN
9000 REM button position (X, Y, W, H, value, alt-key-code)
9010 DATA  10, 86,110, 40, 1, 49
9020 DATA 140, 86,110, 40, 2, 50
9030 DATA  10,148,110, 40, 3, 51
9040 DATA 140,148,110, 40, 4, 52
9050 DATA  56,160,144, 48, 5, 32
9200 REM button pattern (btn-0 status, btn-1 status, ... btn-(BM-1) status)
9210 DATA 1, 1, 1, 1, 0
9220 DATA 0, 0, 0, 0, 1

※クイズデータをどうしても別ファイルでダウンロードしたい方は、こちらから
quiz.txt

プログラムの解説

主な処理

行番号 処理の概要
2~99 初期設定・データの読み込み
200~220 タイトル画面の表示
300~370 ①クイズの表示
500~520 ②回答待ち
530~590 ③正解・不正解の処理。解説画面の表示
800~890 ④採点画面

サブルーチン

行番号 エントリ行 処理の概要 受け取る変数 処理結果が
入る変数
400~470 1個目は400
2~4個目は450
クイズの選択肢を1つずつ表示する。 QI=何問目か なし
1000~140 1000 正解の表示・効果音処理 なし なし
1100~1140 1100 はずれの表示・効果音処理 なし なし
1200~1320 1200 「スタート」「次の問題へ」ボタンの表示・操作待ち処理 BT$=ボタンに表示する文字列 なし
8000~8100 8000 ⑤ボタンが押されたかの検出処理 BP=ボタンの有効/無効パターンで、使うもの T=ボタンが押されてなかったら-1。押されてたらそれ以外の数字。
BV(BT)とすると、ボタンに割り振られた数値が得られる。
8200~8390 8200 ボタンが押されたときの処理。⑤がコールする。ここでは、ボタンの色を変えている。 BT なし
8400~8590 8400 ボタンが離されたときの処理。⑤がコールする。ここでは、ボタンの色を変えている。 BT なし

データ

行番号 内容
2000 ボタンの色データ
9000~9050 ボタンの座標などの情報
9200~9220 ボタンの有効・無効状態のパターン

主な変数

全体的に使用するもの

変数名 用途
BX(), BY(), BW(), BH() ボタンのX座標・Y座標・幅・高さ。ボタンの数に応じた個数を定義する。
BV() 押されたボタンごとに対応する値。ボタンの数に応じた個数を定義する。
BC() ボタンの代わりに受け付けるキーのキャラクターコード。ボタンの数に応じた個数を定義する。
BE() ボタンの有効・無効のパターンの定義。ボタンの数に応じた個数を定義する。
BD() ボタン関係のサブルーチン内部データの保存用(0=PAD(4)/タッチパネルが押されてるか, 1=前回のPAD(4)の値, 2=前回押されたボタンの番号)
QZ$(), Q1$(), AN(), KA$() クイズのデータ。QZ$=出題文、Q1$=選択肢、AN=正解の選択肢、KA$=解説文。
最大15問分をメモリに持てるように、それぞれ15個用意してます。
R(), G(), B() ボタンの色。0=押されてないとき、1=押されたとき。
BM ボタンの個数。BX()などの個数と同じ値。
BS ボタンの有効/無効のパターン数。
QM クイズの設問数。ファイルからデータ読み出すときに自動で算出する。

①,②,③,④の部分で使う主なもの

変数名 用途
QI 何問目か。
SC 正解数。

局所的に使うもの

変数名 用途
I, J よく使う、ループ変数。非常によく使うので、短いループで使う。
ほか いろいろ

メモ

  • 4つの選択肢を1つの文字列に入れてるので、ちょっと変わった処理になってます。これは「MSXべーしっ君」を使おうとしたときの制限を回避してた処理の名残りです。
  • 「スタート」とかのボタンで、ユーザーがボタンを押すまでそのまま待つ、という場合は、以下の処理をやってます。
    • T$に文字列を入れてGOSUB 1200とすることでボタンを表示し、
    • GOSUB 1300とすることで、ユーザーがボタンを押すまで待つ
  • クイズの解答を待つ場面では、500~540行目で以下のように処理してます。
    • BPに0を入れて(ボタンのパターン0を選択)、GOSUB 8000とすることで、ボタンが押されてるかを取得。押されるまでぐるぐる回る。
    • 530行目は、答え合わせ。
    • ボタンが押されたら、離されるまで待つ(540行目)。
  • 8000~8100行目は、ほかでも使いまわしができるといいな、と思って書いたものです。
    • ボタンが押されたら8200行目を、放されたら8400行目をコールするので、「押されたら音を鳴らす」とか「振動する」とかの処理を書いてもいいかも(今のMSX0では振動できないですが)。