2計算で遊ぶ
前回に引き続き、「SmileBASIC」を使ったプログラムの作り方について紹介します。
計算式の書き方
今回はSmileBASICで「計算」を行ってみたいと思います。
計算とは何か? を知るために、まずは第1回目の内容を振り返ってみましょう。
OK
PRINT 1+1
2
OK
│
これは第1回目に登場した「1+1」を計算する命令です。PRINT命令をダイレクトモードで実行していました。
この数式にある「+」の記号を算術演算子といいます。算術演算子には次のような種類があります。
+ | 足し算 |
---|---|
- | 引き算 |
* | かけ算(「*」はアスタリクスと呼びます) |
/ | 割り算(「/」はスラッシュと呼びます) |
MOD | 割り算の余り |
DIV | 割り算で少数を切り捨て |
これらの記号を組み合わせると、複雑な計算を行うことができます。たとえば、「PRINT 2*2*2*2」と実行すると2の4乗を表示することができます。
計算の処理は足し算よりもかけ算が優先されます。たとえば、「PRINT 2+2*2」を実行すると「8」ではなくて、「6」と表示されます。どれが先に処理されるか指定したい場合にはカッコを使って記述するといいでしょう。「PRINT 2+(2*2)」と書けば、読み間違うこともありません。
変数の使い方
計算を行う際に無くてはならない存在が「変数」です。変数とは様々な情報を別の名前に置き換えたもののことです。変数に情報を格納することを「代入」といいます。
変数のイメージを図で表してみました。ここでは変数を「箱」として考えています。代入とは箱の中に情報を格納することです。
変数の名前を「変数名」といいます。変数名として使えるのは英数字または「_(アンダーバー)」です。変数名は数字から始めることができません。このため、「1A」のような変数名の場合、Syntax Errorになってしまいます。
「PRINT」のような命令文などを変数名にすることもできません。これらのルールさえ守れば、自由に変数名を付けることができます。
これが変数を使ったプログラムの例です。
まず、1行目ではACLS命令を使って画面を初期化します。
2~3行目では、変数Aと変数Bに1を代入しています。
4行目では「A+B」を計算して、その結果を変数Cに代入しています。
「A+B」は「変数Aと変数Bを足せ」という意味です。「=(イコール)」は「代入しなさい」という意味です。
5行目ではPRINT命令を使って変数Cの中身を表示します。
2
OK
│
プログラムを実行した結果がこちらです。画面に「2」と表示されました。
プログラムはどのように処理を行っているのでしょうか? それを図で表してみました。
変数Aと変数Bには1が代入され、AとBを足した結果が変数Cに代入されます。
以上で変数の働きが理解できたと思います。
先ほどのプログラムをこのように改造してみました。
「INPUT命令」を使うと、キーボードから変数に値を代入することができます。
INPUT命令の書式は次のとおりです。
INPUT “
表示内容”;
変数名
A? 1
B? 1
A+B=2
OK
│
プログラムを実行すると、「?」マークが表示されます。
ここで、キーボードを使って数値を入力します。入力後にENTERキーをタッチすると決定です。
変数Aと変数Bに入力すると、計算結果が表示されます。
変数の型について
SmileBASICには3種類の変数の形式があります。この形式のことを「型」といいます。
変数の型には次の3種類があります。
実数型(#) | 少数を含んだ数値を格納することができる形式です。数値1つあたりに64ビットのメモリを消費します。 |
---|---|
整数型(%) | 整数のみを格納することができる形式です。少数は格納できません。数値1つあたりに32ビットのメモリを消費します。 |
文字列型($) | 文字列を格納することができる形式です。 |
変数名の語尾に記号を付けることで変数の型を指定することができます。語尾に記号が付いていない場合には、デフォルトで実数型が選択されます。
文字列型の変数を使ったプログラムです。変数名の語尾に「$」の記号が付いています。
A? 1
B? 1
A+B=11
OK
│
プログラムの実行結果、その1です。ここでは例として変数A$と変数B$に「1」を代入しています。その結果、「11」が表示されました。
「1+1」が「2」とならずに「11」という答えが出ました。これは変数の中身が数値ではなく、文字列として扱われているからです。
A? HELLO
B? WORLD
A+B=HELLOWORLD
OK
│
プログラムの実行結果、その2です。ここでは、A$に「HELLO」を代入して、B$に「WORLD」を代入しました。その結果、「HELLOWORLD」と表示されました。文字列の足し算が正常に行われています。
処理を分岐させる
続いて、処理の分岐について紹介します。処理を分岐させるには「IF~THEN~」という文を使います。「IF~THEN~」を日本語にすると「もし~ならば~」です。
IF文を使ったプログラムを作ってみました。IF文の書式は次のとおりです。
IF
式 THEN
処理
この「式」が0以外ならばTHEN以降の処理が実行されます。
ここでは「A<B」という比較を行っています。SmileBASICでは比較した結果が真の場合、その内容が1になるという特性があります。たとえば「PRINT 1<2」を実行すると「1」と表示されます。「PRINT 1>2」を実行すると「0」と表示されます。
「<」や「>」などの記号を「比較演算子」と呼びます。比較演算子の利用例は次のとおりです。
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文です。IF文を使うと処理を分岐させることができます。
A? 1
B? 2
A<B
OK
│
プログラムの実行結果です。ここでは例として変数Aに1を代入して、変数Bに2を代入しました。
結果、「A<B」と表示されました。変数の値を比較する処理が正常に機能しています。
なお、IF文には他にもたくさんの機能があります。「ELSE」や「ENDIF」を使うことで、さらに複雑な処理を行うことができます。その詳細については次回以降に紹介します。
コンソール画面を使いこなす
今まで紹介してきたプログラムではPRINT文を使って文字を表示してきました。この文字を表示するための画面のことを「コンソール画面」といいます。
上画面におけるコンソール画面の仕様を図で表すと、こうなります。
コンソール画面の大きさは50×30文字です。文字を表示する場所は「X座標」と「Y座標」で指定することができます。一番左上の座標が「0,0」で、一番右下の座標が「49,29」となります。
コンソール画面で指定した場所に文字を表示させたい場合には「LOCATE」という命令を使います。
LOCATE命令の書式は次のとおりです。
LOCATE X
座標,Y
座標
もし、立体視を表現する場合は3番目の引数に「Z座標」を指定します。
LOCATE X
座標,Y
座標,Z
座標
LOCATE命令を使ったプログラムを作ってみました。4行目にはLOCATE命令があります。座標は(A,A)としました。
このプログラムでは繰り返し処理を行っています。
3行目にある「@L」は「ラベル」といって、プログラムの見出しです。ちなみに、ラベル名は「@」で始まり、「@」のあとは英数字、もしくは「_(アンダーバー)」を使うという決まりがあります。そのルールさえ守れば、自由に名前を付けることができます。
7行目のIF文で処理を繰り返す回数を比較しています。THENのあとにある「GOTO」命令を使うことによって、処理する行を移りかえることができます。
プログラムの処理の流れをフローチャートにしてみました。
下にある条件分岐によって、処理が繰り返されます。このような繰り返し処理のことを「ループ」と呼びます。
プログラムの実行結果はこのとおりです。
画面に0~19の数値が表示されました。数値がななめに並んでいますが、これはLOCATE命令が正しく機能しているためです。
さらにプログラムを改造してみましょう。
先ほどは処理を20回繰り返していましたが、このプログラムは256回繰り返します。
4~5行目の処理でX座標とY座標を計算しています。
このプログラムでは2つほど初登場の関数があります。5行目にある「FLOOR」関数は少数を切り捨てて整数を求める関数です。7行目にある「CHR$」関数はキャラクターコードに対応する文字を求める関数です。キャラクターコードというのは文字に割り振られている番号のことです。
プログラムを実行した結果がこちらです。画面に16×16文字=256個の文字が表示されました。
一番左上(0,0)の座標にキャラクターコード0番の文字が表示されます。
一番右下(15,15)の座標にキャラクターコード255番の文字が表示されます。
この結果を見ると、番号と文字の関係がわかります。
続いてプログラムを改造してみましょう。
7行目の「CHR$(A)」という部分を「CHR$(A+57856)」に書き換えます。
結果はいったいどう変わるのでしょうか?
プログラムの実行結果がこちらです。
今度は57856~58111番のキャラクターが表示されるようになりました。ヘビやUFOなどもあります。文字以外にも図形も含まれていることがわかります。
これらをうまく活用すると面白いゲームが作れるのではないでしょうか。
ボールを反射させてみる
今まで紹介してきた技術を組み合わせて、画面上で文字が動き回るプログラムを作ってみましょう。
こちらが完成したプログラムです。
2行目では変数X、変数Yの初期値を設定しています。この変数には文字を表示する座標を格納します。
3行目では変数X1、変数Y1の初期値を設定しています。この変数には文字の移動量を格納します。
プログラム内にある「:(コロン)」は処理を区切るための記号です。「:」を使うと、プログラムの行数を少なくすることができます。ただし、使いすぎるとプログラムが読みにくくなってしまいます。
10行目にある「CHR$(58081)」は記号の「●」のことです。この記号をボールに見立てています。キーボードで記号を入力しにくいという場合を考えて、CHR$を使っています。
プログラムを実行すると、このとおりです。
ボールは斜めに移動します。ボールが画面外に出ようとするとバウンドします。ボールの移動した軌跡が残ります。
これで「計算」というものを視覚的に表現できたと思います。
ビット演算
続いて、ビット演算を行ってみましょう。ビット演算とは2進数を使った計算のことです。
2進数というのは「0」か「1」だけで表現する数のことです。普段の私たちの生活では10進数が使われています。10進数と2進数の例を表すと、次のようになります。
10進数 | 2進数 |
0 | &B0 |
1 | &B1 |
2 | &B10 |
: : |
: : |
15 | &B1111 |
16 | &B10000 |
2進数は10進数に比べて桁数がどんどん増えていきます。ちなみに「&B」というのは数値が2進数であるという意味のプログラムの書き方です。
2進数を覚えていればプログラミングに役立ちます。丸暗記する必要はなく、SmileBASICには「BIN$」という便利な関数があります。書式はBIN$(数値)です。たとえば、16を2進数に変換して表示したい場合には次の命令を実行します。
PRINT BIN$(16)
そして、2進数で計算を行う場合には「ビット演算子」という記号を使います。ビット演算子には次のようなものがあります。
OR | 論理和 |
---|---|
AND | 論理積 |
XOR | 排他的論理和 |
NOT | 否定 |
<< | 算術シフト左 |
>> | 算術シフト右 |
《OR処理の例》
式 | 計算結果 |
0 OR 0 | 0 |
1 OR 0 | 1 |
0 OR 1 | 1 |
1 OR 1 | 1 |
《AND処理の例》
式 | 計算結果 |
0 AND 0 | 0 |
1 AND 0 | 0 |
0 AND 1 | 0 |
1 AND 1 | 1 |
《XOR処理の例》
式 | 計算結果 |
0 XOR 0 | 0 |
1 XOR 0 | 1 |
0 XOR 1 | 1 |
1 XOR 1 | 0 |
《NOT処理の例》
式 | 計算結果 |
NOT 0 | -1 |
NOT 1 | -2 |
《 << 処理の例》
式 | 計算結果 |
1 << 0 | 1 |
1 << 1 | 2 |
1 << 2 | 4 |
1 << 3 | 8 |
《 >> 処理の例》
式 | 計算結果 |
8 >> 0 | 8 |
8 >> 1 | 4 |
8 >> 2 | 2 |
8 >> 3 | 1 |
いかがでしょうか?
難しすぎて面食らってしまう人もいるかもしれません。
特に難しいのはNOT処理です。これを理解するには数学の授業で習う「2の補数」の知識が必要です。
ただし、こうした答えを暗記する必要はありません。答えが知りたければSmileBASICを使ってみればいいだけです。わからないことはキーボードを叩いて解決していきましょう。
たとえば、こちらはAND処理を行うプログラムです。4行目の「C=A AND B」がその数式です。
A? 1
B? 3
A AND B=1
OK
│
プログラムの実行結果です。ここでは例として変数Aに1を代入し、変数Bに3を代入しています。結果として「1」が表示されました。
この場合、プログラム内では「1 AND 3」というビット演算が行われています。
1と3を2進数に置き換えると次のようになります。「&B」というのは2進数であることを表している記号です。
10進数 | 2進数 |
1 | &B01 |
3 | &B11 |
2進数のAND処理はお互いのケタごとに行います。つまり結果は、&B01 AND &B11 → &B01。答えは1となります。
ビット演算は様々な場面で使うことができますので、今のうちに仕組みを覚えておきましょう。
配列
より高度な計算を行うのに役立つのが「配列変数」です。配列変数は「配列」と呼ぶことにします。配列とは複数の情報を格納することができる変数の構造のことです。
配列を扱うには「DIM」という文を使います。
DIMの書式は次のとおりです。
DIM
変数名[
要素数]
たとえば、「DIM X[100]」と実行すると、要素が100個あるXという配列が作られます。DIMを使って配列を作成することを「配列を宣言する」といいます。
配列には番号が割り振られています。この番号を「インデックス」といいます。インデックスは0番から始まります。
もし、宣言していない配列を使おうとすると、「Undefined variable(変数が未定義)」というエラーが表示されてしまいます。使用したい配列は事前にDIMで宣言をしておく必要があります。
配列を使ったプログラムを作ってみました。100個のボールがバウンドするというプログラムです。
今回、初めて「FOR」という文が使われています。FOR文は一定回数の処理を繰り返すプログラムの処理です。
FOR文の書式は次のとおりです。
FOR文で使用する「変数名」とは繰り返す処理を数えるためのものです。ここでは変数Iを使用しました。処理を100回繰り返したい場合には「FOR I=0 TO 99」と記述します。
FORは「NEXT」とセットで使います。FORとNEXTの間に繰り返したい処理を配置します。繰り返すためのプログラムは見やすくするために空白を使って、少し右側にずらしています。これを「字下げ」といいます。
4~7行目では「RND」関数を使って、ボールの出現する位置と移動速度を求めています。RND関数はランダムな値を発生させる関数です。RND関数の書式は次のとおりです。
= RND
(最大値)
戻り値の範囲は0~最大値-1です。
プログラムを実行すると、このとおりです。100個のボールが表示されます。
ボールは画面内をバウンドし続けます。個々のボールの移動する速度はランダムです。
(おまけ)ボールをよけるゲーム
先に作った「ボールがバウンドするプログラム」を改造してゲームを作ってみました。名付けて「ボールをよけるゲーム」です。
プログラムがこちらです。
まだ紹介していない命令や関数をいくつか使っています。
11~14行目の「PUSH」は配列の要素を追加することができる命令です。先のプログラムでは配列が100個の要素数からスタートしていましたが、このプログラムでは0個の要素数からスタートします。
プログラムの6行目では「BUTTON」という関数を使って、本体のボタンの状態を読み取っています。ボタンを押すと対応する値が変化して、変数BTに格納されます。押されているボタンによって、変数BTの値は次のように変わります。どのボタンも押していない場合、値は0となります。
そして、プログラムの7行目は左ボタンの判定、8行目は右ボタンの判定する処理を行っています。判定するには先ほど紹介したビット演算を使います。
たとえば7行目には次のような式が使われています。
BT AND #LEFT
この中の「#」というのは「定数」といい、SmileBASICが事前に登録している数値に置き換える機能です。これによって、「#LEFT」は「&B100」に置き換わります。式は次のように考えることができます。
BT AND #LEFT
↓
BT AND &B100
では、左ボタンの状態によって、どのような計算結果になるのでしょうか?
それをまとめたものが次の表です。
左ボタンの状態 | 変数BTの値 | AND処理の計算結果 |
押されている | &B100 | &B100 |
押されていない | 0 | 0 |
つまり、計算結果を比較することでボタンを押した/押していない状態かがわかるわけです。
ビット演算はこれからも繰り返し登場します。
プログラム実行中の様子です。
画面中央にある人型のキャラがプレイヤーです。プレイヤーをうまく操って、ボールをよけるというゲームです。プレイヤーは十字ボタンを使って、左右に動かすことができます。上下には動かすことができません。
ボールは1秒に1個のペースで増えていきます。少しずつ難しくなっていきます。
プレイヤーがボールに当たってしまうとゲームオーバーです。
プログラムの行数を節約していますので、ゲームとしては少しイマイチかもしれません。自分好みに面白くなるように改造して遊んでみましょう。
まとめ
参考までに今回、紹介した内容を箇条書きでまとめてみました。命令や関数については、SmileBASICに搭載されているヘルプ機能を使うことによって、より詳しく調べることができます。命令表 も参考になるのでぜひ活用してみましょう。
- 変数
- 配列変数
- 定数
- 算術演算子
- ビット演算子
- 比較演算子
- IF~THEN~
- GOTO
- LOCATE
- FOR~NEXT
- CHR$()
- FLOOR()
- BUTTON()
※100個のボールがバウンドするプログラム:公開キー「933NV3KM」
※ボールをよけるゲーム:公開キー「K34EXPD」