Can `piece` at (fr,fc) pseudo-legally move/capture to (tr,tc)? (path + pattern only)
(board, piece, fr, fc, tr, tc, ep)
| 88 | |
| 89 | |
| 90 | def _reaches(board, piece, fr, fc, tr, tc, ep) -> bool: |
| 91 | """Can `piece` at (fr,fc) pseudo-legally move/capture to (tr,tc)? (path + pattern only)""" |
| 92 | kind = piece.upper() |
| 93 | dr, dc = tr - fr, tc - fc |
| 94 | target = board[tr][tc] |
| 95 | if kind == "N": |
| 96 | return (abs(dr), abs(dc)) in ((1, 2), (2, 1)) |
| 97 | if kind == "K": |
| 98 | return max(abs(dr), abs(dc)) == 1 |
| 99 | if kind == "P": |
| 100 | white = _white(piece) |
| 101 | step = -1 if white else 1 |
| 102 | start_row = 6 if white else 1 |
| 103 | if dc == 0 and target == "": # push |
| 104 | if dr == step: |
| 105 | return True |
| 106 | if dr == 2 * step and fr == start_row and board[fr + step][fc] == "": |
| 107 | return True |
| 108 | return False |
| 109 | if abs(dc) == 1 and dr == step: # capture (incl. en passant) |
| 110 | return target != "" or (tr, tc) == ep |
| 111 | return False |
| 112 | # sliders |
| 113 | dirs = BISHOP if kind == "B" else ROOK if kind == "R" else BISHOP + ROOK |
| 114 | for ddr, ddc in dirs: |
| 115 | r, c = fr + ddr, fc + ddc |
| 116 | while 0 <= r < 8 and 0 <= c < 8: |
| 117 | if (r, c) == (tr, tc): |
| 118 | return True |
| 119 | if board[r][c]: |
| 120 | break |
| 121 | r, c = r + ddr, c + ddc |
| 122 | return False |
| 123 | |
| 124 | |
| 125 | def _apply(board, san, white, ep): |