注意して欲しいのは、この講座の目的です。
「初めてのプログラミング講座」とあるように、講座をやるのが初めてなわけです(笑)
まあそれは半分冗談で、この講座はプログラミングを始めたい方、特にゲームが作りたい方向けです。
最終的には何か極々簡単なゲームを作りたいと思います。
それこそパソコンがなくてもプログラミングがわかるようにするつもりです。
かくいう俺も、まだパソコンがないときは紙に書いてプログラムをしたもんです。
そういうことですので、感受性豊かな方は大歓迎します(笑)。
なお、本格的に勉強したい人は、ちゃんと本を買った方がいいと思いますよ。
俺はたいした腕もない素人なわけですし。
それか立ち読みでマスターして下さい(笑)。これも俺はやってますからできます。
ただ、そういう書店で売っている本では載っていないような「考え方」や「コツ」など(要するにTips)をたくさん紹介していきます。
この講座ではN88互換BASIC for Windows95(以下、互換BASICと呼んでいるものはこれのこと)というフリーソフトに基づいて説明します。
ダウンロードできる方は下のどれかからダウンロードしてください。サイズは2MBほどありますので、時間のあるときにどうぞ。
なお、上の方ほど推奨です。
・窓の社から自分で探す(推奨)
・ベクターのN88互換BASIC
for Windows95を紹介しているページ
・FTPでダウンロード
・HTTPでダウンロード(FTPでうまくいかない場合はこちらでどうぞ)
では、つまらないものですがどうぞ(笑)。長いからこのページを保存してオフラインで読もう。
次の簡単なプログラムを見てみましょう。 BASICというプログラム言語で書かれています。
互換BASICを持っている方は、真っ白なウィンドウに打ち込んでみてください。
わざわざ打ち込まなくてもコピー&ペーストすれば楽ですね。
10 CLS 20 PRINT "初めてのプログラミング講座" 30 END |
まず、これからの説明をしやすくするために、それぞれの行頭に書かれている数字10〜30を説明します。
これは行番号というもので、BASICのプログラムはこの番号順に実行されます。
行番号は10おきにしておきましょう。こうしておけば、後で行間にプログラムを追加したいときに15行などを追加すればいいですね。
もし1行ずつにしていると、間に挿入できないので面倒なことになります(もちろん挿入する方法はあります) 。
そして、行番号の後にプログラムの中身を書いていきます。
それでは順に何をしているのか追ってみましょう。
10 CLS
それまでの画面を消去して、新しくプログラムを実行する準備をしています。
20 PRINT "初めてのプログラミング講座"
”(ダブルクォーテーション)で囲まれた文字を画面に表示します。
30 END
プログラムを終了します。今回のプログラムではこの行は省略可能です。
では、以下に実行結果を示します。
初めてのプログラミング講座 Ok |
最後のOkは、互換BASICでは表示さません。
しかし、ほとんどのBASICでは表示されますので説明を加えておきます。
これはプログラムが終了したので勝手に表示されています。
PRINT文で表示する文字をいろいろと変えてみてモノにしてくださいな。
ゲームではスコアなどの表示に使えますね。
次は変数というものを覚えましょう。
変数を使うと、数字を代入したり文字を記憶させたりできます。
まずは数字を扱ってみましょう。
10 CLS 20 A=10 30 B=5 40 C=A+B 50 PRINT "合計は";C;"です" 60 END |
A=10とすれば、A には10が代入され、コンピュータが記憶してくれます。
B=5も同じですね。また、 C=A+Bのように計算式を書くこともできます。
この場合、CにはAとBを足した数が代入されるわけです。
変数は255文字までのアルファベットと数字の組み合わせならば自由に決められます。
ただし、最初の文字には数字は使えません。他にも細かい条件があるので、いろいろと試してみてください。
資料があればその条件も載せたいと思います。
また、何に使っているのかわかる名前を付けるようにしましょう。
合計ならGOUKEI、面積ならMENSEKI、X座標の1つ目ならX1、半径ならRなどですね。
そしてさらに、普段は英単語の組み合わせにしておきましょう。
攻撃力なら Strength だからSTR、防御力なら Defence だからDEF、ヒットポイントなら HP や HITPOINT のように。
好みの差があるので強制ではなく提案ですが、多少長い名前になっても、省略しないですむのならばわざわざ省略しないで全部を変数名にしましょう。
これも誰にでもわかりやすくするためです。
変数だけに限らず、誰にでも読みやすく、修正をしやすいプログラムを組むように心がけてください。
まあ、最初はあまり気にすることでもないので、適当にね(笑)
計算式に使える記号(一部) | |||
+ | 足し算 | \ | 9\4なら9÷4で2余り1なので、値は2 |
- | 引き算 | ( ) | 括弧 |
* | かけ算 | MOD | 余り |
/ | わり算 | ||
^ | べき乗 3^2なら3の二乗 |
50行にPRINT文の新しい形を使っていますね。
表示するのが変数の場合、PRINT AとすればAの中身を表示できます。
文字と一緒に表示したい場合は、文字と変数の間に ;(セミコロン) を入れてつなぎます。
(正確には意味が違って、「改行をしない」という指定です。何も指定しなければ改行されます。今までもそうだったはずです)
また、
PRINT "合計は";A+B;"です"
という風に、PRINT文の中で計算式にすることもできます。
それでは次に文字を代入する方法です。
10 CLS 20 A$="ゲームが作れるのは" 30 B$="いつの日か!?" 40 C$=A$+B$ 50 PRINT "この講座で";C$ 60 END |
文字を変数に代入する場合は、これまでの変数の後に $(ダラー) を付けます。
こうすることでコンピュータはこの変数が文字を表していると判断するわけですね。
40行のように、文字の変数にも + のみ使うことができますが、数字の時とは意味が違いますので注意。
40行は「A$の後にB$の中身を結合(連結)する」という意味になります。
50行は次のようにしても同じ結果を得られます。
50 PRINT "この講座で"+C$
ただ、内部でやっていることは少し違うので覚えておきましょう。
"この講座で"+C$
とした場合は、二つの文字列を結合してから、その結合した文字列を表示しています。
"この講座で";C$
とした場合は、前の文字列と後の文字列を別のものと考えて表示しています。
しかし、2回に分けて表示しているのかどうかは確認できませんでした。
▲▲▲▲▲▲ ここまでは 2000/05/01 に書いています ▲▲▲▲▲▲
さて、ここで考え方のちょっとしたコツを書きます。
PRINT 100
PRINT A
PRINT A+B
PRINT "あんまり重要じゃないんだけどね(苦笑)知っておくといいってことで"
PRINT "これは式がややこしいだけですね";100+A*2
上のコード(プログラムのこと)を数学で言う一般式のように書き直すと、
PRINT 式
となりますね。緑のところは、どんなに複雑な式でも同じように考えられるわけです。
要するに数値や文字、変数などでひとまとめにできる集合は式として考えましょう、ってことです。
そうしておけば、これから出てくるたくさんの命令に与えるデータがどんなものになっても、同じように考えることができますね。
また次に出てきたときに説明して補足したいと思います。
いくら何でもPRINT文だけじゃ説明するのが難しいので(苦笑)
▲▲▲▲▲▲ ここまでは 2000/05/02 に書いています ▲▲▲▲▲▲
少し詳しい話になりますが、どんな構造のプログラムでも、「順次」・「繰り返し」・「分岐」の組み合わせで書くことができます。
この3つの構造を中心にしてプログラムを組むことを構造化プログラミングといいます。
さて、この節の本題といきましょうか。次のプログラムを見てください。
10 CLS 20 PRINT "何回も同じことを書くのは面倒だ!" 30 PRINT "何回も同じことを書くのは面倒だ!" 40 PRINT "何回も同じことを書くのは面倒だ!" 50 PRINT "何回も同じことを書くのは面倒だ!" 60 PRINT "何回も同じことを書くのは面倒だ!" 70 END |
こんなのを例にするのもどうかと思いますが(苦笑)
20行から60行まで同じことしか書いていませんよね。
これはまだ5個なのでまだいいですが、100個とかになったら流石に面倒だけではすまなくなりますね。
こういうとき(かどうかは自信ないけど(苦笑))に使うのが繰り返しです。
文法 |
FOR 変数=初期値
TO 終了値 [STEP 増加値] ……(繰り返す命令群)…… NEXT [変数] |
動作 | 変数に初期値を代入し、NEXTまできたら変数に増加値を足す。ここで変数の値が終了値を超えていたらループを抜け、越えていなければFORの次の命令から繰り返す。 |
補足 | STEPの部分を省略すると、増加値は1になります。もちろんマイナスも指定できます。 |
[ ] で囲んだ部分は、省略できることを示しています。
この講座で文法を説明するときにはこういう表記をしますので、覚えておいてくださいね。
それでは実際にこの命令を使って、上のプログラムを書き直してみましょう。
10 CLS 20 FOR I=1 TO 5 30 PRINT "何回も同じことを書くのは面倒だ!" 40 NEXT I 50 END |
これで短くなってすっきりしましたね。同じような処理はこうやってまとめてしまいましょう。
この「回数分だけループさせる」のは、繰り返し処理の一番簡単な使い方だと思います。
他にもたくさんの使い方があるので、後でいくつか説明と一緒に載せておきます。
そして、ループの中の文はインデント(行を下げること)しておきましょう。
こうすることで格段に見やすくなります。何文字分でもいいですけど、あまり多くインデントすると余計に見にくくなってしまいますので注意。
さて、FOR〜NEXTにはまだ書いていない決まり事があります。
NEXTに書く変数はFORで使った変数と同じものでないといけません。
また、NEXTの方は省略できます。上の例のようにループが一重なら、書いても書かなくてもいいでしょう。
でも、二重三重になったら、どのFORとどのNEXTが組になっているのかわかりにくくなりますね。
例えば次のようなやつ。
10 CLS 20 FOR I=1 TO 9 30 PRINT "I=";I;"/" 40 FOR J=1 TO 9 50 PRINT I*J 60 NEXT 70 NEXT 80 END |
ぱっと見ただけじゃ、わかりにくいですよね。インデントもしていないから尚更です。
後で見ても読みやすいように書きましょうね。
そして、こういう多重ループを入れ子といいます。
FORで入れ子にするときには、同じ階層にNEXTを置かなければいけません。
つまり次のようなことはできません。
10 CLS 20 FOR I=1 TO 9 30 PRINT "I=";I;"/" 40 FOR J=1 TO 9 50 PRINT I*J 60 NEXT I 70 NEXT J 80 END |
階層が見づらいのでインデントしてみました。断然、見やすさが違いますね。
さて、どういう風にループしたらいいのかわかりませんよね。こういう交差しているものはエラーになります。
実験としてやってみるのがいいかと。
それではいくつかの使用例を挙げておきますので、各自でプログラムを読んでみてくださいね。
他人の書いたプログラムを読むのは、本当に大変です。俺もできることならやりたくありません。
でも、それしか道はありませんから、根気よくやってみてください。頑張れ〜!
▲▲▲▲▲▲ ここまでは 2000/05/04 に書いています ▲▲▲▲▲▲
10 CLS 20 PRINT "SCORE LANKING TOP 10" 30 FOR I=1 TO 10 40 PRINT "LANK ";I;":";10000-I*350 50 NEXT I 60 END |
点数は適当ですが、スコアランキングの表示をしています。書式が統一されていますから、FORを使った方が綺麗です。
▲▲▲▲▲▲ ここまでは 2000/10/09 に書いています ▲▲▲▲▲▲
さて、ゲームがゲームであるために必要な最低条件がわかりますか?
「プレイヤーからの入力を受けて、判定した結果を画面に表示する。」
これだけあればゲームと呼べるものを作ることができますね。
それでは次に分岐をマスターしましょう。ここは覚えることが多いので頑張ってくださいね。
では次の例を見てください。
10 CLS 20 FOR I=1 TO 10 30 IF I=5 THEN PRINT I 40 NEXT I 50 END |
30行に IF 文という新しい命令が出てきましたね。
このプログラムでは何をやっているのか次に説明します。
「変数 I を1から10まで増加させていって(FOR〜NEXT)、I
が5になったときに(IF)
I の中身を表示する(PRINT)」
それでは文法を簡略して示しておきます。
文法 |
IF 条件式 THEN 命令A [ELSE 命令B] |
動作 | 条件式が成り立つ場合は命令Aを実行し、成り立たなかった場合は命令Bを実行する。 |
補足 | 今のところなし、というか秘密(笑) |
また、 条件式には次の記号を使えます。いろいろ試してみましょう。
条件式に使える記号一覧 | |||
= | 両辺が等しい | ||
<> | 両辺が等しくない | ||
< | 左辺が右辺未満 | ||
> | 右辺が左辺未満 | ||
<= |
左辺が右辺以下 | =< | <=と同じ |
>= | 左辺が右辺以上 | => | >=と同じ |
さて、ここまで読んで、こう思った人がいるかもしれません。
「IF文の後には一つしか命令が書けないんじゃ不便だ!」ってね。
ここまであえて伏せてきましたが、実は一行に二つ以上の命令を書くこともできます。
10 CLS 20 HANKEI=100:PAI=3.1415926535 30 MENSEKI=HANKEI^2*PAI 40 PRINT "半径";HANKEI;"の円の面積は";MENSEKI 50 END |
読みにくいし、あまりいい例じゃないです(苦笑)
20行にあるように :(コロン) を命令の間に挟むと一行に二つ以上書くことができます。
セミコロンと間違えやすいので注意しましょう。見た目もキー配列も間違えやすくなっています。
(もちろん、コロンを使ってIF文の中にIF文を書くこともできます。あまり使わない方がいいですけどね。その辺は臨機応変にカバーしましょう。
)
それではELSEを使った例を挙げておきますね。
10 CLS 20 AGE=20 30 PRINT "歳とお酒の関係?" 40 IF AGE<20 THEN PRINT "お酒は二十歳から!" 50 IF AGE>50 THEN PRINT "歳だし程々に" ELSE PRINT "よし、ガンガン飲め" 60 PRINT "たばこは歳に関係なく止めといた方がいいですよん" 70 PRINT "体を悪くするし金かかりすぎ〜" 80 END |
ああ・・・本当に意味のないプログラムを作ってしまった・・・(苦笑)
内容的にも利用価値的にも意味のないことのオンパレードだわ(笑)
こういうところです、ここは。
まだまだ分岐の講座は続きます。まだこれまでの説明だけでは表現しにくい条件式の形があります。
それは AND(かつ) と OR(または)
です。
例えば、「Xが10以上かつYが20以下」とか「Aが5またはBが3」のような形ですね。
条件式におけるANDとOR | |
条件式1 AND 条件式2 | 条件式1と条件式2の両方が成り立つ場合にTHEN後の命令を実行 |
条件式1 OR 条件式2 | 条件式1と条件式2のどちらか一方でも成り立つ場合にTHEN後の命令を実行 |
さてここで、ANDとORを考えた場合に判断する優先順位というものが出てきます。
例えば 10+5*2 という計算式の場合は5×2を先に計算しますよね。このような関係のことです。
IF 条件式1 AND 条件式2 OR 条件式3 THEN 〜
この場合なら「条件式1と条件式2が両方とも成り立つ」または「条件式3が成り立つ」ならば〜、となります。
これをORの方を優先にしたい場合は次のように括弧でくくります。
IF 条件式1 AND (条件式2 OR 条件式3) THEN 〜
こうすると「条件式1が成り立つ」かつ「条件式2か条件式3のどちらか一方でも成り立つ」ならば〜、となるわけですね。
これでかなり複雑な条件式も表現できるようになりました。
次にANDとORを利用した例を挙げておきますね。
10 CLS 20 FOR X=-10 TO 10 30 Y=X^2-10 40 IF Y<50 AND X<5 OR Y<=0 AND X>=5 THEN PRINT "(X,Y)=(";X;",";Y;")" 50 NEXT 60 END |
上のプログラムは何をしているのかを書いておきましょう。
「y=x^2-10 という方程式について、x座標が−10から10までの範囲内で 「y<50 かつ x<5」 または 「y<=0 かつ x>=5」 が成り立つ整数の座標を表示する」
こんなところでしょうか。やっぱりあまり意味がない(苦笑)
また、文字も比較することができます。
10 CLS 20 A$="同じ文字列" 30 B$="同じ文字列" 40 C$="異なる文字列" 50 IF A$=B$ THEN PRINT "A$とB$は同じだぞ" ELSE PRINT "A$とB$は違うぞ" 60 IF A$=C$ THEN PRINT "A$とC$は同じだね" ELSE PRINT "A$とC$は違うね" 70 IF B$=C$ THEN PRINT "B$とC$は同じだな" ELSE PRINT "B$とC$は違うな" 80 END |
20行から40行の間で変数に文字列を設定していますが、これをこのままで実行したなら結果は次のようになります。
A$とB$は同じだぞ A$とC$は違うね B$とC$は違うな Ok |
どうにも回りくどい書き方になっているようですいません(汗)
でも、IF文は何かと使う命令なので、できるだけ省略せずに書いたつもりです。
サンプルもたくさん書いたので、どういう使い方ができるのか試しやすいと思います。
環境がある人は是非とも自分で試してみてくださいね。
何度も同じ事を書きますが、それが一番の近道ですから。
▲▲▲▲▲▲ ここまでは 2000/05/14 に書いています ▲▲▲▲▲▲
【3】と【4】で説明した2つの命令の他にも、同じようなことができる命令があります。
この節では、【3】【4】の補足をします。
まずは繰り返しの命令。
文法 |
WHILE 条件式 ……(繰り返す命令群)…… WEND |
動作 | 条件式が成り立つ間だけ、WHILE〜WENDとの間にある命令群を繰り返す。 |
補足 | なし |
条件式にはIF文と同じ形のものが使えます。
それにより、FOR〜NEXT文よりも複雑な条件でループすることができますね。
また、NEXTのように後ろに変数名を書く必要もありません。
それではサンプルをどうぞ。
10 CLS 20 A=2:B=0 30 WHILE A<100 40 A=A^2 50 B=B+1 60 WEND 70 PRINT "2を";B;"回2乗して初めて100を越え、";A;"になる。" 80 EMD |
次に分岐の命令ですが、本来は分岐に使うものではありません。
どこかの行へ処理順を移動したいときに使います。
文法 |
GOTO 行番号 |
動作 | 指定した行番号へ処理を移ります。 |
補足 | なし |
ここで注意。
構造化プログラミングを心がけている場合は、GOTO文はできるだけ使わないようにしましょう。
急に処理順が変わってしまうと、プログラムの読みやすさに大きな穴が開いてしまいます。
しかし、実際には、使わなければどうしようもなくなったり、使った方が簡潔に表現できることもあります。
前者の場合は、あなたの組み方が悪いんです。
絶対に「順次」・「繰り返し」・「分岐」の3つだけで書くことができるので、もう一度考えてみましょう。
後者の場合は、こだわらないのであれば使ってもいいんじゃないでしょうか?
俺はこういうときには、ためらわずに使っていたと思います。
次のサンプルは、簡潔に表現できるのでGOTOを使っています。
10 CLS 20 A=0 30 IF A<9 THEN PRINT "0から9の間です":GOTO 90 40 IF A<19 THEN PRINT "10から19の間です":GOTO 90 50 IF A<29 THEN PRINT "20から29の間です":GOTO 90 60 IF A<39 THEN PRINT "30から39の間です":GOTO 90 70 IF A<49 THEN PRINT "40から49の間です" 80 IF A=50 THEN PRINT "50になったので終了":GOTO 110 90 A=A+1 100 GOTO 30 110 END |
思ったよりややこしくなってしまいました(爆) ダメじゃん。
GOTOを使わない書き方も載せておきましょうか。
10 CLS 20 A=0 30 WHILE A<=9 40 PRINT "0から9の間です" 50 A=A+1 60 WEND 70 WHILE A<=19 80 PRINT "10から19の間です" 90 A=A+1 100 WEND 110 WHILE A<=29 120 PRINT "20から29の間です" 130 A=A+1 140 WEND 150 WHILE A<=39 160 PRINT "30から39の間です" 170 A=A+1 180 WEND 190 WHILE A<=49 200 PRINT "40から49の間です" 210 A=A+1 220 WEND 320 PRINT "50になったので終了" 330 END |
構造化プログラミングに則って組むと、こういう感じになるのではないでしょうか?
結構、縦に長くなってしまうものですね。
さて、それでは見比べてみましょうか。
上に書いた方は短いし、作るときには考えやすい割に、処理を追ってみると、とんでもなくややこしいことがわかると思います。
その点、下の方はだらだらと書いているように見えますが、処理を追うのがとても楽ですね。
でも、上に書いたサンプルの方がBASICらしいと感じるのは、俺が間違っているのでしょうか?(苦笑)
普段からああいうプログラムを組んでいたってことなのかなぁ。それって何か問題があるような気が。うーむ。
GOTOが出てきたので、ここでIF文のもう1つの文法を説明します。
文法 |
IF 条件式 THEN 行番号A
[ELSE 行番号B] |
動作 | 条件式が成り立つ場合は行番号Aに移動し、成り立たなかった場合は行番号Bに移動する。 |
補足 | この文法を、前の文法に追加する。 |
これはどういうことかというと、
IF 条件式 THEN GOTO 行番号
としないで、
IF 条件式 THEN 行番号
とでき、少しだけ省略できるわけです。豆知識というか何というか。
ただし、
IF 条件式 THEN 命令群:行番号
IF 条件式 GOTO 命令群
という形にはできませんので、注意してくださいね。
◆ちょっとした愚痴◆
はぁー、ようやくまともなプログラムが書けそうになってきたなぁ。
最初の方は命令が少ないから、どうしようかと思ったよ、ホント(笑)
ではでは、命令も揃ってきたことですし、ガンガン進んで行きましょう!
▲▲▲▲▲▲ ここまでは 2000/06/11 に書いています ▲▲▲▲▲▲
それでは次にユーザからの入力です。
これがないとプログラムの利用価値は大幅にダウンしてしまいます。
その時だけに使う計算程度なら大して問題はないでしょうけど、普通はパソコン(プログラム)は入力を求めてくる物ですよね。
次の、以前に書いたプログラムを見てください。
10 CLS 20 AGE=20 30 PRINT "歳とお酒の関係?" 40 IF AGE<20 THEN PRINT "お酒は二十歳から!" 50 IF AGE>50 THEN PRINT "歳だし程々に" ELSE PRINT "よし、ガンガン飲め" 60 PRINT "たばこは歳に関係なく止めといた方がいいですよん" 70 PRINT "体を悪くするし金かかりすぎ〜" 80 END |
このプログラムを載せた後に、「本当に意味のないプログラムを作ってしまった」と書きましたが、それはユーザの入力がないからです。
20行に、つまりプログラムの中に直接に年齢を書いていますよね。
プログラムの中にこういう情報を載せてしまったら、変更したくなる度にプログラムを呼び出して書き換えなくてはいけません。
これでは、たくさんの人数分をこなすときに困ってしまいますよね。
そこで、プログラムを実行しているときにユーザの入力を受け取る命令があります。
文法 |
INPUT ["表示文字列";]変数[,変数][,変数]... |
動作 | この命令が呼び出されると、そこで処理を一時停止して表示文字列と?を表示する。そして、ユーザが入力した数値や文字列を変数に代入する。 |
補足 |
["表示文字列";]を省略して何も表示しないこともできる。複数の変数を入力したいときは、コンマで区切って羅列してEnterキー。 |
今後、文法の説明での ... は以後繰り返しという意味です。
これからも出てきますので、覚えておいてくださいね。
それでは、INPUT命令を使って上のプログラムを書き換えてみます。
10 CLS 20 INPUT "あなたの年齢を入力してください";AGE 30 PRINT "歳とお酒の関係?" 40 IF AGE<20 THEN PRINT "お酒は二十歳から!" 50 IF AGE>50 THEN PRINT "歳だし程々に" ELSE PRINT "よし、ガンガン飲め" 60 PRINT "たばこは歳に関係なく止めといた方がいいですよん" 70 PRINT "体を悪くするし金かかりすぎ〜" 80 END |
20行だけを変更してみました。これで実行する度にユーザーに入力を求めてくるので、より利用価値が上がりましたね。
まあ、元々利用価値なんてゼロみたいなもんなのですが(笑)
文法の説明にも書きましたが、実行中の入力の仕方は次のようにします。例えば、
INPUT X,Y
という形の場合は
10,20[Enter]
と入力します。もちろんEnterはそう書くのではなく、Enterキーを打つんですよ(笑)
求められているだけの数分の値を羅列して入力しないとエラーが出ます。だから、複数の場合は表示文字列には入力の仕方を書くべきですね。
また、文字列の入力も可能です。例えば、
INPUT STR$,DATA
のように文字列単体でも、数値との複合でも大丈夫です。ただし、どんな形になっても間にはコンマを忘れないように。
(この命令は処理を一時停止してしまうので、実際のゲームで移動などに使うことができません。
一時停止しない方は命令とはまた少し違う関数というものを使うので、第二章で説明します)
さて、これで「入力」と「判定」と「表示」の全てが揃いました。
次の【7】では、今までに説明した命令を使って簡単なゲームを作ってみます。
▲▲▲▲▲▲ ここまでは 2000/06/18 に書いています ▲▲▲▲▲▲
第一章もとうとう締めのところまできました。
最後のこの節では、簡単なゲームを作って実際の命令の使い方を学びましょう。
10 CLS 20 HIT=INT(RND(1)*1001) 30 INPUT "0〜1000までの数字を入力してください";NUMBER 40 IF NUMBER>HIT THEN PRINT "もっと小さいよ" 50 IF NUMBER<HIT THEN PRINT "もっと大きいよ" 60 IF NUMBER=HIT THEN PRINT "当たり!":END 70 GOTO 30 |
構造化プログラミング版も書いてみました。やっぱりすっきりしてるような気がします。
10 CLS : NUMBER=-1 20 HIT=INT(RND(1)*1001) 30 WHILE NUMBER<>HIT 40 INPUT "0〜1000までの数字を入力してください";NUMBER 50 IF NUMBER>HIT THEN PRINT "もっと小さいよ" 60 IF NUMBER<HIT THEN PRINT "もっと大きいよ" 70 WEND 80 PRINT "当たり!" 90 END |
ここで、上をリスト1、下をリスト2とします。
▲▲▲▲▲▲ ここまでは 2000/06/18 に書いています ▲▲▲▲▲▲
さて、ここで初めて関数というものが出てきました。命令とは少し違うものです。では、何が違うのでしょうか。
リスト1、2のどちらでもいいので、20行を見てください。
HIT=INT(RND(1)*1001)
このINT関数とRND関数の2つについて説明します。まずはINT関数から。
文法 |
INT(数値) |
動作 | 数値を超えない、最大の整数を返す。 |
補足 |
単純に小数点以下を切り捨ててはいないことに注意。INT(1.8)は1だけど、INT(-1.8)は-2です。ちなみに単純に切り捨てる関数はFIX関数です。(本当はこのプログラムではFIXにした方がいいんですが……) |
関数は命令と違い、何かの値を返します。値を返すとはどういうことでしょうか。
A=INT(2.2)^2
PRINT INT(3.14)*A
と、こういうことができるわけです。関数は式の中で数値や文字列と同じように扱えるんですね。
ではもう一つのRND関数の文法を。
文法 |
RND(数値) |
動作 | 0以上1未満の乱数を返す。(0≦X<1) 次のように数値によって異なる動作をする。 −:乱数列を初期化した上で、最初の乱数を返す。 0:1回前と同じ数を返す。 +:次の乱数を返す。 |
補足 | 詳しい使用方法などはうろ覚えリファレンスマニュアルにて記載。 |
簡単に語句の説明をしておきます。
乱数とは、数値の順序や大きさに全く関連がない数のことです。数学の教科書の一番最後に乱数表が載っているものもあります。
乱数列とは、決められた「乱数の順序」のことです。これを初期化するとまた最初から同じ乱数が返ってくるようになりますから、実際にはどの乱数列を使うのかもランダムに決めるようにします。
では、ここで20行を見直してみましょう。
HIT=INT(RND(1)*1001)
もう見ただけで何をやっているのかわかりますよね?
RND(1)*1001
の部分で0以上1000以下の乱数を受け取り、
INT(RND(1)*1001)
とすることで、受け取った数値を整数に変換して、後は変数HITに代入してるんですね。
それでは全体の動きを見てみましょう。ごくごく簡単な数当てゲームになっています。
1.当たりの数字を0以上1000以下の乱数で決める。
2.ユーザーに0以上1000以下の数字を入力してもらう。
3.入力された数字が、当たりより大きいのか小さいのかを表示する。
4. もし当たっていたなら「当たり!」と表示して終わり、外れなら2.の入力へ戻る。
こんな感じですね。どちらのリストでも流れに大きな違いはありません。
ただし、リスト2の10行だけに NUMBER=-1 と追加してありますね。これはなぜでしょうか。
まずリスト1の処理を追ってみます。
リスト1は、ユーザーの入力があってから(30行)、当たりかどうかを判定(60行)していますね。
しかし、リスト2はどうでしょうか。30行と40行を見てください。
30 WHILE NUMBER<>HIT
40 INPUT "0〜1000までの数字を入力してください";NUMBER
ユーザーが入力する前に、当たりかどうかを判定してしまっていますね。これが原因です。
もしも最初から2つの値が同じだった場合、ユーザーが一度も入力することなくプログラムは終わってしまいます。
デバッグの練習も兼ねて、どういうときに同じ値になってしまうか考えてみましょう。
BASICの仕様として、実行する度に勝手に変数の中身が 0 に初期化されます。
(これは数値の変数のみで、文字の変数は違うもので初期化されます。要は何もなくなるんですが)
つまり乱数の値が 0 だった場合に、バグが発生してしまいます。
このバグをなくすために、最初に NUMBER=-1 としておいて、判定の前にユーザーが入力したように見せかけているんですね。
初期化する値を -1 にしている理由は、ユーザーが入力するはずの0以上1000以下の条件から外れているからで、この範囲外だったら何でも大丈夫です。
ところが、もしこの値を「見せかけるんだったら、あり得る数字の方がいいよなー」と思って、0以上1000以下の数値にしてしまうと、これもバグになってしまいます。
なぜなら、乱数の値が初期化した値と同じだったら、終了してしまうからですね。
さてさて、いきなりデバッグとかバグって言葉が出てきて、「なんだそりゃー」という方がいるかもしれないので補足。
バグというのは、プログラムの中に潜んでいる虫(bug)です。
タンスの中に大事にしまっておいた服に開いた虫食い穴のように、プログラムに開いた穴、つまりは間違いのこと。
これがただの打ち間違い(スペルミス)だったら見つけるのは簡単な方ですが、今回のような論理的なバグのときには大変です。
しかも、自分の中で一度完成させてしまっているので、自分で見つけるのはさらに困難になります。
このバグを取り除くことを、デバッグと呼びます。
そこのあなた、プログラムを覚えるのは大変ですよね?
でも、一番大変なのははっきり言ってバグ退治です。
これは慣れしかないので、鍛錬を積むしかありません。
「バグができないように組めばいいんでしょ」と思ったあなたー。絶対無理ですから、先に諦めましょう(笑)
一生の内に一度もバグを出したことがないっていう人は、一度しか組んだことがない人です。
もしくは、プログラムをやったことがない人、か。
でも、バグを出しにくい組み方というのはあります。
それが今まで所々で言ってきた、「変数名はわかりやすく」だったり、「ループの中はインデント」だったり、「構造化プログラミング」だったり、まだまだこれから説明することだったりするわけです。
一応、先のことを考えずに無駄にガリガリ説明してるわけじゃないんよー(笑)。 ちゃんと複線張っていってるんだから。
(たまに失敗したりもしてるけど……(爆))
ではでは、「第一章 BASICの基本」はこれでお終いです。
とりあえず、ここまで読んでくださった方へ。
ありがとう! そして、頑張れ!
そして、意見とか間違いとかを教えてくれたあなたへ。
ありがとう! これからもよろしく!(笑)
ではでは、意欲あるあなたの上達を願っています。
▲▲▲▲▲▲ ここまでは 2000/06/24 に書いています ▲▲▲▲▲▲