将棋のZRF:解説3

<マクロの定義3>
  • 歩兵以外の駒打ちを定義しているブロック1:(drop $1)
(define drop
 ( (verify (not-in-zone? play-zone))
   to-board
   (while (not-in-zone? $1) ; $1 = drop zone
       s
   )
   (while (on-board? s)
       mark
       (drop-for-rank)
       back
       s
   )
   (drop-for-rank)
 )
)

※(not-in-zone? play-zone)で駒台の駒かどうか確認します。
※(not-in-zone? $1)で、打つ位置がその駒の打てる位置でないかどうかを確認し、打てない位置であれば下に進みます。
※下が盤上であれば、(drop-for-rank)を呼び出してから、(drop-for-rank)を呼び出す前にいた位置へ戻してから、下に進みます。
※これを、下が盤上でなくなるまで繰り返します。
※下が盤上でなければ、(drop-for-rank)を呼び出して、終わります。

  • 歩兵以外の駒打ちを定義しているブロック2:(drop-for-rank)
(define drop-for-rank
 (while (on-board? e)
  (if empty? add)
  e
 )
 (if empty? add)
)

※右が盤上であれば、空きマスならば打ち、右に進みます。
※これを、右が盤上でなくなるまで繰り返します。
※右が盤上でなければ、空きマスならば打ち、終わります。

  • 歩兵の駒打ちを定義しているブロック1:(drop-pawn $1)
(define drop-pawn
 ( (verify (not-in-zone? play-zone))
   to-board
   (drop-pawn-for-file)
   (while (on-board? e)
       e
       (drop-pawn-for-file)
   )
 )
)

※(not-in-zone? play-zone)で駒台の駒かどうか確認します。
※(drop-pawn-for-file)を呼び出します。
※右が盤上であれば、右に進んでから(drop-pawn-for-file)を呼び出します。
※これを、右が盤上でなくなるまで繰り返します。

  • 歩兵の駒打ちを定義しているブロック2:(drop-pawn-for-file)
(define drop-pawn-for-file
 (set-flag friendly-pawn false)
 mark
 (if (and friend? (piece? Pawn))
    (set-flag friendly-pawn true)
 )
 (while (and (not-flag? friendly-pawn) (on-board? s))
      s
      (if (and friend? (piece? Pawn))
        (set-flag friendly-pawn true)
      )
 )
 back
 (if (not-flag? friendly-pawn)
    mark
    (while (on-board? s)
        s
        (if empty?
           ; Check and disallow if it attacks a King with mate
           (if (and (enemy? n) (piece? King n))
              ; Can undefended Pawn be taken by King or can protected Pawn be taken?
              (set-flag bSafe (or not-defended? (attacked? no-king)))
              ; Check if King can make a move in any other direction
              n
              (check-dir e)
              (check-dir w)
              (check-dir n)
              (check-dir ne)
              (check-dir nw)
              (check-dir se)
              (check-dir sw)
              s
              (if (flag? bSafe)
                add
              )
           else
              add
           )
        )
    )
    back
 )
)

※味方の歩兵がいれば「friendly-pawn」を「true」にして、下が盤上であれば下へ進み、繰り返します。
※元の位置(最上段)へ戻って、「friendly-pawn」が「true」でなければ、空きマスに歩兵を打ちます。

※ただし、打つ位置の上に敵玉がいる場合は、打つ位置に自駒が利いておらず、敵玉以外の敵駒が利いていれば、「bSafe」を「ture」に設定し、玉の位置からその周囲7方向(右・左・上・右上・左上・右下・左下)をチェックします。
※敵玉の周囲7方向に、敵玉が逃げられない場合は、「bSafe」を「false」に設定します。
※「bSafe」が「true」の場合にのみ、歩兵を打てます。
(打ち歩詰めの回避)

※下が盤上であれば、下に進んで、打ち歩詰めでなければ打ちます。
※これを、下が盤上でなくなるまで繰り返します。

  • 玉の逃げるマスをチェックするブロック:(check-dir $1)
(define check-dir
 (if (and (not-flag? bSafe)
       (on-board? $1)
       (not-enemy? $1)
       (not-defended? $1)
    )
    (set-flag bSafe true)
 )
)

※「bSafe」が「true」でなく、$1が盤上であり、$1が敵駒でなく(敵玉にとっては味方でない)、$1が自駒で守られていない(敵玉にとっては敵駒が利いていない)、かどうかを確認します。
※$1に玉が逃げられる場合、「bSafe」を「true」にします。


最終更新:2020年08月18日 18:32