Commit | Line | Data |
---|---|---|
52718c94 BA |
1 | import { ChessRules, Move, PiPo } from "@/base_rules"; |
2 | import { ArrayFun } from "@/utils/array"; | |
3 | import { randInt, sample } from "@/utils/alea"; | |
4 | ||
5 | export class CoregalRules extends ChessRules { | |
6 | ||
7 | // TODO: special symbol (l) for royal queen... | |
8 | ||
9 | getPPpath(m) { | |
10 | if ( | |
11 | m.vanish.length == 2 && | |
12 | m.appear.length == 2 && | |
13 | m.vanish[0].p == V.QUEEN | |
14 | ) { | |
15 | // Large castle: show castle symbol | |
16 | return "Coregal/castle"; | |
17 | } | |
18 | return super.getPPpath(m); | |
19 | } | |
20 | ||
21 | genRandInitBaseFen() { | |
22 | const s = FenUtil.setupPieces( | |
23 | ['r', 'n', 'b', 'l', 'k', 'b', 'n', 'r'], | |
24 | { | |
25 | randomness: this.options["randomness"], | |
26 | between: [{p1: 'k', p2: 'r'}, {p1: 'l', p2: 'r'}], | |
27 | diffCol: ['b'], | |
28 | flags: ['r', 'k', 'l'] | |
29 | } | |
30 | ); | |
31 | return { | |
32 | fen: s.b.join("") + "/pppppppp/8/8/8/8/PPPPPPPP/" + | |
33 | s.w.join("").toUpperCase(), | |
34 | o: {flags: s.flags} | |
35 | }; | |
36 | } | |
37 | ||
38 | pieces() { | |
39 | let res = super.pieces(); | |
40 | res['l'] = {...}; | |
41 | return res; | |
42 | } | |
43 | ||
44 | setFlags(fenflags) { | |
45 | // white pieces positions, then black pieces positions | |
46 | this.castleFlags = { w: [...Array(4)], b: [...Array(4)] }; | |
47 | for (let i = 0; i < 8; i++) { | |
48 | this.castleFlags[i < 4 ? "w" : "b"][i % 4] = | |
49 | parseInt(fenflags.charAt(i), 10); | |
50 | } | |
51 | } | |
52 | ||
53 | getPotentialQueenMoves([x, y]) { | |
54 | let moves = super.getPotentialQueenMoves([x, y]); | |
55 | const c = this.getColor(x, y); | |
56 | if (this.castleFlags[c].slice(1, 3).includes(y)) | |
57 | moves = moves.concat(this.getCastleMoves([x, y])); | |
58 | return moves; | |
59 | } | |
60 | ||
61 | getPotentialKingMoves([x, y]) { | |
62 | let moves = this.getSlideNJumpMoves( | |
63 | [x, y], V.steps[V.ROOK].concat(V.steps[V.BISHOP]), 1); | |
64 | const c = this.getColor(x, y); | |
65 | if (this.castleFlags[c].slice(1, 3).includes(y)) | |
66 | moves = moves.concat(this.getCastleMoves([x, y])); | |
67 | return moves; | |
68 | } | |
69 | ||
70 | getCastleMoves([x, y]) { | |
71 | // Relative position of the selected piece: left or right ? | |
72 | // If left: small castle left, large castle right. | |
73 | // If right: usual situation. | |
74 | const c = this.getColor(x, y); | |
75 | const relPos = (this.castleFlags[c][1] == y ? "left" : "right"); | |
76 | ||
77 | const finalSquares = [ | |
78 | relPos == "left" ? [1, 2] : [2, 3], | |
79 | relPos == "right" ? [6, 5] : [5, 4] | |
80 | ]; | |
81 | const saveFlags = JSON.stringify(this.castleFlags[c]); | |
82 | // Alter flags to follow base_rules semantic | |
83 | this.castleFlags[c] = [0, 3].map(i => this.castleFlags[c][i]); | |
84 | const moves = super.getCastleMoves([x, y], finalSquares); | |
85 | this.castleFlags[c] = JSON.parse(saveFlags); | |
86 | return moves; | |
87 | } | |
88 | ||
89 | // "twoKings" arg for the similar Twokings variant. | |
90 | updateCastleFlags(move, piece, twoKings) { | |
91 | const c = V.GetOppCol(this.turn); | |
92 | const firstRank = (c == "w" ? V.size.x - 1 : 0); | |
93 | // Update castling flags if castling pieces moved or were captured | |
94 | const oppCol = V.GetOppCol(c); | |
95 | const oppFirstRank = V.size.x - 1 - firstRank; | |
96 | if (move.start.x == firstRank) { | |
97 | if (piece == V.KING || (!twoKings && piece == V.QUEEN)) { | |
98 | if (this.castleFlags[c][1] == move.start.y) | |
99 | this.castleFlags[c][1] = 8; | |
100 | else if (this.castleFlags[c][2] == move.start.y) | |
101 | this.castleFlags[c][2] = 8; | |
102 | // Else: the flag is already turned off | |
103 | } | |
104 | } | |
105 | else if ( | |
106 | move.start.x == firstRank && //our rook moves? | |
107 | [this.castleFlags[c][0], this.castleFlags[c][3]].includes(move.start.y) | |
108 | ) { | |
109 | const flagIdx = (move.start.y == this.castleFlags[c][0] ? 0 : 3); | |
110 | this.castleFlags[c][flagIdx] = 8; | |
111 | } else if ( | |
112 | move.end.x == oppFirstRank && //we took opponent rook? | |
113 | [this.castleFlags[oppCol][0], this.castleFlags[oppCol][3]] | |
114 | .includes(move.end.y) | |
115 | ) { | |
116 | const flagIdx = (move.end.y == this.castleFlags[oppCol][0] ? 0 : 3); | |
117 | this.castleFlags[oppCol][flagIdx] = 8; | |
118 | } | |
119 | } | |
120 | ||
121 | }; |