【四川省への道】第7話


こんにちは、トラップですぅ。(^o^)/

今日は、1回曲がるだけで取れる場合の判定処理および、2回曲がって
取れる場合の処理の片方(クランク取り)を組み込んでみましょう。

◎前回の宿題(^^;

 前回の最後に、「組み込んだロジックを確認する為に、ソースリストを
 直して試してみてね」なんて言いましたが、どのようにされました?
 私は、こんな感じで直接 *CGSET ルーチンに埋め込んでおきました。(^^;)テヌキ

    1895 G(2,1)=12,G(2,2)=-1,G(2,3)=-1,G(2,4)=-1,G(2,5)=12
    1897 G(1,12)=24,G(2,12)=-1,G(3,12)=-1,G(4,12)=-1,G(5,12)=-1,G(6,12)=24

 ただ、前の *ALLDRAW ルーチンでは G() の値が -1 にエラーが出ますので、
 次の行を追加して、-1 の時はGPRINT文を飛ばす必要があります。

    2055     IF G(J,I)=-1 THEN *ADSKIP
                  ・・・
    2085     *ADSKIP

◎1回曲がることで結べる場合の判定

 1回曲がる・・・とは、直角に曲がって接続できるということですから、
 X座標とY座標のどちらを先に合わせるかによって2種類あります。(^^)v

 先に横を合わせる時の経路: (T1,U1)-(T2,U1)-(T2,U2)
 先に縦を合わせる時の経路: (T1,U1)-(T1,U2)-(T2,U2)

 さて、前回のプログラムで、どの牌がどこまで動けるかを調べましたが、
 詳しく説明してませんでしたね(^^ゞ。えっと、前回求めたSX,EX,SY,EYは
 図示すると次のようなものなんです。

    T1          T2
   □□□□□□□□□□□□□□
 U1 □■────────→EX□□
   □│□□□□□□□□□□SY□
   □↓□□□□□□□□□□↑□
   □EY□□□□□□□□□□│□
 U2 □□SX←────────■□
   □□□□□□□□□□□□□□

 さて、これを見て何か気付かないでしょうか・・・(^^)?
 そうです、EXがT2に到達し、かつSYがU1に到達すれば、接続できるという
 証明になるんです。同様にして、SX<=T1 で EY>=U2でも成り立ちますね。

 この判定は、(T1,U1)と(T2,U2)の牌の上下関係によって異なるので、
 上図の場合は次の判定を追加すれば良いわけです。

    2905 ' (T1,U1)から下に真直ぐおろし、そこから右に伸ばして接続できる場合。
    2910 IF SX<=T1 AND U2<=EY THEN *T1T1T2
    2915 ' (T2,U2)から上に真直ぐのばし、そこから左に伸ばして接続できる場合。
    2920 IF T2<=EX AND SY<=U1 THEN *T1T2T2

 牌の上下関係が逆の場合は、次の判定で良いですよね。

    2995 ' (T2,U2)から下に真直ぐおろし、そこから右に伸ばして接続できる場合。
    3000 IF SX<=T1 AND SY<=U2 THEN *T1T1T2
    3005 ' (T1,U1)から上に真直ぐのばし、そこから左に伸ばして接続できる場合。
    3010 IF T2<=EX AND U1<=EY THEN *T1T2T2

 例によって、取った時のジャンプ先ですが・・・ま、まあ次のとおりに
 しておいてくださいませ。(^-^)

    3340 *T1T1T2:LX(&0)=T1,LY(&0)=U1,LX(&1)=T1,LY(&1)=U2,LX(&2)=T2,
          LY(&2)=U2,LC=&2:GOTO *OKGET
    3350 *T1T2T2:LX(&0)=T1,LY(&0)=U1,LX(&1)=T2,LY(&1)=U1,LX(&2)=T2,
          LY(&2)=U2,LC=&2:GOTO *OKGET

◎2回曲がることで結べる場合の判定(クランク型)

 直線でも直角ラインでも結べない時、2回曲がることで結べる場合があります。
 その際、外側で結ぶのと内側で結ぶのとがありますが、まずは内側から考えて
 みます。

    T1          T2
 U1 □■─────→EX□□□□□
   □│□□□□□□□□□□SY□
   □│□□□□□□□□□□↑□
 YW □├──────────┤□
   □↓□□□□□□□□□□│□
   □EY□□□□□□□□□□│□
 U2 □□□□SX←──────■□

 上の図は「縦・横・縦」の接続を示したものですが、よく見ると必要な条件が
 見えてきます。つまり、Y座標YWが前に求めていたSYとEYの共通範囲であって、
 なおかつT1〜T2まで何もないことが必要なのです。
 ・・ということは、Y座標をSYからEYまで1つずつ動かしながら、T1〜T2が
 あいている所を探せばいいわけですね。(^^)
 さあ、その考えをプログラムにしてしまいましょう。

    3045 ' 縦・横・縦の形で接続できるか調べる。
    3050 YW=SY:GOTO *PYSK1
    3060 *PYLP1
    3062 ' Y座標=YWで、X座標 T1〜T2 に障害物がないかを調べる。
    3064 GOSUB *XLCHK
    3066 ' なければ、(T1,U1)-(T1,YW)-(T2,YW)-(T2,U2)の経路で取れる。
    3068 IF RC THEN *T1122U1WW2 ELSE YW=YW+1
    3070 *PYSK1:IF YW<=EY THEN *PYLP1

 「横・縦・横」の場合も同様に・・・

    3075 ' 横・縦・横の形で接続できるか調べる。
    3080 XW=SX:GOTO *PXSK1
    3090 *PXLP1
    3092 ' X座標=XWで、Y座標 UT〜UB に障害物がないかを調べる。
    3094 GOSUB *YLCHK
    3096 ' なければ、(T1,U1)-(XW,U1)-(XW,U2)-(T2,U2)の経路で取れる。
    3098 IF RC THEN *T1WW2U1122 ELSE XW=XW+1
    3100 *PXSK1:IF XW<=EX THEN *PXLP1

 リスト中で呼んでいる *XLCHK, *YLCHK は注釈のとおりのチェックを行う
 サブルーチンにすれば吉ですね。(^^) ツカイマワシ キキマスシ。

 なお、実行するには、いつものように前回までのリストと今回のリストを
 合成してください。

    1 REMサンプル No.6

    3360 *T1122U1WW2:LX(&0)=T1,LY(&0)=U1,LX(&1)=T1,LY(&1)=YW,LX(&2)=T2,
          LY(&2)=YW,LX(&3)=T2,LY(&3)=U2,LC=&3:GOTO *OKGET
    3370 *T1WW2U1122:LX(&0)=T1,LY(&0)=U1,LX(&1)=XW,LY(&1)=U1,LX(&2)=XW,
          LY(&2)=U2,LX(&3)=T2,LY(&3)=U2,LC=&3:GOTO *OKGET

    3400 '
    3410 ' Y座標=YWで、X座標 T1〜T2 に障害物がないかを調べる。
    3420 '
    3430 *XLCHK
    3440 RC=0,WX=T1
    3450 *XL1:IF WX<=T2 THEN IF G(YW,WX)=-1 THEN WX=WX+1:GOTO *XL1 ELSE RETURN
    3460 RC=1:RETURN

    3470 '
    3480 ' X座標=XWで、Y座標 UT〜UB に障害物がないかを調べる。
    3490 '
    3500 *YLCHK
    3510 RC=0,WY=UT
    3520 *YL1:IF WY<=UB THEN IF G(WY,XW)=-1 THEN WY=WY+1:GOTO *YL1 ELSE RETURN
    3530 RC=1:RETURN

☆次回予告

 ついにここまで辿りつきました。
 次回は最後の取り方である「コの字型」にてお会いしましょう。
【今回のソースお持ち帰り】 SAMPLE6.SRC