BASIC
BASICとは?
コンピュータは機械語と呼ばれる0と1のみで構成された羅列で処理を行いますが、人間にはそれがどのような命令か分かりにくいため、コンピュータにも人間にも通じるように作られたのがプログラミング言語であり、そのうちの1つがBASICです。ここではポケットコンピュータのプログラミングに必要な操作・基本的な処理をご紹介します。
目次
操作編
- 実際にプログラミングしてみましょう
- プログラムを実行する
- エラーが表示されたら
- プログラムが思い通りに動いているか確認する
- プログラムを保存する
- 保存したプログラムを呼び出す
- 保存したプログラムを消去する
- その他便利な機能
処理編
実際にプログラミングしてみましょう
それでは、簡単なプログラムからプログラミングしていきましょう。まず、ポケットコンピュータ(以下"ポケコン")の電源を入れ、BASICと書かれたボタンを押してください。BASICプログラムは画面の右上に"PRO"と表示されたこの"PROモード"で打ち込みます。
次にNEWと入力し、キャリッジリターンキー(CRキー、⏎)を押します。こうすることでポケコンに残っているプログラムやデータを初期化し、新しくプログラミングする準備が整います。
準備が終わったら、以下の内容をポケコンに打ち込んでください。
プログラム例
100:REM "NEW"
110:PRINT "Hello, BASIC!"
120:END
最初の数字を行番号と呼び、大きくなればなるほど下に並びます(昇順)。コロン:に続くのが命令文で、実行したい処理を記述していきます。行番号は1、2、3…でも問題ありませんが、後で行を足すときに元からあった行の番号をいちいち書き換えなくていいようにするため、目安として10ずつ空けておくことをおすすめします。
なお、行をまるごと消すときはコロン:より後ろの文(命令文)をBSまたはSHIFTとINSの同時押しで削除します。SHIFTと何らかのボタンを同時に押すと、そのボタンの上のオレンジ色で書かれた文字が入力されます。これは、2ndFを押したあとにそのボタンを押しても同じになります。
ポケコンでは、数字とアルファベット(大文字・小文字)、カタカナが使えますがひらがなや漢字はありません。ただし、キャラクタコードには漢字が少数ではあるものの収録されています。CAPSで大文字と小文字が、カナでアルファベットとカタカナが切り替えられ、カタカナの状態でCAPSを押すと次に入力するカタカナ一字が小文字(ァ・ィ・ゥ・ェ・ォ・ッ・ャ・ュ・ョ)になります。なお、小文字のアルファベットは引用符"で括られた箇所かREM文(後述)の注釈でのみ有効で、それ以外は自動的に大文字に変換されます。
プログラムを実行する
打ち込みが終わったらBASICを押します。すると画面右上の"PRO"が"RUN"に変わります("RUNモード"と言います)。ここで画面にRUNと入力し、キャリッジリターンキーを押すとプログラムを実行することが出来ます。
Hello, BASIC!と表示されれば成功です。おめでとうございます!>はプログラムの実行が正常に終了したことを示しています。
ERROR 10 IN 110などと表示されたときはプログラムに間違いがあります。詳しくは次項"エラーが表示されたら"またはエラーコード一覧をご参照ください。
エラーが表示されたら
プログラムに間違いや文法上の誤りがあると、ERROR に続いてエラーコードが、IN に続けて問題のある行の行番号が表示され、プログラムの実行が停止します。
エラーの原因となっている行を確認するためにCLSを押して表示内容を消去し、BASICでPROモードに変えて▲または▼を押します。
表示された行をよく見ると、PRINT
となるべきところが誤ってPRIN
になっています。これがエラーの原因のようです。INSを押せば文字と文字の間に打ち込むことが出来る"挿入モード"になりますので、これでプログラムを修正(デバッグとも言います)します。挿入モードではカーソルが左三角◀に変わり、もう一度INSを押せば元の"上書きモード"に戻ります。修正が終わったら、"プログラムを実行する"に戻って再度プログラムを実行してください。
エラーコードが何を表しているのかはエラーコード一覧をご覧ください。
プログラムが思い通りに動いているか確認する
プログラムの行番号が昇順で並んでいるとおり、実行も数字が小さいほうから大きいほうに向かって進んでいきます。ところがプログラムが複雑になってくると、どの順番で命令文が実行されているのか分からなくなることも考えられます。ここで役に立つのが"トレース"です。まずはプログラム例"NEW"に少し手を加えます。
100:REM "NEW"
105:GOTO 120
110:PRINT "Hello, BASIC!"
120:END
105行を足しました。さて結果はどうなるでしょうか?
実行結果
実行すると何も表示することなく終了してしまいました。プログラムがどの順番で実行されたのかトレースで確認してみましょう。
RUNモードでTRONと打ち、⏎を押します。この状態でプログラムを実行するとトレースが開始されます。
今度は実行してすぐに100:が表示されました。これは今実行している行の番号です。次に進むには▼を押します。すると、105:を表示してプログラムは終了しました。
つまり、105行の命令文によって110行を実行しなかったことになりますが、GOTO
はその名前のとおり、任意の行に処理を飛ばす(ジャンプさせる)ものです。一瞬で終わるプログラムも、長大なプログラムもこれを使えば実行する順番を確認することが可能です。ちなみに、このGOTOを使って処理を最初の行に戻せば、無限ループとすることも出来ます。なお、無限ループとなったプログラムを止めるときはON(BREAK)を押してください。
プログラムを保存する
ポケコンには"プログラム・データエリア"と"プログラムファイルエリア"の2つの領域があり、前者はRUNで実行可能なプログラムを、後者は保存したプログラムを保持しています。つまり、プログラムファイルエリアにプログラムを保存すれば、プログラム・データエリアを使ってまた別のプログラムを作成することができるわけです。内部メモリの容量の範囲内でいくつものプログラムを保存できますが、オールリセットを行うとすべて消去されますので注意してください。
プログラムを保存するにはまずプログラムの名前、ファイル名が必要です。ファイル名は大文字・小文字のアルファベットと数字を使うのが一般的です(最大8文字、一部の記号も使用可)。SAVEに続けて任意のファイル名を引用符で括って入力し、⏎を押して>が表示されたら保存は完了です。
保存したプログラムを呼び出す
プログラムファイルエリアのプログラムをプログラム・データエリアに呼び出すと、今までプログラム・データエリアで保持していたプログラムはなくなりますのでご注意ください。
LOADに続けて呼び出したいプログラムのファイル名を引用符で括って入力後、⏎を押します。ファイル名は保存した名前と完全に同じでなければなりません。
ファイル名を忘れた場合は、まずFILES⏎で保存したファイル名の一覧を表示させます。この状態で左の矢印を▲または▼で呼び出したいファイル名の横に移動させ、SHIFTとMを同時に押せばそのファイル名で保存したプログラムが呼び出されます。
保存したプログラムを消去する
プログラムファイルエリアからファイルを消去するには、KILL "ファイル名"⏎と操作します。
その他便利な機能
マニュアル操作(手動操作)で利用できる便利な機能をご紹介します。
指定桁での四捨五入
計算結果を小数点以下何桁まで表示させるか指定できます。計算を行う前、または結果が表示されているときにSHIFTとF↔Eを同時に押し、桁数にあたる数字を1つ入力します。
桁数に2を入力した場合
小数第3位で四捨五入し、小数第2位まで表示されました。負数は絶対値として丸められます。
指定を解除するには、SHIFTとF↔Eを同時に押して·を入力します。(モード切り替えや電源を切ることでも解除されます)
定数計算
あらかじめ設定した数値と演算子(+、-、∗、/)の組み合わせ(定数)を使用して計算します。数値・演算子CONSTを入力すると定数が設定され、消去するまではすべて定数計算となります。
例として、ある商品の価格を1割引きした値段(=9割)を繰り返し求める場合について考えます。まずは0.9∗CONSTで定数を設定してください。画面の右下にある"CONST"が点灯します。
この状態で数値⏎を操作すると、そのたびに定数を利用した計算が行われます。
定数の設定内容を確認するにはSHIFTとCONSTを、消去するにはSHIFTとCLSをそれぞれ同時に押します。なお電源を切ることでも設定が消去されます。
入出力
ここからは処理編になります。プログラムはこのいくつかある処理を組み合わせて目的に合った形にします。プログラム例を1つ1つ確認していきましょう!
プログラム例
100:REM "INPUT-OUTPUT"
110:INPUT A
120:B=3.14*A^2
130:PRINT B
140:END
実行結果
実行するとすぐに?が表示されます。これはポケコンが入力を待っていることを表しますので、ボタンを押して好きな数値を入れてください。入力が終わったら⏎で確定させると次に進みます。
1を入力した場合…3.14
2を入力した場合…12.56
10を入力した場合…314
分かりましたか?これは入力した値を半径とする円の面積(円周率は3.14とする)を求めるプログラムです。
命令文の意味
100:REM "INPUT-OUTPUT"
- プログラムの名前、注釈を書きます。この命令が先頭にあるとそれ以降の内容は無視されますので、修正で一時的に命令文を実行させない場合にも使えます。
110:INPUT A
- 変数A(変数については変数宣言・配列をご参照ください)に、キーボードから入力した値を代入します。この文では実行すると?が出るだけでしたが、
のように記述すれば引用符で括られた文字列が表示されるようになります。110:INPUT "ハンケイ? ";A
120:LET B=3.14*A^2
- 変数Bに3.14∗A^2の結果を代入します。LETは学習用の命令語で普通は使わないため、プログラム例には書いていません。
130:PRINT B
- 変数Bに代入されている値を出力(表示)します。また、INPUTと同じく引用符で括られた文字列も表示できます。変数と文字列を繋ぐときはセミコロン;を使ってください。
140:END
- プログラムを終了します。画面には待機中を示すプロンプト記号>が必ず表示されます。
繰り返し
上記のプログラムを何回も実行しようとすると、毎回RUNと入力するのが面倒になってきます。そんなときに活躍するのが"繰り返し処理"で、この処理があるおかげでプログラムを短く書くことが出来るわけです。プログラム例"INPUT-OUTPUT"を次のように書き換えてください。
プログラム例
100:REM "LOOP"
105:FOR C=0 TO 5
110:INPUT "ハンケイ? ";A
120:B=PI*A^2
130:PRINT "ハンケイ: ";A;" メンセキ: ";B
135:NEXT C
140:END
105行と135行を追加し、120行と130行を書き換えています。ポケコンでは"PI"が円周率(≒3.141592654)としてあらかじめ設定(定数)されているので使ってみました。
実行結果
入力・出力(計算結果)が分かりやすく、より正確になり、同じ計算(処理)が6回繰り返されるようになりました。
命令文の意味
105:FOR C=0 TO 5 / 135:NEXT C
- 変数Cに0を代入したあと、そこから続くプログラムを処理していき、"NEXT C"が出現するごとにCに1を足して5になるまでFOR文とNEXT文の間を繰り返します。つまり、0・1・2・3・4・5の6回同じ処理を行います。なおこれは
から105:FOR C=0 TO 5 STEP 1
STEP 1
を省略したものです。1は"きざみ値"と呼び、必要に応じて任意の数値に変えることが出来ます。プログラムを仮にSTEP 2
と記述すると0・2・4と繰り返す数が3回になり(6は最終値の5を超えているため実行されません)、STEP 0
にするとCにいくら0を足しても5に到達することはないので無限ループになります(前述の通り、無限ループとなったプログラムを止めるときはON(BREAK)を押してください)。
フォーマット
プログラム例"LOOP"で定数PIを使用した結果、画面には小数第7位まで表示されましたが、実際の計算ではそんな長い桁まで求めることは稀だと思います。そこで、表示する桁を前もって指定することで、出力する内容を調整してみましょう。
プログラム例
100:REM "FORMAT"
102:USING "####.##"
105:FOR C=0 TO 5
110:INPUT "ハンケイ? ";A
120:B=PI*A^2
130:PRINT "ハンケイ: ";A
132:PRINT "メンセキ: ";B
135:NEXT C
140:END
102行を追加し、130行の内容の後半部分を132行に分けました。
実行結果
出力(計算結果)が見やすくなりました。同じ計算(処理)を6回繰り返すのは変わりません。
命令文の意味
102:USING "####.##"
- PRINT命令で数値を出力するときのフォーマットを指定します。"#"は数値1桁を、"."は小数点を意味します。この場合、数値4桁+小数点以下2桁となりそうですが、符号(マイナス-)に1桁使用するため、正しくは符号1桁+数値3桁+小数点以下2桁です。よって、例えば整数5桁(小数点なし)を出力させるには"######"と符号用の桁を1つ足して指定しなければ思い通りの結果にはなりません。
四捨五入
USING命令の出力内容を見ると、溢れた桁はすべて切り捨てになっていることが分かります。数値を四捨五入するための命令語はありませんが、次のような方法で代えられます。なお、どちらの方法も以下の3つの事項を利用したものです。
- 四捨五入したい位が5以上なら、その桁に5を足せば切り上がる
- 四捨五入したい位が4以下なら、その桁に5を足しても切り上がらない
- 切り上がらなかった桁は、計算または表示時に切り捨てられる
INTを使用する方法
100:REM "ROUND"
110:INPUT "マルメルカズ? ";A
120:INPUT "ショウスウテンイカ? ";B
130:C= SGN A*( INT ( ABS A*10^B+0.5)/10^B)
140:PRINT C
150:D= INT (A*10^B+0.5)/10^B
160:PRINT D
170:END
実行結果
最初に丸めたい数、次にどの位で四捨五入するか(整数にするときは0)を入力してください。
命令文の意味
130:C= SGN A*( INT ( ABS A*10^B+0.5)/10^B)
- 負数(0より小さい数)も含めた数値を任意の桁で四捨五入します。小数第1位を四捨五入し整数にするだけであれば、
と記述することも可能です。なお、SGNは数値が負数であれば-1、0であれば0、それら以外は1を返す命令語、INTは小数点以下を切り捨て、その数値を超えない最大の整数を返す命令後、ABSはマイナスを取り除いた絶対値を返す命令語です。130:C= SGN A* INT ( ABS A+0.5)
150:D= INT (A*10^B+0.5)/10^B
- 0以上の数値を任意の桁で四捨五入するときはこの命令文が利用できます。こちらも小数第1位を四捨五入し整数にするだけであれば、
と記述できます。150:D= INT ( ABS A+0.5)
USINGを使用する方法
出力する桁数がUSINGで指定されている場合、この方法を使うと簡単です。
100:REM "ROUND"
110:USING "#####.#"
120:INPUT "マルメルカズ? ";A
130:C= SGN A*( ABS A+0.05)
140:PRINT C
150:END
実行結果
整数4桁以内+小数第2位以上の数値を入力してください。小数第2位で四捨五入した結果を表示します。
命令文の意味
130:C= SGN A*( ABS A+0.05)
- このプログラムのUSINGは小数第1位までの表示を指定していますので、その1/10(1つ右)の位、つまり小数第2位に5を足すために0.05となっています。位をどこまで表示するかによって加算する数値が変わってきますので、USINGの内容を変えたら数値を変更するのを忘れないようにしましょう。変数Aに負数が入らないのであれば、
としても処理できます。130:C=A+0.05
条件分岐
条件分岐とは、"もし~が◯であれば△をする"というような処理を言い、条件を満たすかどうかによってある処理を実行させる(またはさせない)場合に使用します。ここでの"条件"とは比較演算子によって値を比較するための式で、例えば"A < B"のようなものです。この場合、AがBより小さければ(条件と一致すれば)"条件を満たす"、それ以外(条件と一致しない場合、つまりAがBと同じかそれ以上)であれば"条件を満たさない"と言います。
比較演算子
BASICで使用できる比較演算子の一覧です。数値の他、文字列でも比較することが可能で、文字列はそれぞれのキャラクタコードの大小で比べることになります。
A < B
- AがB未満であれば条件を満たします。
A > B
- AがBを超えていれば条件を満たします。
A <= B
- AがB以下であれば条件を満たします。
A >= B
- AがB以上であれば条件を満たします。
A = B
- AがBと同じであれば条件を満たします。
A <> B
- AがBと異なれば条件を満たします。
他のプログラミング言語とは違い、等号=を2つ繋げたり感嘆符!を使用したりすることはありません。とても単純です。
論理演算子
条件が2つ以上あるときは論理演算子で結合させます。ただし、加減乗除に計算の順番があるように論理演算子にも優先順位があり、OR
よりもAND
を優先する原則があります(AND
が複数あるときは左のAND
から評価します)。条件が3つ以上あり、評価の優先順位を変えたいときは優先する条件式を括弧で括ってください。
A = 0 AND B <> 0
- Aが0・Bが0以外の両方を満たせば条件を満たします。
A = 0 OR B <> 0
- Aが0・Bが0以外のどちらか(両方でもよい)を満たせば条件を満たします。
プログラム例
100:REM "BRANCH"
110:INPUT "セイレキ? ";A
120:IF A<0 THEN END
130:IF A MOD 4=0 AND A MOD 100<>0 OR A MOD 400=0 THEN B$="ウルウドシ" ELSE B$="ヘイネン"
140:PRINT B$;" デス"
150:END
実行結果
2000を入力した場合…ウルウドシ デスと表示されました。
入力した数値を西暦年とみなし、それが閏年かどうかを判定します。負数を入力したときは何も表示せずに終了します。
命令文の意味
120:IF A<0 THEN END
- 条件式を判断し、満たしていれば
THEN
に続く命令だけを、満たさなければ何もせずに次の行へ移ります。そのため、
のようにIF文にコロン:を足して繋げた命令は条件を満たすときだけ実行されます。120:IF A<0 THEN PRINT "セイレキガ マイナス デス" :PRINT "ゼッタイチデ ハンテイシマス" :A= ABS A
130:IF A MOD 4=0 AND A MOD 100<>0 OR A MOD 400=0 THEN B$="ウルウドシ" ELSE B$="ヘイネン"
- 条件式を判断し、満たしていれば
THEN
に続く命令だけを、満たさなければELSE
に続く命令だけを実行します。
条件式について
西暦は以下の2条件のうちどちらかを満たせば閏年となります。
- 4で割り切れ、かつ100で割り切れない西暦年は閏年
- 400で割り切れる西暦年は閏年
割り切れるかどうかを調べるときに登場するのがMOD
です。A MOD B
はAをBで割ったときの余りを求める演算子で、マニュアル計算でも使えます。
A MOD B = 0
- AをBで割ると余りが0(割り切れる)であれば条件を満たします。
A MOD B <> 0
- AをBで割ると余りが0以外(割り切れない)であれば条件を満たします。
こうして出来た条件を論理演算子で組み合わせたものが130行の条件式になります。
変数宣言・配列
ここまで変数について大きく触れることなく進んできました。他のプログラミング言語とは異なり、いきなり変数に値を代入しても実行には問題ありませんが、"宣言"と呼ばれる定義を行うことでメモリを確保し、繰り返し処理に利用したり保持する文字数を変えて長い文字列を処理したりといったことが可能になります。
変数とは?
変数はよく"箱"に例えられます。1つの箱には任意の数値や文字列(これらを"データ型"、または単に"型"と呼びます)を1つ収めることができ、必要なときに呼び出して計算したり表示させたりして使います。変数はアルファベット1文字かアルファベット+アルファベットまたは数字の2文字で好きな名前を付けられますが、後述するように制約もあります。
型とは?
データの種類のことです。BASICでは数値型(0、77.5、-9.99999、PIなどの10進数)と文字列型("コンニチハ!"などの文字列や"0101"、"5EF"などの2進数・16進数)に分けられます。数値用の変数に文字列を代入しようとするとエラーになるように、BASICでは1つの変数は1つの型のみ扱います。
変数の種類
変数に格納できるデータの長さと型によって、変数には以下の種類があります。
- 数値変数
- 数値固定変数
- A・B・C…などのアルファベット1文字
- 数値単純変数
- AA・ID・X1…などのアルファベット+アルファベットまたは数字の2文字
- 数値配列変数
- TB(3,4)など
- 文字変数
- 文字固定変数
- A$・B$・C$…などのアルファベット1文字+$
- 文字単純変数
- AA$・ID$・X1$…などのアルファベット+アルファベットまたは数字の2文字+$
- 文字配列変数
- TB$(3,4)など
変数名の制約
- アルファベットは大文字のみ
- 記号は使用不可。ただし文字を格納する文字変数は末尾に$を付ける
- IFやON、PIなどの予約語でないこと
- 固定変数(1文字の変数)は、数値変数か文字変数のどちらかのみ使用可能(XとX$は同時に使えない)
- 3文字以上の変数でもエラーにはならないが、最初の2文字だけで判別される(ANS1とANS2は同じ変数ANと見なされる)
変数に格納できるデータの長さ
文字変数の場合、格納できるデータの長さ以上の値を代入すると、超えた分の文字は切り捨てられます。
- 数値変数
- 有効数字10桁まで(仮数部10桁+指数部2桁)
- 文字固定変数
- 7文字まで
- 文字単純変数
- 16文字まで
- 文字配列変数
- 16文字(DIM命令により1~255文字まで設定可能)
配列とは?
同じ型の変数が1つ以上集まった集合体、変数の集まりと思ってもらえれば良いでしょう。例えば、とあるゲームの1回目の得点を変数P1、2回目の得点をP2、…9回目の得点をP9に代入したとします。これら9つの値の合計Tを求めるとき、
T=P1+P2+P3+P4+P5+P6+P7+P8+P9
とすべての変数を記述しなければなりませんが、配列Pを使うと
FOR N=0 TO 8
T=T+P(N)
NEXT N
と繰り返し処理が利用できるようになるため、プログラム全体で見れば命令文の量が明らかに少なくて済み、間違いやエラーが起きにくくなることも期待できます。
配列Pを見ると、P(0)には1回目の得点、P(1)には2回目の得点、…が代入されており、このデータ1つ1つを要素、括弧の中の数字を添字(そえじ)と呼びます。添字は1ではなく0から始まることに注意しましょう。普通の変数と同じように値を代入したり呼び出したり出来ますが、使用するには前述の通り"宣言"と呼ばれる定義が必要です。
プログラム例
100:REM "VARIABLE"
110:DIM A(9) :D=0
120:FOR C=0 TO 9
130:INPUT A(C)
140:NEXT C
150:FOR F=0 TO 8 :E=A(F) :D=F
160:FOR C=F+1 TO 9
170:IF E<A(C) THEN D=C :E=A(C)
180:NEXT C
190:A(D)=A(F) :A(F)=E :NEXT F
200:CLS
210:FOR G=0 TO 9
220:PRINT A(G);" ";
230:NEXT G
240:END
実行結果
実行したら、好きな数値を10回入力してください。入力を終えると大きい順に並び替えられて表示されます。
命令文の意味
110:DIM A(9)
- 変数Aを0~9の10個のデータを保持する数値配列変数として定義します。配列が使えるのはこの命令文のおかげです。定義する変数が複数あるときは
とコンマで区切って記述します。110:DIM A(9),Y(5),Z$(10)
130:INPUT A(C)
- 変数Cの初期値は0なので、1回目はA(0)に数値を代入します。2回目はA(1)、3回目はA(2)…と繰り返し、10回目のA(9)までの10個の要素の値をここで入力します。
200:CLS
- 表示内容をすべて消去し、次の出力(表示)を(0,0)位置(画面左上)にリセットします。
データ
データとは資料や情報などを意味する言葉ですが、BASICのDATAもまさにそのために用意された命令語です。具体的には、処理で必要な資料や情報を保持しておくもので、保持するデータを呼び出すにはREADを使います。DATAとREADはどちらが欠けてもうまく動かない相棒の関係にあると言えます。
プログラム例
100:REM "DATA"
110:DIM A(9) :D=0
120:FOR C=0 TO 9
130:READ A(C)
140:NEXT C
150:FOR F=0 TO 8 :E=A(F) :D=F
160:FOR C=F+1 TO 9
170:IF E<A(C) THEN D=C :E=A(C)
180:NEXT C
190:A(D)=A(F) :A(F)=E :NEXT F
200:CLS
210:FOR G=0 TO 9
220:PRINT A(G);" ";
230:NEXT G
240:END
250:DATA 10,33,26,170,15,7,2,7,0,69
プログラム例"VARIABLE"の130行を書き換え、250行を追加しました。250行の10個の数字は好きなもので構いません。
実行結果
実行すると、DATA文の数字が大きい順に並び替えられて表示されました。
命令文の意味
130:READ A(C)
- 配列変数A(C)にDATA文のデータを代入します。プログラム例ではA(0)に10、A(1)に33、A(2)に26、…が代入されます。
250:DATA 10,33,26,170,15,7,2,7,0,69
- データを定義します。データの区切りにはコンマ,を使用してください。
サブルーチン
同じ処理を繰り返すのが"繰り返し処理"ですが、同じ処理を好きなときに使えるのが"サブルーチン"です。
プログラム例
100:REM "SUBROUTINE"
110:DIM A(9) :D=0
120:FOR C=0 TO 9
130:READ A(C)
140:NEXT C
150:FOR F=0 TO 8 :E=A(F) :D=F
160:FOR C=F+1 TO 9
170:IF E<A(C) THEN D=C :E=A(C)
180:NEXT C
190:GOSUB *DISP :A(D)=A(F) :A(F)=E :NEXT F
200:GOSUB *DISP
202:END
204:*DISP
206:CLS
210:FOR G=0 TO 9
220:PRINT A(G);" ";
225:IF G=9 THEN PRINT :WAIT :PRINT "CRキーヲオシテクダサイ"
230:NEXT G
240:WAIT 0 :RETURN
250:DATA 10,33,26,170,15,7,2,7,0,69
プログラム例"DATA"の200行を206行・240行を202行に行番号を変更し、190行・200行・240行を書き換え、204行・225行を追加しました。
実行結果
実行すると、DATA文の数字が記述された通りに並び、その下にはCRキーヲオシテクダサイと表示されます。
この状態で⏎を押すと10と170が入れ替わりました。
また⏎を押すと、今度は33と69が入れ替わりました。
⏎を押すごとに数字が入れ替わり、最終的には大きい順に並び替えられます。
このプログラムは、プログラム例"DATA"の並び替えの動作を1つ1つ確認できるようにしたものです。
命令文の意味
190/200:GOSUB *DISP
- "∗DISP"と書かれた行にサブルーチンジャンプ(実行する行を移す)します。
204:*DISP
- 行頭(行番号の後ろ)に書かれた、アスタリスク∗で始まるか引用符"で括った文字列をラベルと言います。GOSUBはラベルではなく行番号の指定
も可能ですが、ラベルは行番号を考慮する必要がないのでおすすめです。190:GOSUB 204
文字列
文字列とは文字の集合体で、数値と区別するために引用符"で括ります。例えば12345は数値、"12345"は文字列です。それぞれの文字は1文字ずつASCII(アスキー)というコード表に基づいて番号(キャラクタコード)が振られており、BASICもそれに則っています(一部除く)。文字列も変数に代入できますが、BASICでは文字列用の変数は名前の最後に$を付ける決まりがあります。
プログラム例
100:REM "CHARACTER"
110:A$="" :USING "####"
120:WHILE A$<>"0"
130:A$= INKEY$
140:B= ASC A$
150:IF A$="" THEN A$=" "
160:LOCATE 15,2
170:PRINT "キ- ";A$
180:LOCATE 8,4
190:PRINT "キャラクタコ-ド ";B
200:WEND
210:END
実行結果
実行後、キーボードの好きなキーを押してください。その文字のキャラクタコードを表示します。
CRキー(⏎)やスペースキーなどにもキャラクタコードがあることが分かります。0を押せばプログラムが終了します。
命令文の意味
120:WHILE A$<>"0" / 200:WEND
- WHILEに続く条件式を判断し、満たしていればWENDまでの間を繰り返し実行します。WENDに到達したとき、条件式を満たしていなければループを抜けて次の命令文に実行が移ります。最初から条件式を満たしていない場合はWENDまでの間は実行せず、次の命令文に移ります。A$は130行の説明の通りキーボードから入力された値ですので、これが0でない限りは繰り返し処理を行います。
130:A$= INKEY$
- 文字列変数A$にキーボードから入力された値を代入します。ただしこの文だけでは処理が一瞬で終わり、キーが押されるのを待つことが出来ないため、通常は上記のような繰り返し処理と組み合わせて待機状態を作ります。INKEY$を含め、文字列を返す命令には最後に$が付いています。
140:B= ASC A$
- 数値変数Bに、文字列変数A$の値(押されたキー)のキャラクタコードを代入します。ASCは文字列(2文字以上あるときは先頭の文字)をキャラクタコードに変換する命令です。
160:LOCATE 15,2
- 画面左上(0,0)を基準に、これ以降の出力(表示)開始位置を左から15列目、上から2行目に設定します。
疑似乱数
サイコロを振るとき、1から6のどの目が出るかは振ってみないと分かりませんが、何千回、何万回と振っていくと1が出る確率も6が出る確率も、どの目も1/6に近づいていくことはご存じだと思います。乱数とはこのように規則がなく予想できない数のことを言い、BASICにも乱数を発生させる命令があります。しかしながら、コンピュータが発生させる乱数には必ず何らかの規則があるため、規則がなく予想できない真の乱数に対して疑似乱数と呼ばれています。そんな疑似乱数ですが、ゲームの進行や対戦などの結果を左右する大きな鍵であり、とても重要なものです。
プログラム例
100:REM "RANDOM"
110:RANDOMIZE :A$=""
120:DIM C$(3) :C$(0)="ダイキチ" :C$(1)="チュウキチ" :C$(2)="ショウキチ" :C$(3)="キチ"
130:CLS :LOCATE 2,2 :PRINT "オミクジ ";
140:WHILE A$=""
150:A$= INKEY$
160:WEND
170:B= RND 4-1
180:PRINT "コレダ!"
190:LOCATE 16,3 :PRINT C$(B)
200:END
実行結果
おみくじです。何かキーを押すと運勢が出ます。何が出ましたか?
命令文の意味
110:RANDOMIZE
- RND命令に先立ち、乱数の種を植え付けます。これによって疑似乱数が真の乱数になるわけではありませんが、この命令がない場合と比べて不規則性が高まります。
170:B= RND 4-1
- 疑似乱数を発生させます。ここで
と記述すると1・2・3・4のどれかが発生します。欲しい数値は120行にある配列C$の添字の範囲(0・1・2・3)なので、発生した数値から1を引いて欲しい範囲に合わせています。170:B= RND 4
190:PRINT C$(B)
- 上記の通り変数Bには0~3のどれかが代入されることから、配列C$(0)~C$(3)のどれかが表示されることになります。
グラフィック
ポケコンの液晶画面は数字やアルファベットなどを表示するだけでなく、1ドットずつ点灯・消灯を指定できるようになっています。描画の最小単位は縦4ドットですが、指定の基本単位は縦8ドットと違いがあります。
2進数
ドットの点灯・消灯は2進数の知識があると役立ちます。そもそもN進数とは"NのM(正の整数)乗がM+1桁になる数"と説明でき、普段使っている10進数は10^1(=10)で2桁、10^2(=100)で3桁、10^3(=1000)で4桁、…と桁が増えていきます。2進数はありとあらゆる数値を0と1で表現する方法で、2^1(=2)で2桁、2^2(=4)で3桁、2^3(=8)で4桁、…と増えることになります。ところでコンピュータの内部では電圧の高低だけで処理を行いますが、"電圧が低い状態"を0、"電圧が高い状態"を1と表すことが一般的です。ドットの状態もこれに共通しており、0を消灯・1を点灯に対応させています。
10進数 | 2進数 |
---|---|
0 | 0 |
1 | 1 |
2 | 10 |
3 | 11 |
4 | 100 |
5 | 101 |
6 | 110 |
7 | 111 |
8 | 1000 |
9 | 1001 |
10 | 1010 |
11 | 1011 |
12 | 1100 |
13 | 1101 |
14 | 1110 |
15 | 1111 |
16 | 10000 |
16進数
10進数の16を2進数で表記すると10000になり、桁がやたらと長くなります。これを短く表記できるのが16進数です。16進数ということは16^1(=16)で初めて桁が繰り上がるので、それまでの10~15は1文字で表記できるようにアルファベットが充てられています。基本単位の8つのドットをすべて点灯させるなら2進数では11111111と8桁必要なところ、16進数ではFFだけで済みます。BASICではFFのような16進数でドットの点灯・消灯パターンを指定します。
10進数 | 2進数4桁 | 16進数 |
---|---|---|
0 | 0000 | 0 |
1 | 0001 | 1 |
2 | 0010 | 2 |
3 | 0011 | 3 |
4 | 0100 | 4 |
5 | 0101 | 5 |
6 | 0110 | 6 |
7 | 0111 | 7 |
8 | 1000 | 8 |
9 | 1001 | 9 |
10 | 1010 | A |
11 | 1011 | B |
12 | 1100 | C |
13 | 1101 | D |
14 | 1110 | E |
15 | 1111 | F |
16進数とドットパターン
下の画像は縦4ドットの点灯・消灯のパターンを分かりやすいように拡大し数値(16進数)別に並べたものです。塗りつぶされたマスが点灯したドットを、塗りつぶされていないマスが消灯したドットを表します。例えばAは2進数4桁では1010で、パターンは上から"消灯・点灯・消灯・点灯"ですが、これは2進数の右の位から下に並べたもの(0・1・0・1)と0=消灯・1=点灯の関係が一致することが分かります。なお実際には、縦8ドットずつ描画する関係上16進数を2桁単位(下→上の順)で記述します。
プログラム例
100:REM "GRAPHIC"
110:RANDOMIZE :A$=""
120:DIM C$(3)*38
122:C$(0)="848444241F244484840002EAAAAAAFAAAAEA02"
124:C$(1)="1E121212FF1212121E0002EAAAAAAFAAAAEA02"
126:C$(2)="201C0080FF00001C200002EAAAAAAFAAAAEA02"
128:C$(3)="000000000002EAAAAAAFAAAAEA020000000000"
130:CLS :LOCATE 2,2 :PRINT "オミクジ ";
135:LINE (99,20)-(123,33),S,B
140:WHILE A$=""
150:A$= INKEY$
160:WEND
170:B= RND 4-1
180:PRINT "コレダ!"
190:GCURSOR (102,30)
200:GPRINT C$(B)
210:END
プログラム例"RANDOM"の120行・190行を書き換え、122~128行・135行を追加しました。
実行結果
おみくじの運勢が四角い枠の中に漢字で表示されました。カタカナより断然分かりやすいですね!
この"中吉"の各文字のドットパターンを縦4ドットずつに分解すると、以下のようになります。
縦8ドットは下→上の順で記述しますので、"中"をグラフィックで表示させるには1E121212FF1212121E
と指定すれば良いわけです。
命令文の意味
120:DIM C$(3)*38
- 変数C$を0~3の4個の文字列(最大38字)を保持する文字列配列変数として定義します。
135:LINE (99,20)-(123,33),S,B
- 画面左上の点(0,0)を基準に、(99,20)と(123,33)を結ぶ線を対角線とする四角形を描画します。後ろの
,B
を省略して
と記述すると2つの座標を結ぶ線のみが描かれます。135:LINE (99,20)-(123,33),S
190:GCURSOR (102,30)
- 次のグラフィック出力(表示)を(102,30)位置に設定します。LOCATEが数値・文字列の出力開始位置を設定するのに対し、GCURSORはグラフィックの出力開始位置を設定します。
200:GPRINT C$(B)
- 指定されたパターンでグラフィック出力を行います。
終わりに
ここまでお疲れさまでした。どうでしょう、プログラミングは楽しいと思いませんか?もし興味が湧いたら、基本命令語一覧もご活用ください。
ようこそポケコンの世界へ!