パソコン活用研究5番街(Visual Basic、Excel(VBA)、BASIC プログラミング研究)
VB4〜VB6の配列については「配列(VB)」をご参照下さい。
(1) 配列の宣言と使い方
大量のデータを扱う時に便利なのが、配列です。
DIM A(100)
と宣言することにより、A(0)からA(100)まで101個の変数が用意されます。
(注1) ほとんどのBASICで、配列の添え字はA(1)ではなく、A(0)から始まる点に注意して下さい。
N88BASICにはOPTION BASE 1 を指定すると、添え字が1から始まります。
BASICによっては、OPTION BASEの指定ができないものがあります。
(注2)N88BASICやF-BASICでは配列をDIMで宣言しなくても、添え字が10までの配列は使用することができました。
■多次元配列
多くのBSICでは、
DIM A(10,10)
のように2次元配列、3次元配列(あるいはそれ以上の多次元配列)を宣言して使うことが出来ました。
2次元配列は2次元座標を表わすのに使うことができます。
以下ノプログラムでは2次元配列配列A$(4,4)に"*"などのキャラクタを入れ、画面上Aという文字を表示させています。
10 cls 20 DIM A$(4,4) 30 for i=0 to 4 40 for j=0 to 4 50 A$(i,j)=" " 60 next j,i 70 A$(2,0)="*": A$(1,1)="*": A$(3,1)="*": A$(1,2)="*": A$(3,2)="*": A$(0,3)="*": A$(4,3)="*": A$(0,4)="*": A$(4,4)="*":A$(2,2)="=" 80 for i=0 to 4 90 for j=0 to 4 100 locate i,j:print A$(i,j); 110 next i,j


子供の頃に遊んだことがあると思いますが、
例として、以下に 「いつ どこで 誰が 何を どうした」 ゲーム のリストをあげます。
DIM(配列), FOR ... NEXT, READ, DATA以外は INPUT, PRINT,
IF ... THEN, RND等の基本命令しか
使っていませんので分かりやすいと思います。
このように、大量(このゲームではさほど大量ではないですが)のデータを使うプログラム
で、データを変数にセットする場合、この方法が定石となっています。
まず、20行で配列の宣言をしています。when$ (いつ?のデータ用) where$ (どこで?のデータ用)
・・・といった具合です。
25行のrestore は以下の readで読み込むデータ(data
のある行)行の先頭行を指定
しています。この場合 when$()に読み込むデータは500行から読みはじめろ、ということに
なります。
以下 for ... next と readで次々にデータを変数に読み込んでいます。
300行からは、乱数(rnd)を使って、ランダムにデータを選択して表示しています。
400行からは、ユーザーの入れたデータ(どこで、何を)とコンピューター(いつ、誰が、どうした)
の合作の表示です。
10 '** いつどこで誰が何をどうしたGAME ver0.0.1** 15 '** N88互換BASIC用 Written ByKASAI ** 20 dim when$(11), where$(15),who$(11),what$(12),verb$(10) 25 restore 500 30 for i=0 to 11 40 read when$(i) 50 next 55 restore 510 60 for i=0 to 15 70 read where$(i) 80 next 85 restore 520 90 for i=0 to 11 100 read who$(i) 110 next 115 restore 530 120 for i=0 to 12 130 read what$(i) 140 next 145 restore 540 150 for i=0 to 10 160 read verb$(i) 170 next 180 randomize val(right$(time$,2)) 190 print "いつ どこで 誰が 何を どうした GAME ver0.0.1 Written by KASAI" 200 print "1 ComputerのDEMO 2コンピューターとあなたで合作する 3 終わり(半角で入力して下さい)" 210 a$=input$(1) 220 if a$="1" then gosub 300 230 if a$="2" then gosub 400 235 if a$="3" then end 240 goto 190 300 print when$(int(rnd*12)) 310 print where$(int(rnd*16)) 320 print who$(int(rnd*12)) 330 print what$(int(rnd*13)) 340 print verb$(int(rnd*11)) 350 print:return 400 input "どこでを入力して下さい",whe$ 410 input "何を、を入力して下さい",wha$ 415 print when$(int(rnd*12)) 420 print whe$ 425 print who$(int(rnd*12)) 430 print wha$ 440 print verb$(int(rnd*11)) 450 print:return 500 data きのう,今日,おととい,1年前,朝,昼,真夜中,夏休み,旅行に行った時,1週間前 505 data 冬,昼休み 510 data トイレで,家の前で,レストランで,公園で,階段で,駅で,デパートで,屋上で,バスの中で,机の上で 515 data 海で,山で,本屋で,花屋で,職員室で,社長室で 520 data 僕が,赤ちゃんが,弟が,お母さんが,おじさんが,おまわりさんが,猫が 525 data アメリカ人が,いぬが,友達が,先生が,金髪の美人が 530 data バナナの皮を,うんちを,アイスクリームを,シャベルを,ボールを,本を 535 data 1000円札を,団子を,コンピューターを,ぽけもんを,飴を,本を,花を 540 data 食べた,拾った,投げた,蹴飛ばした,踏み潰した,ポケットに入れた,捨てた 550 data 眺めた,飛び越えた,見つけた,踏んづけてころんだ
実行したところ
単純なゲームですがまあまあ面白いですね。
BASIC超基本2では、敵のキャラクタを1つだけ動かすプログラム例をあげましたが、
配列を使えば、簡単にたくさんのキャラを動かすことができます。
下のプログラムはFM8kame.bas(N88互換Basic for Win用 N88互換BASIC の
ページからダウンロードできます)の敵キャラ移動ルーチンの抜粋です。
変数の付け方が汚くて申し訳ありませんが、このゲームはかなり多くのキャラを動かして
います。
敵キャラは2種あり、一つは牛 "C" (500行から600行)、もう一つは虎
"T"(610行から
690行まで)です。
(1) 牛
牛の頭数は変数maxに設定してあります。ワンターンではそのうち3頭づつ動かしています。
牛は単純に一つ左に移動させています。ただし、前に他の牛、虎がいる時はその位置にとどまります。
変数は
Pが牛の番号(1からmaxまで)
Aは3頭づつ動かすためのカウンタ用 A>3となったら牛移動ルーチンから抜ける
cx(), cy() は牛のx座標、y座標
char( , ) その座標に 0なら何もいない 1なら牛がいる
2なら虎がいる
(2) 虎
虎は8頭です(No.1からNo.8)
虎の移動は for ... next
ループを使って、8頭の移動処理をしています。
8頭分の処理が終わってからメインルーチンにリターンさせています。
虎の移動は、他の牛、虎を避けて動くようにしてあります。基本は一つ左に移動(1)。もし、そこに牛、虎が
いたら斜め上に移動(2)。そこにも、牛、虎がいるか、道路にはみだすようなら、斜め下に移動(3)。
もし、そこにも牛、虎がいるなら、元の位置のすぐ下に移動(4)。それでもだめなら移動しない。
下の1から4の順で虎の移動先を選んでいきます。
| 2 1<T 3 4 |
変数
G 虎の番号(No.1からNo.8)
tx, ty 虎のx座標、y座標
QT1,QT2 虎の元の座標一時保存用
char 牛と同じ
ということで、牛も虎も配列を使い、通し番号で個々のキャラを識別、制御しています。
スマートでなくきたないコードですが、参考にして下さい。
FM8kame.bas (ver0.6) 抜粋
500 P=P+1:A=A+1 510 IF P>max THEN P=1 '牛のNo.がMaxを超えたらNo.1に戻す 520 IF A>3 THEN A=0:RETURN '3頭動かしたらリターン 525 LOCATE cx(P),cy(P):PRINT" ":char(cx(p),cy(p))=0:r1=cx(p):t1=cy(p) '牛を消す char( )=0にする 530 cx(P)=cx(P)-1 '一つ左に座標を移動 540 IF cx(P)<10 THEN GOTO 545 ELSE 570 '左端(X座標 10)まできたら右端移動の処理(545行へ) 545 cx(P)=31 '右端(X座標31) 550 LOCATE 10,cy(P):PRINT" ":char(10,cy(p))=0 560 cy(P)=INT(RND(1)*6)+6 ' Y座標をランダムに決定 570 oi=char(cx(p),cy(p)) 572 if oi<>0 then cx(p)=r1:cy(p)=t1 '他の牛、虎いたら元の座標に戻す 580 LOCATE cx(P),cy(P):PRINT"C":char(cx(p),cy(p))=1 '新座標で表示 590 IF cx(P)=X AND cy(P)=Y THEN GOTO 900 '自分のキャラ(かめ)との当たり判定。当たりなら900へ 600 GOTO 500 610 FOR G=1 TO 8 '虎 No.1からNo.8 620 LOCATE tx(G),ty(G):PRINT" ":char(tx(g),ty(g))=0:QT1=tx(G):QW1=ty(G) '虎消す 630 tx(G)=tx(G)-1 '以下636行まで移動先(他の牛、虎のいない場所)の決定 631 OI=char(tx(G),ty(G)) 632 IF OI<>0 THEN ty(G)=ty(G)-1 ELSE 640 633 OI=char(tx(G),ty(G)) 634 IF OI<>0 OR ty(g)<=5 THEN ty(G)=ty(G)+2 ELSE 640 635 OI=char(tx(G),ty(G)) 636 IF OI<>0 THEN tx(G)=tx(G)+1 ELSE 640 637 OI=char(tx(G),ty(G)) 638 IF OI<>0 THEN tx(G)=QT1: ty(G)=QW1 '移動先のない時は元の座標に 640 IF tx(G)=9 THEN 650 ELSE 665 '左端まで来た時の処理 650 tx(G)=31:ty(G)=INT(RND(1)*6)+6 660 IF ty(G)<6 THEN ty(G)=6 ELSE IF ty(G)>12 THEN ty(G)=12 662 oi=char(tx(g),ty(g)) 663 if oi<>0 then tx(g)=qt1:ty(g)=qw1 665 LOCATE tx(G),ty(G):PRINT"T":char(tx(g),ty(g))=2 '新座標の表示 670 IF tx(G)=X AND ty(G)=Y THEN 900 '自分のキャラ(かめ)との当たり判定 680 NEXT 690 RETURN
500 P = P + 1: A = A + 1
510 If P > 30 Then P = 0 '牛のNo.29を超えたらNo.0に戻す
520 If A > 3 Then A = 0: Return '3頭動かしたらリターン
525 LOCATE R(P), T(P): Print " ": char(R(P), T(P)) = 0 '牛を消す
530 R(P) = R(P) - 1 '一つ左に座標を移動
540 If R(P) < 10 Then GoTo 545 Else GoTo 580 '左端(X座標 10)まできたら右端へ
'560行まで左端に来た牛を右端へ戻す処理
545 R(P) = 31 '右端(X座標 31)
550 LOCATE 10, T(P): Print " ": char(10, T(P)) = 0
560 T(P) = Int(Rnd(1) * 6) + 6 ' Y座標をランダムに決定
580 LOCATE R(P), T(P): Print "C": char(R(P), T(P)) = 1 '新座標で表示
590 If R(P) = x And T(P) = y Then GoTo 900 '自分のキャラとの当たり判定。当たりなら900へ
600 GoTo 500
610 For G = 1 To 8 '虎 No.1から No.8
620 LOCATE QT(G), QW(G): Print " ": char(QT(G), QW(G))
= 0
630 QT(G) = QT(G) - 1
631 OI = char(QT(G), QW(G))
632 If OI = 1 Then QW(G) = QW(G) - 1 Else GoTo 640
633 OI = char(QT(G), QW(G))
634 If OI = 1 Or QW(G) <= 5 Then QW(G) = QW(G) + 2 Else GoTo
640
635 OI = char(QT(G), QW(G))
636 If OI = 1 Then QT(G) = QT(G) + 1 Else GoTo 640
640 If QT(G) = 9 Then GoTo 650 Else GoTo 660
650 QT(G) = 31: QW(G) = Int(Rnd(1) * 6) + 6
660 If QW(G) < 6 Then QW(G) = 6 Else If QW(G) > 12 Then QW(G)
= 12
665 LOCATE QT(G), QW(G): Print "T": char(QT(G), QW(G))
= 2
670 If QT(G) = x And QW(G) = y Then GoTo 900
680 Next
690 Return