サンプルプログラム3(前)
配列変数のことはもう大丈夫ですか?
もはやこの章ではあたりまえのように配列がFOR文といっしょに使われています。
一歩ひきかえすのもいいかもしれません。何度も読んだり、自分で打ってみて、ついでにちょっと書き換えたりしてみて、自分のものになることもあるものです。
心配のしすぎだったでしょうか。
前回はかなりプログラムっぽいことをやったので、今回はちょっと方向をかえてリアルタイムのキー入力や、十字ボタンの操作なんてやってみます。
「リアルタイム」というのは、まあいろいろ意味はあるんですが、いまは「押したらすぐ動く」みたいなものと思っていいんじゃないでしょうか。
けっこうゲームっぽいですね。
そういう意味ではけっこう大事なことをまなぶサンプルかもしれません。
けっこう長くなっているので、今回と次回の2つにわけて見ていきましょう。
あと、BEEP命令で音を出すヒントもちょっとついてますよ。

サンプルプログラム3は、まあちょっとした楽器プログラムじゃな。
LOAD”SAMPLE3”
RUN

これを読んでいるPCなどの前のみんなも、サンプルをRUNしてためしてみよう! 前も言ったけど。
今回はプログラムリストをDSiで見ながら読むとわかりやすいよ!

ピアノ風のキーボードが1オクターブと、ドラムが4音使えるんだね。

ツーバスやハイハットを考えてねェあたり好感がもてるぜ。だがピアノなんざ資産階級のオモチャじゃねえか! いただけねえな!

ワンパク君はいささか音楽的にかたよったエイキョウばかり受けている気がするんじゃが、まあピアノがイヤならプログラムを改造するというコトもできるぞい。

プログラムをサイショから見ていこうか。まず気になるのはどこかな?

1~21行まではだいたいおなじみの画面表示だね。7行目が引っかかるなあ。
0007#. SYSBEEP=FALSE
「
=」を使ってるってことは、変数?

いいところに気がついたね。このSYSBEEPは「システム変数」という、変数の一種なんだ。システム変数はプチコンの動作にかかわるデータが入るようになっているよ。

ウンザリだぜ! 配列変数をやっとオボえたってのに、また変数のバリエーションかよ!

今はこんがらがりそうだから変数のことは考えずに、命令として丸暗記しておいた方が早いかもしれないね。
「SYSBEEP=FALSE」と書くと、プチコンのシステム音が鳴らなくなるんだよ。

オボエるのがそれだけなら、まあカンタンかな。このプログラムでキーボードを打っても、いつもの「ポツッ」ていう音が出なかったのはSYSBEEPを使ったからなんだね。

そういやBEEPはサウンドを鳴らす命令だったな。SYSBEEPの「SYS」ってのはシステムの「シス」ってコトか?

「FALSE」は「まちがった」って意味だと思ったけど……

プログラムの世界ではちょっと意味が変わって「偽」などと言うのじゃが、どう見てもイッパンテキではないのう。おおざっぱなオボエかたじゃが、アリ・ナシの「ナシ」がFALSE、とオボエると今後なにかとワカりやすいぞい。

システムのBEEPが「ナシ」、つまりシステム音を鳴らさない、ってコトか……ワカりやすいが、じゃあ鳴らすようにモドすにはどうすりゃイイんだ?

イッキにプログラムのサイゴになるが、89行で使っておるな。
0089#. SYSBEEP=TRUE
「
TRUE」は「
真」と言うが、これも「アリ」とオボエておけばよかろう。

ワカモノコトバをムリに使ってるカンジもするが、ワカりやすいことはタシカだな!

それ、ワシに言っとるのかの……?

23~43行は、配列とFOR~NEXT、READ・DATAを使ったおなじみのプログラムだね。

配列変数N$()にキーボードを左からジュンに入れてるのはだいたいワカったゼ。たぶん、そのウチこの変数を使うんだろ。

40行で使っている変数
KCNTは何なんだろう?
0040#. KCNT=20
0041#. FOR I=0 TO KCNT-1

ケンバンの数、すなわち20コと考えてもらえばいいかの。「Kenban」の「CouNT」じゃからKCNTじゃ。変数の名前を決めるのはけっこうナヤむところじゃわい。

おっと待った、こういうコトにはオレはうるさいゼ! わざわざ変数にしなくても、FOR I=0 TO 19でいいんじゃねェか!?

う、ウム。このアトにも1回しか使っておらんし、そうとも言えるのう。じゃが、コレはケンバンの数をふやす改造をするトキにベンリなように作っておるのじゃよ。

39行で
DIM N$(20)と変数を使わずに配列宣言をしているから、カンペキじゃないけどね。
0039#. KCNT=20
0040#. DIM N$(KCNT)
となっていればもっと良かったんじゃないかな。

インテリ君のレイセイなシテキは、ときどきワシの心をスルドクえぐるぞい……。

まァそのヘンはいいとしてもよォ、42行で1文字スペースがあいてんのはナンかイミあんのか?
0041#. FOR I=0 TO KCNT-1
0042#. READ N$(I)
0043#. NEXT I

これはプログラム用語で「インデント」というヤツじゃな。カンタンに言えば、FORやGOTOで「くり返しているナカミ」のブブンだけ、1文字スペースを空けておるのじゃ。
これはまだ1行じゃからあまりイミはないが、ナカミが何行もあったりFORの中にFORがあったりするトキには、なかなか見やすくなっててイイものじゃぞい。

「
’」のコメントもそうだけど、プログラムがどう動いているのか、リストを他人が見てもすぐわかるように書くのはダイジだよね。
そのわりに次の46~47行の変数のイミが分かりづらいけど……
0046#. F=4096/12
0047#. V=22

インテリ君は上げてから落とすのがウマいのう……。
0046#. F=4096/12
0047#. V=22

この変数のイミを教えるには、まずBEEP命令についてもっとクワしく説明がヒツヨウじゃな。
BEEP 22でピアノの音を鳴らす、ココまでは知っておるハズじゃな?

このプログラムでも使っている音色ですね。

その先はボクが説明しようか。BEEP命令にはもっとフクザツな使い方があって、ピッチを決めることもできるんだ。

ビ……?

「PITCH」は「音高」とも言うんだけど、カンタンに言えば音の高さのことだね。

音の……タカ……?

ワンパク君は音楽系のキャラだと思っていただけに、さすがにその反応にはオドロキを隠せないよ。
たとえばドレミの「ミ」の音は「ド」より「高い」という言い方をするよね。ドからレ、レからミ、ファソラシド……と先に行くほどピッチが高くなる、と思えばだいたいマチガイじゃないよ。

音楽リロンを気にしてるようじゃパンクじゃねーゼ! もっとストレートにセツメイしやがれ!

たとえばBEEP 22,0はピアノのドの音が鳴って、BEEP 22,682でレの音になると言えば実感できるかな?

「,」の後の数字がピッチになっているんだね。

ちょっとセンモン的な話になるけど、ピッチが-8192だと2オクターブ下、8192で2オクターブ上になるよ。つまり半音は4096÷12という……

それイジョウ難しいコトをさえずるようなら、オレのベースが火をふくゼ!

ワンパク君にとってのベースギターは人をナグる武器だからなあ。

うーん、じゃあこう説明しよう。ドレミをセイカクに言うと「ド・ド#・レ・レ#・ミ・ファ・ファ#・ソ・ソ#・ラ・ラ#・シ」だね。最初の「ド」がピッチ0だと考えて、ひとつ右に行くごとにピッチの数字が4096/12ずつ増えるとおぼえるといいんじゃないかな。

フーム……まったくリクツがワカった気はしねえが、そういうモンだとわりきってオボエればいいってコトだな!

(ワンパク君のロックと、ボクらが知ってるロックは少しちがうのかもしれない……)

ハナシはワカったようじゃな。そこで46行目にモドるが、F=4096/12というのはまさにピッチを増やすキジュンの数、V=22はピアノの音色の番号というワケじゃ。あとあとBEEP命令でこの変数を使っておるからオボエておいてくれい。

つまり変数Vの数を変えればピアノ以外の音も出せるってワケだな。V=20なんかロックでいいんじゃねェか?

ここを読んでるみんなも数字を変えてRUNしてみよう!

プログラムリストは50行からメインループに入るね。

その「メインループ」ってのはナンだ? メインなのはなんとなくオレにもワカるけどよォ、ループするってコトは無限ループになったりすんのか?

そうマチガっとるワケでもないぞい。じゃが、やってはならない無限ループとちがって、これはヒツヨウなループなのじゃ。

ちょっと実感がわかないけど、先を読むとわかってくるのかな。

まずドラムが、54~63行目か。
0054#. ’--- ト゛ラム
0055#. OLDB=B
0056#. B=BUTTON()
0057#. IF OLDB!=0 GOTO @DSKIP
0058#. IF B AND 1 THEN BEEP 52
0059#. IF B AND 2 THEN BEEP 53
0060#. IF B AND 4 THEN BEEP 62
0061#. IF B AND 8 THEN BEEP 25
0062#. IF B==64 GOTO @EXIT
0063#. @DSKIP
ワカらねえコトだらけで、ドコから手をつければいいのかもワカらねえぜ!

そういうことなら、まず56行目のB=BUTTON()がポイントだね。こう書くと、押されたボタンの情報が変数Bに入るようになっているんだ。

ボタンっていうと、DSiのAボタンみたいな?

DSiのボタンはひととおり全部だね。この表を見てごらん。
十字ボタン↑ | 1 | | Aボタン | 16 | | Lボタン | 256 |
十字ボタン↓ | 2 | Bボタン | 32 | Rボタン | 512 |
十字ボタン← | 4 | Xボタン | 64 | START | 1024 |
十字ボタン→ | 8 | Yボタン | 128 | SELECT | 2048 |
たとえば十字ボタンの上を押したときは、変数
Bには
1が入る。右ボタンなら
4だね。

ナンだってこんなハンパな数なんだ? 2の次は3でいいじゃねェか! ジュンバンに数字をふれば1~12ですむハナシだろ?

じゃあ十字ボタンの左上を押したときを考えてごらん。左は4、上は1だね。だから4+1で、変数には5が入ることになるんだ。

同時押しされた時を考えて、わざと数字に間をあけてるってコト?

フツウはまずないことだけど、上と下が同時に押されれば1+2で3、さらに左も押せば3+4で7だね。こういうふうにどんな組み合わせで何個ボタンを押しても、同じ数字が出てこないようにできてるんだよ。もともとはビット演算という考えかたが……

おっと、ヤヤコシそうなハナシはゴメンだぜ! とにかくシクミはワカッたぜ。タブンその後のIF文で変数Bにあわせた音を鳴らしたりしてんだろ?

たしかにほぼそのトオリじゃ。ワンパク君のいろいろすっとばしたリカイリョクには、野生のたくましさを感じるのう。

このままプログラムリストの先に進んでもいいけど、その前にさっきもちらっと出てきた「ループ」の考え方を知っておくほうがよさそうだね。

ナンだかフクザツなハナシのヨカンを感じるぜ。

いやいや、フクザツにならないための予習さ。ちょっと実行モードでNEWと打ってごらん。
NEW
OK

これがナンだってんだ?

あ、編集モードにすると……

プ、プログラムリストがゼンブ消えてるじゃねェか!

プログラムリストを消すのがNEW命令なのか……マチガって使ったらコワいね。

サンプルプログラムはまた
LOADしなおせばいいけど、自分のプログラムは消す前に
SAVEを忘れずにね!
じゃあループの話にもどって、このプログラムを打ってみよう。プログラムのイミは分かるかな?
0001#. INPUT”ニュウリョク”;A
0002#. PRINT”コタエハ”;A

またずいぶんシンプルな……。

オレをバカにしてんのか? ヨウするにINPUTで変数Aを入れさせて、それをPRINTしてるだけじゃねェか!
RUN
ニュウリョク?
1
コタエハ1
OK

その通り。じゃあ、BUTTON()命令を使って同じことをするにはどうすればいいかな?

1行ふえちまうが、こういうコトだな?
0001#. PRINT”ニュウリョク”
0002#. A=BUTTON()
0003#. PRINT”コタエハ”;A
RUN
ニュウリョク
コタエハ0
OK

あれ? なにもしないうちにプログラムが終わっちゃったよ。

どういうコトだチクショー! ボタンを押してねェんだからそりゃ「コタエハ0」だろうぜ!

そこだよ! INPUT命令とちがって、BUTTON()命令では「ボタンを押してない」ことも入力のウチなんだ。だからRUNしたとたんに終わっちゃうんだね。

じゃあどうすりゃボタンを押すまで待ってもらえるってんだ、ナットクできねえぞ!

何回でも
BUTTON()命令をやり直すってことだよね。こうすればいいのかな?
0001#. PRINT”ニュウリョク”
0002#. @LOOP
0003#. A=BUTTON()
0004#. PRINT”コタエハ”;A
0005#. GOTO @LOOP
……あ、これじゃダメだ……。

やっぱり。PRINT文もループの中に入ってるからどんどん書き続けちゃう……

でもなかなか悪くないよ。ボタン入力の結果をPRINTするのはデキてるからね。

タシカに、ボタンを押してるアイダは「コタエハ」のアトにちゃんと数字が入ってるな。

ダイジなのは、このタイプの命令では何回もくり返さないと思ったように動かないってコトさ。そのためにはGOTOでループを作らないとね。

さよう。こういうリアルタイムで入力を待つプログラムは、入力を待っているとアッというまに終わってしまうので、ループを作って入力を待ち続けるのがキホンじゃな。

ハハーン、そこで「メインループ」のできあがりってワケか!

ジッサイにはこれ以外にもすぐ通りすぎちゃう命令や、くり返さないとイミがないコトもプログラムにはたくさんあって、そういうのをまとめてひとつのループにするのが「メインループ」になるね。
まあ、プログラムをおぼえていくうちに自然に身につくハズさ。

今つくったプログラムは無限ループだったけど、本当にやりたかったように作るとどうなるの?

まだ見おぼえのない書き方もまじるけど、これでいいんじゃないかな。
0001#. PRINT”ニュウリョク”
0002#. @LOOP
0003#. A=BUTTON()
0004#. IF A!=0 THEN PRINT”コタエハ”;A:END
0005#. GOTO @LOOP
みんなも打ってみてね!

ウゥ……マジで見たことねェ書き方しやがって、ヨウシャのねえヤロウだぜ!

この行がモンダイなんだね。
0004#. IF A!=0 THEN PRINT”コタエハ”;A:END
今までの話から、これが「もしも変数
Aがゼロじゃなければ~する」ってIF文だとはなんとなく分かるんだけど……

気になるのは「変数!=数字」のカタチだよね。

「==」もビックリだったけど、「!=」だって初めて見るよ!

ほっほっほ。ソコはそうムズカシいモノでもないぞ。いわゆる「≠(等号否定)」と同じイミで、まあ右と左が「ちがう」というくらいのことじゃな。

まさか、またムカシのコンピューターに「≠」の字がなかったから「!=」と書いたとか、そんなことじゃねェだろうな……。

それでだいたい合っておるそうじゃ。

コ、コンピューターにタイするゲンソウがどんどんウシナわれていくぜェ……。

ほかにも「<」「>」を使うこともあるが、「≦」は「<=」、「≧」は「>=」と書くのじゃ。

そんなのばっかりか! なんかもう、コンカイはオレもいろいろダキョウしてる気がするぜェ……。
- インデント
- 行の先頭に空白スペースを入れることを「インデント」といいます。プログラムの動作には関係ありませんが、リストを見やすくするのに使います。FOR~NEXTの中に使うのがいちばん一般的ですね。
- NEW命令
- NEW
実行モードで使います。プログラムが消去されます。
- SYSBEEP変数
- SYSBEEP=FALSE
SYSBEEP=TRUE
FALSEならシステム音を消し、TRUEならシステム音が鳴るようになります。
- BEEP命令のピッチ
- BEEP (音色),(ピッチ)
ピッチ0が基本の音、-8192だと2オクターブ下、8192で2オクターブ上になります。おおざっぱに「ドレミで半音上げるには、ピッチを4096/12だけ増やす」とおぼえておくといいでしょう。
- BUTTON()命令
- 変数=BUTTON()
変数に押されたボタンの情報が入ります。
十字ボタン↑ | 1 | Aボタン | 16 | Lボタン | 256 |
十字ボタン↓ | 2 | Bボタン | 32 | Rボタン | 512 |
十字ボタン← | 4 | Xボタン | 64 | START | 1024 |
十字ボタン→ | 8 | Yボタン | 128 | SELECT | 2048 |
たとえば左上に押せば4+1で5が、何も押さなければ0が入ります。
- 比較演算子
- IF~THEN命令の条件文で使います。
変数AとBを比べる場合
A==B | AとBの内容が同じ |
A!=B | AとBの内容が違う |
A<B | AよりBが大きい |
A<=B | AよりBが大きいか、同じ |
A>B | AよりBが小さい |
A>=B | AよりBが小さいか、同じ |
IF (変数)!=(数) THEN (命令)
変数と数が一致しないときだけ命令を実行します。