【四川省への道】第5話


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

今回は、ゲームのルールをどう組み込むか?に的をしぼって話を
進めていきましょう。

◎四川省のルール

 四川省のルールは、ごく簡単なものです。単に、同じ種類の牌を
 探して2個1組で取っていくだけ・・・。但し、それだけじゃ
 ゲームになりませんから、次のような条件がついています。

 「2つの牌の中心から垂直線 or 水平線を伸ばした時、
  他の牌の上を横切らずに2曲り以内で結べること。 」

 う〜ん、言葉では説明しづらいですねぇ。(^_^;)
 図解すると、次のような取り方ができるということなんです。

 ・2つの牌の間を1本の直線で結べる場合(隣接も可)
              □□□
  □□□□□□□□□□  □■□
  □■──────■□  □■□
  □□□□□□□□□□  □□□ 

 ・下図の様に1度曲がることで結べる場合
                  
  □■──────┐  □■□□
  □□□□□□  │  □│□□
  □□□□□□□□■  □│□□
              └─■

 ・クランク型か、コの字型で結べる場合 

  ■──┐□□□  ┌──────┐
  □□□│□□□  │ □□   │
  □□□└──■  ■ □□□□ ■
  □□□ □□□

 前回までで、牌の表示も反転もできていますし、それが何の
 牌であるかも、配列変数G()で簡単にわかりますから、後は、
 上記のルールを組み込んで飾りをつければ「四川省」になる
 わけです。ね、簡単でしょ。(^-^)

◎ルールのプログラム化

 さて、牌をペンでタッチした場合、どの牌をタッチしたかは
 PX,PYの2つの変数に入るようにしてましたね。(^^)

 従って、ここから先を作り込んでいけばいいわけです。
 まずは、「同じ牌じゃなければ取れない」という処理を組み
 込んでみることにしましょう。
 ざっと考えると、こんな流れでしょうか・・・。

  (1) 画面がタッチされる。
  (2) 牌のない所なら何もせず、戻る。
  (3) 今、1つも選択されてなければ、それを反転して戻る。
  (4) 1つめの牌を再びタッチされたら、反転を元に戻して戻る。
  (5) 1つめと同じ種類でなければ、何もしないで戻る。
  (6) 1つめと2つめの牌を取り去る。

 ちなみに、この「流れ」はどうやって考えるか・・・ですが、
 特に難しいことなくって、1つ1つ細かく機械の気持ちになって
 考えてあげればいいんです。人間だと一瞬でわかる事でも、
 1つ1つ噛み砕いて教えてあげないといけないんですね。(^-^)

 さて、上のように「流れ」を作れば、自ずと必要なものが見えて
 くることにお気づきでしょうか?例えば「1つめと同じ牌・・」
 という1文から、「1つめの牌が何であったか覚えておく変数」が
 必要だとわかります。同時に、どこにあったかも覚えておかなきゃ
 後で反転させる事も、消すこともできませんよね。

 そこで私は、こう決めました。
 「P1が -1 ならどれも選択されていない。」
 「P1が 0〜35 なら、その番号の種類の牌が選択されている。」
 場所の方は、そうですね・・1つ目の牌はX,Yに、2つ目の牌は
 V,Wにでも入れるようにしましょう。

 上記をふまえてプログラム化すると、こんな感じになります。

    1 REMサンプル No.4
    155 P1=-1 : Z=144
    240 IF P1<0 THEN X=PX,Y=PY:GOSUB *TC1 ELSE V=PX,W=PY:GOSUB *TC2
    250 IF Z THEN *LP1                           :'まだ牌がある?
    260 GOTO *THEEND
    400 '
    410 *TC1
    420 IF G(Y,X)=-1 THEN RETURN     :'牌がない
    430 P1=G(Y,X)                    :'今の牌の種類を P1 に保存。
    440 GOSUB *HANTENX
    450 RETURN
    460 '
    470 *TC2
    480 IF G(W,V)<>P1 THEN RETURN    :'同じ種類ではない。
    490 IF X=V AND Y=W THEN *CANCEL  :'1つ目と同じ牌なら、キャンセル
    500 GOSUB *HANTEN2
    620 '
    630 *T3
    640 CALL@41,(X*12-1,Y*16+13)-(X*12+10,Y*16+28),3,0  :'消去
    650 CALL@41,(V*12-1,W*16+13)-(V*12+10,W*16+28),3,0  :'消去
    660 G(Y,X)=-1,G(W,V)=-1 : 'この行を外すと困ったことが(^_^;)
    670 Z=Z-&2
    680 P1=-1
    690 RETURN
    790 '
    800 *CANCEL
    810 P1=-1
    820 GOSUB *HANTENX
    830 RETURN
    840 '
    850 *HANTENX:CALL@41,(X*12-1,Y*16+13)-(X*12+9,Y*16+27),1,1:RETURN
    860 *HANTEN2:CALL@41,(V*12-1,W*16+13)-(V*12+9,W*16+27),1,1:RETURN

 ちょっと長くなりましたが、全部の牌を消すと終了するようにしたり、
 それっぽい雰囲気になってきてると思います。これで、カードが裏返って
 いれば神経衰弱なんてすぐに作れそうですよね。(^^)
 例によって、カードのデータ作成が大変ですけど、麻雀牌を用いる事に
 すれば、四川省の牌データがそのまま使えるでしょうし。(笑)

☆次回予告

 今回は、まず単純なルールから組み込んでみました。
 次回は、他のルールのアルゴリズムにてお会いしましょう。
【今回のソースお持ち帰り】 SAMPLE4.SRC