Commit | Line | Data |
---|---|---|
a6abf094 BA |
1 | class SwitchingRules extends ChessRules |
2 | { | |
1221ac47 BA |
3 | // Build switch move between squares x1,y1 and x2,y2 |
4 | getSwitchMove_s([x1,y1],[x2,y2]) | |
5 | { | |
1221ac47 BA |
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); | |
6752407b BA |
9 | const V = VariantRules; |
10 | if (p1 == V.KING && p2 == V.ROOK) | |
11 | return []; //avoid duplicate moves (potential conflict with castle) | |
1221ac47 BA |
12 | let move = new Move({ |
13 | appear: [ | |
14 | new PiPo({x:x2,y:y2,c:c,p:p1}), | |
15 | new PiPo({x:x1,y:y1,c:c,p:p2}) | |
16 | ], | |
17 | vanish: [ | |
18 | new PiPo({x:x1,y:y1,c:c,p:p1}), | |
19 | new PiPo({x:x2,y:y2,c:c,p:p2}) | |
20 | ], | |
21 | start: {x:x1,y:y1}, | |
22 | end: {x:x2,y:y2} | |
23 | }); | |
24 | // Move completion: promote switched pawns (as in Magnetic) | |
25 | const sizeX = VariantRules.size[0]; | |
26 | const lastRank = (c == "w" ? 0 : sizeX-1); | |
1221ac47 | 27 | let moves = []; |
9f18af3b | 28 | if ((p1==V.PAWN && x2==lastRank) || (p2==V.PAWN && x1==lastRank)) |
1221ac47 | 29 | { |
9f18af3b BA |
30 | const idx = (p1==V.PAWN ? 0 : 1); |
31 | move.appear[idx].p = V.ROOK; | |
1221ac47 BA |
32 | moves.push(move); |
33 | for (let piece of [V.KNIGHT, V.BISHOP, V.QUEEN]) | |
34 | { | |
35 | let cmove = JSON.parse(JSON.stringify(move)); | |
9f18af3b | 36 | cmove.appear[idx].p = piece; |
1221ac47 BA |
37 | moves.push(cmove); |
38 | } | |
9f18af3b BA |
39 | if (idx == 1) |
40 | { | |
41 | // Swap moves[i].appear[0] and [1] for moves presentation [TODO...] | |
42 | moves.forEach(m => { | |
43 | let tmp = m.appear[0]; | |
44 | m.appear[0] = m.appear[1]; | |
45 | m.appear[1] = tmp; | |
46 | }); | |
47 | } | |
1221ac47 BA |
48 | } |
49 | else //other cases | |
50 | moves.push(move); | |
51 | return moves; | |
52 | } | |
a6abf094 | 53 | |
15952ada | 54 | getPotentialMovesFrom([x,y], computer) |
1221ac47 BA |
55 | { |
56 | let moves = super.getPotentialMovesFrom([x,y]); | |
15952ada | 57 | // Add switches: respecting chessboard ordering if "computer" is on |
1221ac47 BA |
58 | const V = VariantRules; |
59 | const color = this.turn; | |
60 | const piece = this.getPiece(x,y); | |
61 | const [sizeX,sizeY] = V.size; | |
62 | const steps = V.steps[V.ROOK].concat(V.steps[V.BISHOP]); | |
63 | const kp = this.kingPos[color]; | |
64 | const oppCol = this.getOppCol(color); | |
65 | for (let step of steps) | |
66 | { | |
67 | let [i,j] = [x+step[0],y+step[1]]; | |
15952ada BA |
68 | if (!!computer && (i<x || (i==x && j<y))) |
69 | continue; //only switch with superior indices | |
1221ac47 BA |
70 | if (i>=0 && i<sizeX && j>=0 && j<sizeY && this.board[i][j]!=V.EMPTY |
71 | && this.getColor(i,j)==color && this.getPiece(i,j)!=piece | |
72 | // No switching under check (theoretically non-king pieces could, but not) | |
73 | && !this.isAttacked(kp, [oppCol])) | |
74 | { | |
75 | let switchMove_s = this.getSwitchMove_s([x,y],[i,j]); | |
76 | if (switchMove_s.length == 1) | |
77 | moves.push(switchMove_s[0]); | |
78 | else //promotion | |
79 | moves = moves.concat(switchMove_s); | |
80 | } | |
81 | } | |
82 | return moves; | |
83 | } | |
84 | ||
15952ada BA |
85 | getAllValidMoves(computer) |
86 | { | |
87 | const color = this.turn; | |
88 | const oppCol = this.getOppCol(color); | |
89 | let potentialMoves = []; | |
90 | const [sizeX,sizeY] = VariantRules.size; | |
91 | for (let i=0; i<sizeX; i++) | |
92 | { | |
93 | for (let j=0; j<sizeY; j++) | |
94 | { | |
95 | if (this.board[i][j] != VariantRules.EMPTY && this.getColor(i,j) == color) | |
96 | { | |
97 | Array.prototype.push.apply(potentialMoves, | |
98 | this.getPotentialMovesFrom([i,j], computer)); | |
99 | } | |
100 | } | |
101 | } | |
102 | return this.filterValid(potentialMoves); | |
103 | } | |
104 | ||
9f18af3b BA |
105 | updateVariables(move) |
106 | { | |
107 | super.updateVariables(move); | |
108 | if (move.appear.length == 2 && move.vanish.length == 2 | |
109 | && move.appear[1].p == VariantRules.KING) | |
110 | { | |
111 | // Switch with the king; not castle, and not handled by main class | |
112 | const color = this.getColor(move.start.x, move.start.y); | |
113 | this.kingPos[color] = [move.appear[1].x, move.appear[1].y]; | |
114 | } | |
115 | } | |
116 | ||
117 | unupdateVariables(move) | |
118 | { | |
119 | super.unupdateVariables(move); | |
120 | if (move.appear.length == 2 && move.vanish.length == 2 | |
121 | && move.appear[1].p == VariantRules.KING) | |
122 | { | |
123 | const color = this.getColor(move.start.x, move.start.y); | |
124 | this.kingPos[color] = [move.appear[0].x, move.appear[0].y]; | |
125 | } | |
126 | } | |
127 | ||
15952ada BA |
128 | static get SEARCH_DEPTH() { return 2; } //high branching factor |
129 | ||
130 | getNotation(move) | |
131 | { | |
132 | if (move.appear.length == 1) | |
133 | return super.getNotation(move); //no switch | |
134 | // Switch or castle | |
135 | if (move.appear[0].p == VariantRules.KING && move.appear[1].p == VariantRules.ROOK) | |
136 | return (move.end.y < move.start.y ? "0-0-0" : "0-0"); | |
137 | // Switch: | |
138 | const startSquare = | |
139 | String.fromCharCode(97 + move.start.y) + (VariantRules.size[0]-move.start.x); | |
140 | const finalSquare = | |
141 | String.fromCharCode(97 + move.end.y) + (VariantRules.size[0]-move.end.x); | |
142 | return "S" + startSquare + finalSquare; | |
143 | } | |
a6abf094 | 144 | } |