ゲームっぽいプログラムに
前章 BASIC であそぼう 3 のプログラムを変更してオリエンテーリング (もどき) ゲームを作ります。
以下の点で本物のオリエンテーリングとは異なります。
- スポーツになっていない。
- テレインが迷路。(人工的)
0-1. この章では、十進 BASIC を使います。
インストールがまだなら、ここ (ラズパイ400) か ここ (CentOS) の gtk2 版か、0-2. この章では、別のテキストエディタを使いません。
ここ (Windows10) を参考にしてインストールしておいてください。
十進 BASIC には専用のエディタ画面があるので、これを使います。0-3. 未経験者向けの情報を省いています。
プログラミング未経験の方は、予めこちら (BASIC であそぼう 1) を、
アニメーションの仕組みをまだ考えたことがない方は、こちら (BASIC であそぼう 2) を
学習しておくことを推奨します。
1. 前回 BASIC であそぼう 3 - 第 3 項 のおさらい
1-1. アニメーション風に改良したプログラム
<テキスト7> では以下の様に記述していました。
これを変更していきます。
<テキスト7> ファイル名「program.BAS」
SET WINDOW 0,39,19,0 DIM heya$(7) LET heya$(1) = "+---------------+" LET heya$(2) = "| # # |" LET heya$(3) = "| ### # # ### # |" LET heya$(4) = "| # # # # # |" LET heya$(5) = "| # ####### # # |" LET heya$(6) = "| # # |" LET heya$(7) = "+---------------+" DECLARE EXTERNAL SUB HeyaDisplay CALL HeyaDisplay(heya$, 2, 2) DECLARE EXTERNAL SUB BogusTick BogusTick_before = -1 ! 自分の横位置、縦位置 LET x = 2 LET y = 2 DO CALL BogusTick(BogusTick_before, 10) IF GetKeyState(27) < 0 THEN EXIT DO IF GetKeyState(39) < 0 AND mid$(heya$(y + 0), x + 1, 1) = " " THEN LET x = x + 1 IF GetKeyState(37) < 0 AND mid$(heya$(y + 0), x - 1, 1) = " " THEN LET x = x - 1 IF GetKeyState(40) < 0 AND mid$(heya$(y + 1), x + 0, 1) = " " THEN LET y = y + 1 IF GetKeyState(38) < 0 AND mid$(heya$(y - 1), x + 0, 1) = " " THEN LET y = y - 1 CALL HeyaDisplay(heya$, x, y) LOOP END
! 部屋を表示する副プログラム EXTERNAL SUB HeyaDisplay(heya$(), x, y) SET DRAW MODE Hidden CLEAR SET COLOR 1 FOR tate = 1 TO 7 LET gyou$ = heya$(tate) FOR yoko = 1 TO 17 LET kabe$ = mid$(gyou$, yoko, 1) PLOT TEXT ,AT yoko,tate:kabe$ NEXT yoko NEXT tate SET COLOR 1 PLOT TEXT ,AT x,y:"A" SET DRAW MODE Explicit END SUB
! BogusTick version 1.0 written by fuku@rouge.gr.jp EXTERNAL SUB BogusTick(before, fps) IF before >= 0 AND fps > 0 THEN LET current = TIME IF before > current THEN LET before = before - 24 * 3600 LET this_wait = 1 / fps - (current - before) IF this_wait > 0 THEN WAIT DELAY this_wait END IF LET before = TIME END SUB
2. コントロールの表示
2-1. コントロールを表示するプログラムを作成する。
オリエンテーリングには「コントロール」と呼ばれる通過ポイントがいくつか設けられます。2-2. コントロールを表示するプログラムを実行する。
参加者はこのコントロールを通過していき、最後にゴールします。
<テキスト8> ファイル名「program.BAS」
SET WINDOW 0,39,19,0 DIM heya$(7) LET heya$(1) = "+---------------+" LET heya$(2) = "| # # |" LET heya$(3) = "| ### # # ### # |" LET heya$(4) = "| # # # # # |" LET heya$(5) = "| # ####### # # |" LET heya$(6) = "| # # |" LET heya$(7) = "+---------------+" ! X, Y, Mark コントロールの場所と記号 DATA 2, 5,"a" DATA 10, 6,"b" DATA 16, 2,"c" DIM Controls$(3,3) MAT READ Controls$ ! コントロールを迷路に埋め込む FOR Mokuhyo = 1 TO 3 LET mx = VAL(Controls$(Mokuhyo, 1)) LET my = VAL(Controls$(Mokuhyo, 2)) LET mm$ = Controls$(Mokuhyo, 3) LET heya$(my)(mx:mx) = mm$ NEXT Mokuhyo ! 自分の横位置、縦位置 LET x = 2 LET y = 2 DECLARE EXTERNAL SUB HeyaDisplay CALL HeyaDisplay(heya$, x, y) DECLARE EXTERNAL SUB BogusTick BogusTick_before = -1 DO CALL BogusTick(BogusTick_before, 10) IF GetKeyState(27) < 0 THEN EXIT DO IF GetKeyState(39) < 0 AND mid$(heya$(y + 0), x + 1, 1) = " " THEN LET x = x + 1 IF GetKeyState(37) < 0 AND mid$(heya$(y + 0), x - 1, 1) = " " THEN LET x = x - 1 IF GetKeyState(40) < 0 AND mid$(heya$(y + 1), x + 0, 1) = " " THEN LET y = y + 1 IF GetKeyState(38) < 0 AND mid$(heya$(y - 1), x + 0, 1) = " " THEN LET y = y - 1 CALL HeyaDisplay(heya$, x, y) LOOP END
! 部屋を表示する副プログラム EXTERNAL SUB HeyaDisplay(heya$(), x, y) SET DRAW MODE Hidden CLEAR SET COLOR 1 FOR tate = 1 TO 7 LET gyou$ = heya$(tate) FOR yoko = 1 TO 17 LET kabe$ = mid$(gyou$, yoko, 1) PLOT TEXT ,AT yoko,tate:kabe$ NEXT yoko NEXT tate SET COLOR 1 PLOT TEXT ,AT x,y:"A" SET DRAW MODE Explicit END SUB
! BogusTick version 1.0 written by fuku@rouge.gr.jp EXTERNAL SUB BogusTick(before, fps) IF before >= 0 AND fps > 0 THEN LET current = TIME IF before > current THEN LET before = before - 24 * 3600 LET this_wait = 1 / fps - (current - before) IF this_wait > 0 THEN WAIT DELAY this_wait END IF LET before = TIME END SUB
2-3. コントロールを表示するプログラムの説明。コントロール a b c が表示されます。
キーボードの キーを押すと終了します。
キーボードの矢印キー を押して、
文字を自由に動かしてみてください。
移動できない場所が出来てしまいました。
<テキスト8> ファイル名「program.BAS」
SET WINDOW 0,39,19,0 DIM heya$(7) LET heya$(1) = "+---------------+" LET heya$(2) = "| # # |" LET heya$(3) = "| ### # # ### # |" LET heya$(4) = "| # # # # # |" LET heya$(5) = "| # ####### # # |" LET heya$(6) = "| # # |" LET heya$(7) = "+---------------+" ! X, Y, Mark コントロールの場所と記号 DATA 2, 5,"a" ! 1 個目の横位置、縦位置、記号(a) DATA 10, 6,"b" ! 2 個目の横位置、縦位置、記号(b) DATA 16, 2,"c" ! 3 個目の横位置、縦位置、記号(c) DIM Controls$(3,3) ! 2 次元配列 (3 × 3) を Controls$ という名前で用意する。 MAT READ Controls$ ! コントロールの場所と記号を Controls$(3,3) に読み込む。 ! ↑ こうすることにより、以下の様にそれぞれを取り出せるようにします。 ! Controls$(1,1) -- 1 個目の横位置 ! Controls$(1,2) -- 1 個目の縦位置 ! Controls$(1,3) -- 1 個目の記号 ! Controls$(2,1) -- 2 個目の横位置 ! ~ ! Controls$(3,3) -- 3 個目の記号 ! コントロールを迷路に埋め込む FOR Mokuhyo = 1 TO 3 ! 1 ~ 3 個目のコントロールすべてが対象。 LET mx = VAL(Controls$(Mokuhyo, 1)) ! 横位置を取り出す。 LET my = VAL(Controls$(Mokuhyo, 2)) ! 縦位置を取り出す。 LET mm$ = Controls$(Mokuhyo, 3) ! 記号を取り出す。 LET heya$(my)(mx:mx) = mm$ ! 取り出した横位置、縦位置に記号を埋め込む。 NEXT Mokuhyo ! 自分の横位置、縦位置 LET x = 2 ! HeyaDisplay() の 2, 2 と同じ意味なので、 LET y = 2 ! 定義をこの行 (HeyaDisplay() より前) に移動し、HeyaDisplay() の 2, 2 を x, y として利用。 DECLARE EXTERNAL SUB HeyaDisplay CALL HeyaDisplay(heya$,x, y) ! 固定値 2, 2 をそれぞれ x, y に変更。 DECLARE EXTERNAL SUB BogusTick BogusTick_before = -1 DO CALL BogusTick(BogusTick_before, 10) IF GetKeyState(27) < 0 THEN EXIT DO IF GetKeyState(39) < 0 AND mid$(heya$(y + 0), x + 1, 1) = " " THEN LET x = x + 1 IF GetKeyState(37) < 0 AND mid$(heya$(y + 0), x - 1, 1) = " " THEN LET x = x - 1 IF GetKeyState(40) < 0 AND mid$(heya$(y + 1), x + 0, 1) = " " THEN LET y = y + 1 IF GetKeyState(38) < 0 AND mid$(heya$(y - 1), x + 0, 1) = " " THEN LET y = y - 1 CALL HeyaDisplay(heya$, x, y) LOOP END
! 部屋を表示する副プログラム EXTERNAL SUB HeyaDisplay(heya$(), x, y) SET DRAW MODE Hidden CLEAR SET COLOR 1 FOR tate = 1 TO 7 LET gyou$ = heya$(tate) FOR yoko = 1 TO 17 LET kabe$ = mid$(gyou$, yoko, 1) PLOT TEXT ,AT yoko,tate:kabe$ NEXT yoko NEXT tate SET COLOR 1 PLOT TEXT ,AT x,y:"A" SET DRAW MODE Explicit END SUB
! BogusTick version 1.0 written by fuku@rouge.gr.jp EXTERNAL SUB BogusTick(before, fps) IF before >= 0 AND fps > 0 THEN LET current = TIME IF before > current THEN LET before = before - 24 * 3600 LET this_wait = 1 / fps - (current - before) IF this_wait > 0 THEN WAIT DELAY this_wait END IF LET before = TIME END SUB
3. コントロールの通過
3-1. コントロールを踏めるプログラムの作成。
前項 2 でコントロールを迷路に埋め込んだ結果、その場所へ移動することが出来なくなってしまいました。3-2. コントロールを踏めるプログラムの実行。
これは、移動先にゆかだけを許しているせいです。
ゆかだけでなくコントロールの上にも移動できるよう、プログラムを変更します。
この変更は少し高度です。
以前は、「方向キーが押されたら、その方向に移動できるか確認する」ということを行っていましたが、
今回は、「予め今の位置の左右上下に移動できるかを調査し、キーが押されたらその方向を採用する」
ということを行います。
<テキスト9> ファイル名「program.BAS」
SET WINDOW 0,39,19,0 DIM heya$(7) LET heya$(1) = "+---------------+" LET heya$(2) = "| # # |" LET heya$(3) = "| ### # # ### # |" LET heya$(4) = "| # # # # # |" LET heya$(5) = "| # ####### # # |" LET heya$(6) = "| # # |" LET heya$(7) = "+---------------+" ! X, Y, Mark コントロールの場所と記号 DATA 2, 5,"a" DATA 10, 6,"b" DATA 16, 2,"c" DIM Controls$(3,3) MAT READ Controls$ ! コントロールを迷路に埋め込む FOR Mokuhyo = 1 TO 3 LET mx = VAL(Controls$(Mokuhyo, 1)) LET my = VAL(Controls$(Mokuhyo, 2)) LET mm$ = Controls$(Mokuhyo, 3) LET heya$(my)(mx:mx) = mm$ NEXT Mokuhyo ! 自分の横位置、縦位置 LET x = 2 LET y = 2 DECLARE EXTERNAL SUB HeyaDisplay CALL HeyaDisplay(heya$, x, y) DECLARE EXTERNAL SUB BogusTick BogusTick_before = -1 DECLARE EXTERNAL SUB Search DO CALL BogusTick(BogusTick_before, 10) IF GetKeyState(27) < 0 THEN EXIT DO DIM idou(4) CALL Search(idou, heya$, x, y) dx = 0 dy = 0 IF GetKeyState(39) < 0 THEN LET dx = idou(1) IF GetKeyState(37) < 0 THEN LET dx = idou(2) IF GetKeyState(40) < 0 THEN LET dy = idou(3) IF GetKeyState(38) < 0 THEN LET dy = idou(4) x = x + dx y = y + dy CALL HeyaDisplay(heya$, x, y) LOOP END
! 部屋を表示する副プログラム EXTERNAL SUB HeyaDisplay(heya$(), x, y) SET DRAW MODE Hidden CLEAR SET COLOR 1 FOR tate = 1 TO 7 LET gyou$ = heya$(tate) FOR yoko = 1 TO 17 LET kabe$ = mid$(gyou$, yoko, 1) PLOT TEXT ,AT yoko,tate:kabe$ NEXT yoko NEXT tate SET COLOR 1 PLOT TEXT ,AT x,y:"A" SET DRAW MODE Explicit END SUB
! BogusTick version 1.0 written by fuku@rouge.gr.jp EXTERNAL SUB BogusTick(before, fps) IF before >= 0 AND fps > 0 THEN LET current = TIME IF before > current THEN LET before = before - 24 * 3600 LET this_wait = 1 / fps - (current - before) IF this_wait > 0 THEN WAIT DELAY this_wait END IF LET before = TIME END SUB
! 周囲を調査する副プログラム EXTERNAL SUB Search(idou(),heya$(),cx,cy) LET ikeru$ = " abc" MAT idou = ZER IF POS(ikeru$, mid$(heya$(cy + 0), cx + 1,1)) > 0 THEN LET idou(1) = +1 IF POS(ikeru$, mid$(heya$(cy + 0), cx - 1,1)) > 0 THEN LET idou(2) = -1 IF POS(ikeru$, mid$(heya$(cy + 1), cx + 0,1)) > 0 THEN LET idou(3) = +1 IF POS(ikeru$, mid$(heya$(cy - 1), cx + 0,1)) > 0 THEN LET idou(4) = -1 END SUB
3-3. コントロールを踏めるプログラムの説明。表示したコントロールを通り抜けることが出来ます。
<テキスト9> ファイル名「program.BAS」
SET WINDOW 0,39,19,0 DIM heya$(7) LET heya$(1) = "+---------------+" LET heya$(2) = "| # # |" LET heya$(3) = "| ### # # ### # |" LET heya$(4) = "| # # # # # |" LET heya$(5) = "| # ####### # # |" LET heya$(6) = "| # # |" LET heya$(7) = "+---------------+" ! X, Y, Mark コントロールの場所と記号 DATA 2, 5,"a" DATA 10, 6,"b" DATA 16, 2,"c" DIM Controls$(3,3) MAT READ Controls$ ! コントロールを迷路に埋め込む FOR Mokuhyo = 1 TO 3 LET mx = VAL(Controls$(Mokuhyo, 1)) LET my = VAL(Controls$(Mokuhyo, 2)) LET mm$ = Controls$(Mokuhyo, 3) LET heya$(my)(mx:mx) = mm$ NEXT Mokuhyo ! 自分の横位置、縦位置 LET x = 2 LET y = 2 DECLARE EXTERNAL SUB HeyaDisplay CALL HeyaDisplay(heya$, x, y) DECLARE EXTERNAL SUB BogusTick BogusTick_before = -1 ! 副プログラムの使用予告 DECLARE EXTERNAL SUB Search DO CALL BogusTick(BogusTick_before, 10) IF GetKeyState(27) < 0 THEN EXIT DO DIM idou(4) ! 副プログラム Search() の調査結果を格納する配列変数を用意。 CALL Search(idou, heya$, x, y) ! 自分の周囲を調査する。 dx = 0 ! 横の移動量 (-1, 0, +1) を 0 (移動しない) にしておく。 dy = 0 ! 縦の移動量 (-1, 0, +1) を 0 (移動しない) にしておく。 IF GetKeyState(39) < 0 THEN LET dx = idou(1) ! が押されたら dx に +1 (または 0) を入れる。 IF GetKeyState(37) < 0 THEN LET dx = idou(2) ! が押されたら dx に -1 (または 0) を入れる。 IF GetKeyState(40) < 0 THEN LET dy = idou(3) ! が押されたら dy に +1 (または 0) を入れる。 IF GetKeyState(38) < 0 THEN LET dy = idou(4) ! が押されたら dy に -1 (または 0) を入れる。 x = x + dx ! 横位置に横の移動量 (-1, 0, +1) を加える。 y = y + dy ! 縦位置に縦の移動量 (-1, 0, +1) を加える。 CALL HeyaDisplay(heya$, x, y) LOOP END
! 部屋を表示する副プログラム EXTERNAL SUB HeyaDisplay(heya$(), x, y) SET DRAW MODE Hidden CLEAR SET COLOR 1 FOR tate = 1 TO 7 LET gyou$ = heya$(tate) FOR yoko = 1 TO 17 LET kabe$ = mid$(gyou$, yoko, 1) PLOT TEXT ,AT yoko,tate:kabe$ NEXT yoko NEXT tate SET COLOR 1 PLOT TEXT ,AT x,y:"A" SET DRAW MODE Explicit END SUB
! BogusTick version 1.0 written by fuku@rouge.gr.jp EXTERNAL SUB BogusTick(before, fps) IF before >= 0 AND fps > 0 THEN LET current = TIME IF before > current THEN LET before = before - 24 * 3600 LET this_wait = 1 / fps - (current - before) IF this_wait > 0 THEN WAIT DELAY this_wait END IF LET before = TIME END SUB
! 周囲を調査する副プログラム*1 EXTERNAL SUB Search(idou(),heya$(),cx,cy) LET ikeru$ = " abc" ! 移動できるゆか。このどれかに周りの印が該当すれば移動できる。 MAT idou = ZER ! 調査結果を格納する配列変数を 0 で埋める。 IF POS(ikeru$, mid$(heya$(cy + 0), cx + 1,1)) > 0 THEN LET idou(1) = +1 ! 右に移動できそうなら調査結果(1) に +1 を入れる。 IF POS(ikeru$, mid$(heya$(cy + 0), cx - 1,1)) > 0 THEN LET idou(2) = -1 ! 左に移動できそうなら調査結果(2) に -1 を入れる。 IF POS(ikeru$, mid$(heya$(cy + 1), cx + 0,1)) > 0 THEN LET idou(3) = +1 ! 下に移動できそうなら調査結果(3) に +1 を入れる。 IF POS(ikeru$, mid$(heya$(cy - 1), cx + 0,1)) > 0 THEN LET idou(4) = -1 ! 上に移動できそうなら調査結果(4) に -1 を入れる。 END SUB
*1周囲を調査する副プログラム Search() について
関数 POS(s,c)*2 は文字列 s から文字列 c を探して、見つかった位置を返します。
見つからない場合は 0 を返します。
*2「関数」についてはあとで説明します。今は「便利な機能」と覚えてください。
少し読みにくい記述にしていますが、上記のひとつ (アンダーラインのところ) を展開すると、
このようになります。↓
X, Y, L$, c$, Z は説明用の架空の変数です。
X = cx + 1 ! 右のゆかについて調査する。 Y = cy + 0 L$ = heya$(Y) c$ = mid$(L$,X, 1) Z = POS(" abc", c$) ! c$ が " abc" にあれば Z に 1,2,3,4 のどれかが入る。(なければ 0 が入る) IF Z > 0 THEN LET idou(1) = +1 ! 移動できる。 END IF
プログラム中にはありません。
これを左右上下の 4 組も書くと、さらに読みにくくなる (=バグが出やすくなる) ので、それぞれをひとつの行にまとめています。
4. コントロールのクリア
4-1. コントロールをクリアできるプログラムの作成。この章は、ここで終了です。
前項 3 でコントロールを通過できるようになりましたが、本物のオリエンテーリングには4-2. コントロールをクリアできるプログラムの実行。
以下の特徴があるので、当プログラムもそれに従う変更をします。
コントロールを通過する順番は、→ a → b → c の順とし、c に移動したらプログラムを終了させます。
- 必ずコントロールを通過しなければならない。(天候等、無理がある場合は主催者が省略を許可することもある)
- 通過するコントロールは順番が決まっている。(テレインが広い場合は必然的にそうなる)
また、通過済みのコントロールは、それが見て分かるように削除する (ゆかの記号で上書きする) ことにします。
(本物のオリエンテーリングではコントロールを破壊してはいけません。通過するときに付属のハンコで自分の紙カードにパンチします)
<テキスト10> ファイル名「program.BAS」
SET WINDOW 0,39,19,0 DIM heya$(7) LET heya$(1) = "+---------------+" LET heya$(2) = "| # # |" LET heya$(3) = "| ### # # ### # |" LET heya$(4) = "| # # # # # |" LET heya$(5) = "| # ####### # # |" LET heya$(6) = "| # # |" LET heya$(7) = "+---------------+" ! X, Y, Mark コントロールの場所と記号 DATA 2, 5,"a" DATA 10, 6,"b" DATA 16, 2,"c" DIM Controls$(3,3) MAT READ Controls$ ! コントロールを迷路に埋め込む FOR Mokuhyo = 1 TO 3 LET mx = VAL(Controls$(Mokuhyo, 1)) LET my = VAL(Controls$(Mokuhyo, 2)) LET mm$ = Controls$(Mokuhyo, 3) LET heya$(my)(mx:mx) = mm$ NEXT Mokuhyo ! 自分の横位置、縦位置 LET x = 2 LET y = 2 DECLARE EXTERNAL SUB HeyaDisplay CALL HeyaDisplay(heya$, x, y) DECLARE EXTERNAL SUB BogusTick BogusTick_before = -1 DECLARE EXTERNAL SUB Search Mokuhyo = 1 LET mx = VAL(Controls$(Mokuhyo, 1)) LET my = VAL(Controls$(Mokuhyo, 2)) LET mm$ = Controls$(Mokuhyo, 3) DO CALL BogusTick(BogusTick_before, 10) IF GetKeyState(27) < 0 THEN EXIT DO DIM idou(4) CALL Search(idou, heya$, x, y) dx = 0 dy = 0 IF GetKeyState(39) < 0 THEN LET dx = idou(1) IF GetKeyState(37) < 0 THEN LET dx = idou(2) IF GetKeyState(40) < 0 THEN LET dy = idou(3) IF GetKeyState(38) < 0 THEN LET dy = idou(4) x = x + dx y = y + dy CALL HeyaDisplay(heya$, x, y) IF x = mx AND y = my THEN IF mm$ = "c" THEN EXIT DO LET heya$(my)(mx:mx) = " " Mokuhyo = Mokuhyo + 1 LET mx = VAL(Controls$(Mokuhyo, 1)) LET my = VAL(Controls$(Mokuhyo, 2)) LET mm$ = Controls$(Mokuhyo, 3) END IF LOOP END
! 部屋を表示する副プログラム EXTERNAL SUB HeyaDisplay(heya$(), x, y) SET DRAW MODE Hidden CLEAR SET COLOR 1 FOR tate = 1 TO 7 LET gyou$ = heya$(tate) FOR yoko = 1 TO 17 LET kabe$ = mid$(gyou$, yoko, 1) PLOT TEXT ,AT yoko,tate:kabe$ NEXT yoko NEXT tate SET COLOR 1 PLOT TEXT ,AT x,y:"A" SET DRAW MODE Explicit END SUB
! BogusTick version 1.0 written by fuku@rouge.gr.jp EXTERNAL SUB BogusTick(before, fps) IF before >= 0 AND fps > 0 THEN LET current = TIME IF before > current THEN LET before = before - 24 * 3600 LET this_wait = 1 / fps - (current - before) IF this_wait > 0 THEN WAIT DELAY this_wait END IF LET before = TIME END SUB
! 周囲を調査する副プログラム EXTERNAL SUB Search(idou(),heya$(),cx,cy) LET ikeru$ = " abc" MAT idou = ZER IF POS(ikeru$, mid$(heya$(cy + 0), cx + 1,1)) > 0 THEN LET idou(1) = +1 IF POS(ikeru$, mid$(heya$(cy + 0), cx - 1,1)) > 0 THEN LET idou(2) = -1 IF POS(ikeru$, mid$(heya$(cy + 1), cx + 0,1)) > 0 THEN LET idou(3) = +1 IF POS(ikeru$, mid$(heya$(cy - 1), cx + 0,1)) > 0 THEN LET idou(4) = -1 END SUB
4-3. コントロールをクリアできるプログラムの説明。通過したコントロールが削除されます。
キーボードの キーを押すと終了します。
コントロール c を通過しても終了します。
<テキスト10> ファイル名「program.BAS」
SET WINDOW 0,39,19,0 DIM heya$(7) LET heya$(1) = "+---------------+" LET heya$(2) = "| # # |" LET heya$(3) = "| ### # # ### # |" LET heya$(4) = "| # # # # # |" LET heya$(5) = "| # ####### # # |" LET heya$(6) = "| # # |" LET heya$(7) = "+---------------+" ! X, Y, Mark コントロールの場所と記号 DATA 2, 5,"a" DATA 10, 6,"b" DATA 16, 2,"c" DIM Controls$(3,3) MAT READ Controls$ ! コントロールを迷路に埋め込む FOR Mokuhyo = 1 TO 3 LET mx = VAL(Controls$(Mokuhyo, 1)) LET my = VAL(Controls$(Mokuhyo, 2)) LET mm$ = Controls$(Mokuhyo, 3) LET heya$(my)(mx:mx) = mm$ NEXT Mokuhyo ! 自分の横位置、縦位置 LET x = 2 LET y = 2 DECLARE EXTERNAL SUB HeyaDisplay CALL HeyaDisplay(heya$, x, y) DECLARE EXTERNAL SUB BogusTick BogusTick_before = -1 DECLARE EXTERNAL SUB Search ! 最初に目指すコントロールの定義 (あとで自分の位置と比較する) Mokuhyo = 1 ! 1 番のコントロールを取り出すための索引 LET mx = VAL(Controls$(Mokuhyo, 1)) ! 索引 (1 番目) に従って横位置を取り出しておく LET my = VAL(Controls$(Mokuhyo, 2)) ! 索引 (1 番目) に従って縦位置を取り出しておく LET mm$ = Controls$(Mokuhyo, 3) ! 索引 (1 番目) に従って記号を取り出しておく DO CALL BogusTick(BogusTick_before, 10) IF GetKeyState(27) < 0 THEN EXIT DO DIM idou(4) CALL Search(idou, heya$, x, y) dx = 0 dy = 0 IF GetKeyState(39) < 0 THEN LET dx = idou(1) IF GetKeyState(37) < 0 THEN LET dx = idou(2) IF GetKeyState(40) < 0 THEN LET dy = idou(3) IF GetKeyState(38) < 0 THEN LET dy = idou(4) x = x + dx y = y + dy CALL HeyaDisplay(heya$, x, y) IF x = mx AND y = my THEN ! 自分の横位置と縦位置が記号の位置と同じかどうか比較する。 IF mm$ = "c" THEN EXIT DO ! 記号が c なら繰り返しから抜け出す。(プログラムを終了する) LET heya$(my)(mx:mx) = " " ! 記号と重なったので、その場所をゆかの記号で上書きする。 Mokuhyo = Mokuhyo + 1 ! 次に目指すコントロールのために索引を 1 つ進める。 LET mx = VAL(Controls$(Mokuhyo, 1)) ! 索引に従って横位置を取り出しておく LET my = VAL(Controls$(Mokuhyo, 2)) ! 索引に従って縦位置を取り出しておく LET mm$ = Controls$(Mokuhyo, 3) ! 索引に従って記号を取り出しておく END IF LOOP END
! 部屋を表示する副プログラム EXTERNAL SUB HeyaDisplay(heya$(), x, y) SET DRAW MODE Hidden CLEAR SET COLOR 1 FOR tate = 1 TO 7 LET gyou$ = heya$(tate) FOR yoko = 1 TO 17 LET kabe$ = mid$(gyou$, yoko, 1) PLOT TEXT ,AT yoko,tate:kabe$ NEXT yoko NEXT tate SET COLOR 1 PLOT TEXT ,AT x,y:"A" SET DRAW MODE Explicit END SUB
! BogusTick version 1.0 written by fuku@rouge.gr.jp EXTERNAL SUB BogusTick(before, fps) IF before >= 0 AND fps > 0 THEN LET current = TIME IF before > current THEN LET before = before - 24 * 3600 LET this_wait = 1 / fps - (current - before) IF this_wait > 0 THEN WAIT DELAY this_wait END IF LET before = TIME END SUB
! 周囲を調査する副プログラム EXTERNAL SUB Search(idou(),heya$(),cx,cy) LET ikeru$ = " abc" MAT idou = ZER IF POS(ikeru$, mid$(heya$(cy + 0), cx + 1,1)) > 0 THEN LET idou(1) = +1 IF POS(ikeru$, mid$(heya$(cy + 0), cx - 1,1)) > 0 THEN LET idou(2) = -1 IF POS(ikeru$, mid$(heya$(cy + 1), cx + 0,1)) > 0 THEN LET idou(3) = +1 IF POS(ikeru$, mid$(heya$(cy - 1), cx + 0,1)) > 0 THEN LET idou(4) = -1 END SUB