Commit | Line | Data |
---|---|---|
964eda04 BA |
1 | import { ChessRules, Move, PiPo } from "@/base_rules"; |
2 | ||
3 | export class SwitchingRules extends ChessRules { | |
4 | // Build switch move between squares x1,y1 and x2,y2 | |
5 | getSwitchMove_s([x1, y1], [x2, y2]) { | |
6 | const c = this.getColor(x1, y1); //same as color at square 2 | |
7 | const p1 = this.getPiece(x1, y1); | |
8 | const p2 = this.getPiece(x2, y2); | |
9 | let move = new Move({ | |
10 | appear: [ | |
11 | new PiPo({ x: x2, y: y2, c: c, p: p1 }), | |
12 | new PiPo({ x: x1, y: y1, c: c, p: p2 }) | |
13 | ], | |
14 | vanish: [ | |
15 | new PiPo({ x: x1, y: y1, c: c, p: p1 }), | |
16 | new PiPo({ x: x2, y: y2, c: c, p: p2 }) | |
17 | ] | |
18 | }); | |
19 | // Move completion: promote switched pawns (as in Magnetic) | |
20 | const lastRank = (c == "w" ? 0 : V.size.x - 1); | |
21 | let moves = []; | |
22 | if ((p1 == V.PAWN && x2 == lastRank) || (p2 == V.PAWN && x1 == lastRank)) { | |
23 | const idx = (p1 == V.PAWN ? 0 : 1); | |
24 | move.appear[idx].p = V.ROOK; | |
25 | moves.push(move); | |
26 | for (let piece of [V.KNIGHT, V.BISHOP, V.QUEEN]) { | |
27 | let cmove = JSON.parse(JSON.stringify(move)); | |
28 | cmove.appear[idx].p = piece; | |
29 | moves.push(cmove); | |
30 | } | |
31 | if (idx == 1) { | |
32 | // Swap moves[i].appear[0] and [1] for moves presentation [TODO...] | |
33 | moves.forEach(m => { | |
34 | let tmp = m.appear[0]; | |
35 | m.appear[0] = m.appear[1]; | |
36 | m.appear[1] = tmp; | |
37 | }); | |
38 | } | |
39 | } | |
40 | else | |
41 | // Other cases | |
42 | moves.push(move); | |
43 | return moves; | |
44 | } | |
45 | ||
46 | getPotentialMovesFrom([x,y]) { | |
47 | let moves = super.getPotentialMovesFrom([x,y]); | |
48 | const piece = this.getPiece(x,y); | |
49 | const color = this.turn; | |
50 | const oppCol = V.GetOppCol(color); | |
51 | const kp = this.kingPos[color]; | |
52 | // Add switches (if not under check, from anything but the king) | |
53 | if (piece != V.KING && !this.isAttacked(kp, oppCol)) { | |
54 | const steps = V.steps[V.ROOK].concat(V.steps[V.BISHOP]); | |
55 | for (let step of steps) { | |
56 | const [i, j] = [x+step[0], y+step[1]]; | |
57 | if ( | |
58 | V.OnBoard(i, j) && | |
59 | this.board[i][j] != V.EMPTY && | |
60 | this.getColor(i,j) == color && | |
61 | this.getPiece(i,j) != piece | |
62 | ) { | |
63 | const switchMove_s = this.getSwitchMove_s([x,y], [i,j]); | |
64 | Array.prototype.push.apply(moves, switchMove_s); | |
65 | } | |
66 | } | |
67 | } | |
68 | return moves; | |
69 | } | |
70 | ||
71 | postPlay(move) { | |
72 | // Did some king move? | |
73 | move.appear.forEach(a => { | |
74 | if (a.p == V.KING) { | |
75 | this.kingPos[a.c] = [a.x, a.y]; | |
76 | this.castleFlags[a.c] = [V.size.y, V.size.y]; | |
77 | } | |
78 | }); | |
0b8bd121 | 79 | const firstRank = (move.vanish[0].c == 'w' ? 7 : 0); |
964eda04 BA |
80 | for (let coords of [move.start, move.end]) { |
81 | if ( | |
82 | Object.keys(firstRank).includes(coords.x) && | |
83 | this.castleFlags[firstRank[coords.x]].includes(coords.y) | |
84 | ) { | |
85 | const c = firstRank[coords.x]; | |
86 | const flagIdx = (coords.y == this.castleFlags[c][0] ? 0 : 1); | |
87 | this.castleFlags[c][flagIdx] = V.size.y; | |
88 | } | |
89 | } | |
90 | } | |
91 | ||
92 | postUndo(move) { | |
93 | // Did some king move? | |
94 | move.vanish.forEach(v => { | |
95 | if (v.p == V.KING) this.kingPos[v.c] = [v.x, v.y]; | |
96 | }); | |
97 | } | |
98 | ||
99 | static get SEARCH_DEPTH() { | |
100 | // Branching factor is quite high | |
101 | return 2; | |
102 | } | |
103 | ||
104 | getAllPotentialMoves() { | |
105 | // Since this function is used only for computer play, | |
106 | // remove duplicate switches: | |
107 | return super.getAllPotentialMoves().filter(m => { | |
108 | return ( | |
109 | m.appear.length == 1 || | |
0b8bd121 | 110 | (m.appear[0].p == V.KING && m.appear[1].p == V.ROOK) || |
964eda04 BA |
111 | (m.appear[1].x <= m.vanish[1].x && m.appear[1].y <= m.vanish[1].y) |
112 | ); | |
113 | }); | |
114 | } | |
115 | ||
116 | getNotation(move) { | |
117 | if (move.appear.length == 1) | |
118 | // Normal move | |
119 | return super.getNotation(move); | |
120 | if (move.appear[0].p == V.KING && move.appear[1].p == V.ROOK) | |
121 | // Castle | |
122 | return (move.end.y < move.start.y ? "0-0-0" : "0-0"); | |
123 | // Switch | |
124 | return "S" + V.CoordsToSquare(move.start) + V.CoordsToSquare(move.end); | |
125 | } | |
126 | } |