BASIC (ベーシック) であそぼう 4
〜 迷路でオリエンテーリング 〜
2022-06-22 作成 福島
TOP > asob > decbasic-mazeol
[ TIPS | TOYS | OTAKU | LINK | MOVIE | CGI | AvTitle | ConfuTerm | HIST | AnSt | Asob | Shell ]

ゲームっぽいプログラムに

前章 BASIC であそぼう 3 のプログラムを変更してオリエンテーリング (もどき) ゲームを作ります。

以下の点で本物のオリエンテーリングとは異なります。


0. 事前準備

0-1. この章では、十進 BASIC を使います。
インストールがまだなら、ここ (ラズパイ400)ここ (CentOS) の gtk2 版か、
ここ (Windows10) を参考にしてインストールしておいてください。
0-2. この章では、別のテキストエディタを使いません。
十進 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. コントロールを表示するプログラムを作成する。
オリエンテーリングには「コントロール」と呼ばれる通過ポイントがいくつか設けられます。
参加者はこのコントロールを通過していき、最後にゴールします。

<テキスト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-2. コントロールを表示するプログラムを実行する。
コントロール a b c が表示されます。

キーボードの キーを押すと終了します。

キーボードの矢印キー を押して、
文字を自由に動かしてみてください。

移動できない場所が出来てしまいました。

2-3. コントロールを表示するプログラムの説明。
<テキスト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 でコントロールを迷路に埋め込んだ結果、その場所へ移動することが出来なくなってしまいました。
これは、移動先にゆかだけを許しているせいです。

ゆかだけでなくコントロールの上にも移動できるよう、プログラムを変更します。

この変更は少し高度です。
以前は、「方向キーが押されたら、その方向に移動できるか確認する」ということを行っていましたが、
今回は、「予め今の位置の左右上下に移動できるかを調査し、キーが押されたらその方向を採用する」
ということを行います。

<テキスト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-2. コントロールを踏めるプログラムの実行。
表示したコントロールを通り抜けることが出来ます。

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 = 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
X, Y, L$, c$, Z は説明用の架空の変数です。
プログラム中にはありません。

これを左右上下の 4 組も書くと、さらに読みにくくなる (=バグが出やすくなる) ので、それぞれをひとつの行にまとめています。


4. コントロールのクリア

4-1. コントロールをクリアできるプログラムの作成。
前項 3 でコントロールを通過できるようになりましたが、本物のオリエンテーリングには
以下の特徴があるので、当プログラムもそれに従う変更をします。
  • 必ずコントロールを通過しなければならない。(天候等、無理がある場合は主催者が省略を許可することもある)
  • 通過するコントロールは順番が決まっている。(テレインが広い場合は必然的にそうなる)
コントロールを通過する順番は、→ 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-2. コントロールをクリアできるプログラムの実行。
通過したコントロールが削除されます。

キーボードの キーを押すと終了します。

コントロール c を通過しても終了します。

4-3. コントロールをクリアできるプログラムの説明。
<テキスト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
この章は、ここで終了です。