サンプルプログラム3(前)

プログラマーからひとこと

配列変数のことはもう大丈夫ですか?
もはやこの章ではあたりまえのように配列がFOR文といっしょに使われています。
一歩ひきかえすのもいいかもしれません。何度も読んだり、自分で打ってみて、ついでにちょっと書き換えたりしてみて、自分のものになることもあるものです。

心配のしすぎだったでしょうか。

前回はかなりプログラムっぽいことをやったので、今回はちょっと方向をかえてリアルタイムのキー入力や、十字ボタンの操作なんてやってみます。
「リアルタイム」というのは、まあいろいろ意味はあるんですが、いまは「押したらすぐ動く」みたいなものと思っていいんじゃないでしょうか。
けっこうゲームっぽいですね。

そういう意味ではけっこう大事なことをまなぶサンプルかもしれません。
けっこう長くなっているので、今回と次回の2つにわけて見ていきましょう。

あと、BEEP命令で音を出すヒントもちょっとついてますよ。

SYSBEEP変数

博士
サンプルプログラム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

博士
インテリ君は上げてから落とすのがウマいのう……。


BEEP命令のピッチ

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=20なんかロックでいいんじゃねェか?

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


BUTTON()命令

インテリ
プログラムリストは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()がポイントだね。こう書くと、押されたボタンの情報が変数に入るようになっているんだ。

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

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

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

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

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

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

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

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


メインループ

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

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

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

NEW
OK
ワンパク
これがナンだってんだ?

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

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

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

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

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

ワンパク
オレをバカにしてんのか? ヨウするにINPUTで変数を入れさせて、それをPRINTしてるだけじゃねェか!

RUN
ニュウリョク?

コタエハ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
今までの話から、これが「もしも変数がゼロじゃなければ~する」ってIF文だとはなんとなく分かるんだけど……

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

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

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

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

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

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

博士
ほかにも「小なり」「大なり」を使うこともあるが、「小なりイコール」は「<=」、「大なりイコール」は「>=」と書くのじゃ。

ワンパク
そんなのばっかりか! なんかもう、コンカイはオレもいろいろダキョウしてる気がするぜェ……。


今回のまとめ

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