【四川省への道】第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
|