GUST NOTCH? DIARY

スタートレックのソースを読む その11

その10からの続きです。

  • コンピュータ


4630 IF D[8] >= 0 THEN 4660
4640 PRINT "COMPUTER DISABLED"
4650 GOTO 1270
4660 PRINT "COMPUTER ACTIVE AND AWAITING COMMAND";
4670 INPUT A
4680 GOTO A+1 OF 4740,4830,4880
4690 PRINT "FUNCTIONS AVAILABLE FROM COMPUTER"
4700 PRINT " 0 = CUMULATIVE GALACTIC RECORD"
4710 PRINT " 1 = STATUS REPORT"
4720 PRINT " 2 = PHOTON TORPEDO DATA"
4730 GOTO 4660
4740 PRINT USING 4750;Q1,Q2
4750 IMAGE "COMPUTER RECORD OF GALAXY FOR QUADRANT ",D,",",D
4760 PRINT USING 5330
4770 PRINT USING 5360
4780 FOR I=1 TO 8
4790 PRINT USING 5350;I,Z[I,1],Z[I,2],Z[I,3],Z[I,4],Z[I,5],Z[I,6],Z[I,7],Z[I,8]
4800 PRINT USING 5360
4810 NEXT I
4820 GOTO 1270
4830 PRINT "\012 STATUS REPORT\012"
4840 PRINT "NUMBER OF KLINGONS LEFT ="K9
4850 PRINT "NUMBER OF STARDATES LEFT ="(T0+T9)-T
4860 PRINT "NUMBER OF STARBASES LEFT ="B9
4870 GOTO 3560
4880 PRINT
4890 H8=0
4900 FOR I=1 TO 3
4910 IF K[I,3] <= 0 THEN 5260
4920 C1=S1
4930 A=S2
4940 W1=K[I,1]
4950 X=K[I,2]
4960 GOTO 5010
4970 PRINT USING 4980;Q1,Q2,S1,S2
4980 IMAGE "YOU ARE AT QUADRANT ( ",D,",",D," ) SECTOR ( ",D,",",D," )"
4990 PRINT "SHIP'S & TARGET'S COORDINATES ARE";
5000 INPUT C1,A,W1,X
5010 X=X-A
5020 A=C1-W1
5030 IF X<0 THEN 5130
5040 IF A<0 THEN 5190
5050 IF X>0 THEN 5070
5060 IF A=0 THEN 5150
5070 C1=1
5080 IF ABS(A) <= ABS(X) THEN 5110
5090 PRINT "DIRECTION ="C1+(((ABS(A)-ABS(X))+ABS(A))/ABS(A))
5100 GOTO 5240
5110 PRINT "DIRECTION ="C1+(ABS(A)/ABS(X))
5120 GOTO 5240
5130 IF A>0 THEN 5170
5140 IF X=0 THEN 5190
5150 C1=5
5160 GOTO 5080
5170 C1=3
5180 GOTO 5200
5190 C1=7
5200 IF ABS(A) >= ABS(X) THEN 5230
5210 PRINT "DIRECTION ="C1+(((ABS(X)-ABS(A))+ABS(X))/ABS(X))
5220 GOTO 5240
5230 PRINT "DIRECTION ="C1+(ABS(X)/ABS(A))
5240 PRINT "DISTANCE ="(SQR(X^2+A^2))
5250 IF H8=1 THEN 5320
5260 NEXT I
5270 H8=0
5280 PRINT "DO YOU WANT TO USE THE CALCULATOR";
5290 INPUT A$
5300 IF A$="YES" THEN 4970
5310 IF A$ <> "NO" THEN 5280
5320 GOTO 1270
5330 IMAGE " 1 2 3 4 5 6 7 8"
5340 IMAGE "---------------------------------------------------"
5350 IMAGE D,8(3X,3D)
5360 IMAGE " ----- ----- ----- ----- ----- ----- ----- -----"
5370 IMAGE " WARP ENGINES SHUTDOWN AT SECTOR ",D,",",D," DUE TO BAD NAVIGATION"
5380 R1=INT(RND(1)*8+1)
5390 R2=INT(RND(1)*8+1)
5400 A$=" "
5410 Z1=R1
5420 Z2=R2
5430 GOSUB 5680
5440 IF Z3=0 THEN 5380
5450 RETURN
5460 FOR I=1 TO 11
5470 PRINT
5480 NEXT I
5490 PRINT
5500 RETURN

コンピュータの機能は3つあります。

    • 銀河系地図の表示
    • ステータスレポート
    • コース計算

まず、コンピュータが故障中であるかを確認します。
故障している場合は、故障中のメッセージを表示してコマンド入力待ちに戻ります。(4630行から4650行)
故障していない場合はコンピュータのコマンド入力待ちに移ります。
4670行で A にコマンド番号を保持します(4670行)。入力された番号の値に応じて分岐します(4680行)。範囲外の値が入力された場合は、コマンドの説明を表示して、コンピュータのコマンド入力に戻ります。

銀河系地図の表示は4740行から4820行です。表示だけして、コマンド入力待ちに戻ります。
こんな感じの出力になるはずです。数字は省略して"xxx"にしてます。ここで表示しているのは、Gの情報ではなくZの情報です。ですので、長距離センサでスキャンした範囲しか表示されないはずです。
それ以外のところは初期値の0が入っているはずなので、「0」と表示されるのか「000」と表示されるのかはちょっとわかりません。


1 2 3 4 5 6 7 8

                                                                                                    • -

1 xxx xxx xxx xxx xxx xxx xxx xxx
----- ----- ----- ----- ----- ----- ----- -----
2 xxx xxx xxx xxx xxx xxx xxx xxx
----- ----- ----- ----- ----- ----- ----- -----
3 xxx xxx xxx xxx xxx xxx xxx xxx
----- ----- ----- ----- ----- ----- ----- -----
4 xxx xxx xxx xxx xxx xxx xxx xxx
----- ----- ----- ----- ----- ----- ----- -----
5 xxx xxx xxx xxx xxx xxx xxx xxx
----- ----- ----- ----- ----- ----- ----- -----
6 xxx xxx xxx xxx xxx xxx xxx xxx
----- ----- ----- ----- ----- ----- ----- -----
7 xxx xxx xxx xxx xxx xxx xxx xxx
----- ----- ----- ----- ----- ----- ----- -----
8 xxx xxx xxx xxx xxx xxx xxx xxx

                                                                                                    • -

ステータスレポートは、4830行から4870行の処理です。
以下のものが表示されます。

    • 残りのクリンゴン
    • 残りの年数
    • 銀河系内の基地数
    • 各計器の故障状況

表示しているだけです。計器の故障状況は、3560行からのダメージ制御のルーチンが使われます。つまり、ダメージ制御が壊れている場合は、ここでも表示できません。

4880行からがコース計算です。以下のことを行います。

    • クリンゴンがいる場合は各クリンゴンのいる方向(1-9)と距離を示します
    • コース計算機があるので、これを使用するかどうかを確認します

つまり、短距離センサが故障していても、コンピュータが生きていれば座標がわかるのです。

4890行で H8 という変数がでてきますが、何を初期化しているのか不明です。具体的にH8が0以外になることはないのです。H はフェーザやクリンゴンの攻撃エネルギーを計算する際に使われていましたが、エネルギー関係の何か処理があったのでしょうか?

4900行から5260行で各クリンゴンの方向を求めています。なぜか変数を使いまわしていて、(C1,A)=(S1,S2)から(W1,X)=(K[I,1],K[I,2])への座標を求めます。
4960行で5010行にスキップするのは、4970行から5000行は、コース計算機として使う場合に二点間の座標を入力する処理があり、その後の処理は共通なためです。

5010行から5230行で、二点の座標から求めた方向を、1から9の値に変換します。
条件分岐がややこしいのですが、やっていることは以下のことです。
まずX方向、Y方向の成分を求めます。(5010行、5020行)
ここで注意しないといけないのは、X=K[I,2]-S2, A=S1-K[I,1] なので、座標(X,A)は右側がX軸で上側がY軸の座標系に変換されています。その上で、4つの象限のうち、どの象限にあるかで、基準となるコース C1 を決めます。

    • 第一象限(右上)を向いている場合(X>0,A>=0): C1=1
      • ABS(A) < ABS(X) ならば(1から2の間ならば)、C1+(ABS(A)/ABS(X))
      • ABS(A) >= ABS(X) ならば(2から3の間ならば)、C1+(((ABS(A)-ABS(X))+ABS(A))/ABS(A))
    • 第二象限(左上)を向いている場合(X<=0,A>0): C1=3
      • ABS(A) > ABS(X) ならば(3から4の間ならば)、C1+(ABS(X)/ABS(A))
      • ABS(A) <= ABS(X) ならば(4から5の間ならば)、C1+(((ABS(X)-ABS(A))+ABS(X))/ABS(X))
    • 第三象限(左下)を向いている場合(X<0,A<=0): C1=5
      • ABS(A) < ABS(X) ならば(5から6の間ならば)、C1+(ABS(A)/ABS(X))
      • ABS(A) >= ABS(X) ならば(6から7の間ならば)、C1+(((ABS(A)-ABS(X))+ABS(A))/ABS(A))
    • 第四象限(右下)を向いている場合(X>=0,A<0): C1=7
      • ABS(A) > ABS(X) ならば(7から8の間ならば)、C1+(ABS(X)/ABS(A))
      • ABS(A) <= ABS(X) ならば(8から9の間ならば)、C1+(((ABS(X)-ABS(A))+ABS(X))/ABS(X))

ABS()は絶対値を求める関数でプチコンにもあります。*1

5240行までで、方向と距離が表示されます。
5250行で H8 の値を調べていますが、H8 が1になることはありません。

最後にコース計算を行うかの入力待ちです。"YES"の場合は4970行からの処理に移り、移動元座標と移動先座標の入力を行うと、方向と距離が表示され、コース計算を行うかの入力待ちに戻ってきます。
コース計算を行わない場合は"NO"を入力します。その場合、コマンド入力待ちのところへ戻ります。
それ以外の文字列が入力された場合は、コース計算を行うかの確認に戻ります。

ここで、コース計算を行う場合4970行に飛びますが、実はここはFOR..NEXTの間です。プチコンでは、FORの初期化なしでNEXTがくるのはエラーになるようです。
ですので、ここはコース計算の部分をサブルーチンにしてしまうといいでしょう。


FOR I=0 TO 2
'エンタープライズクリンゴンの座標設定
GOSUB @CALC_DIR
NEXT
@USE_CALC
'計算機を使う?
IF A$=="NO" THEN GOTO @COMMAND
IF A$!="YES" THEN @USE_CALC
'座標入力
GOSUB @CALC_DIR
GOTO @COMMAND
〜〜〜
@CALC_DIR
'C1,A,W1,X で座標計算
'方向の表示
'距離の表示
RETURN

さて、次回は最後、ゲームオーバーの処理です。
その12(最終回)に続きます。