| 1 | import { ChessRules } from "@/base_rules"; |
| 2 | |
| 3 | export class Squatter1Rules extends ChessRules { |
| 4 | |
| 5 | static get Lines() { |
| 6 | return [ |
| 7 | [[1, 0], [1, 8]], |
| 8 | [[7, 0], [7, 8]] |
| 9 | ]; |
| 10 | } |
| 11 | |
| 12 | // Find possible captures by opponent on [x, y] |
| 13 | findCaptures([x, y]) { |
| 14 | const color = this.getColor(x, y); |
| 15 | const forward = (color == 'w' ? -1 : 1); |
| 16 | let moves = []; |
| 17 | const steps = { |
| 18 | // Rook and bishop: included in queen case |
| 19 | p: { s: [[forward, -1], [forward, 1]], one: true }, |
| 20 | n: { s: V.steps[V.KNIGHT], one: true }, |
| 21 | q: { s: V.steps[V.ROOK].concat(V.steps[V.BISHOP]) }, |
| 22 | k: { s: V.steps[V.ROOK].concat(V.steps[V.BISHOP]), one: true } |
| 23 | }; |
| 24 | const oppCol = V.GetOppCol(color); |
| 25 | Object.keys(steps).forEach(piece => { |
| 26 | outerLoop: for (let loop = 0; loop < steps[piece].s.length; loop++) { |
| 27 | const step = steps[piece].s[loop]; |
| 28 | let i = x + step[0]; |
| 29 | let j = y + step[1]; |
| 30 | while (V.OnBoard(i, j) && this.board[i][j] == V.EMPTY) { |
| 31 | if (steps[piece].one) continue outerLoop; |
| 32 | i += step[0]; |
| 33 | j += step[1]; |
| 34 | } |
| 35 | if ( |
| 36 | V.OnBoard(i, j) && |
| 37 | this.board[i][j] != V.EMPTY && |
| 38 | this.getColor(i, j) == oppCol |
| 39 | ) { |
| 40 | const oppPiece = this.getPiece(i, j); |
| 41 | if ( |
| 42 | oppPiece == piece || |
| 43 | ( |
| 44 | piece == V.QUEEN && |
| 45 | ( |
| 46 | (oppPiece == V.ROOK && step.some(e => e == 0)) || |
| 47 | (oppPiece == V.BISHOP && step.every(e => e != 0)) |
| 48 | ) |
| 49 | ) |
| 50 | ) |
| 51 | // Possible capture (do not care about promotions): |
| 52 | moves.push(this.getBasicMove([i, j], [x, y])); |
| 53 | } |
| 54 | } |
| 55 | }); |
| 56 | return moves; |
| 57 | } |
| 58 | |
| 59 | someValid(moves, color) { |
| 60 | // Stop at first valid move found: |
| 61 | for (let m of moves) { |
| 62 | this.play(m); |
| 63 | const res = !this.underCheck(color); |
| 64 | this.undo(m); |
| 65 | if (res) return true; |
| 66 | } |
| 67 | return false; |
| 68 | } |
| 69 | |
| 70 | getCurrentScore() { |
| 71 | // Try both colors (to detect potential suicides) |
| 72 | for (let c of ['w', 'b']) { |
| 73 | const oppCol = V.GetOppCol(c); |
| 74 | const goal = (c == 'w' ? 0 : 7); |
| 75 | if ( |
| 76 | this.board[goal].some( |
| 77 | (b,j) => { |
| 78 | return ( |
| 79 | b[0] == c && |
| 80 | ( |
| 81 | !this.isAttacked([goal, j], oppCol) || |
| 82 | !this.someValid(this.findCaptures([goal, j]), oppCol) |
| 83 | ) |
| 84 | ); |
| 85 | } |
| 86 | ) |
| 87 | ) { |
| 88 | return c == 'w' ? "1-0" : "0-1"; |
| 89 | } |
| 90 | } |
| 91 | return super.getCurrentScore(); |
| 92 | } |
| 93 | |
| 94 | static get SEARCH_DEPTH() { |
| 95 | return 2; |
| 96 | } |
| 97 | |
| 98 | }; |