Commit | Line | Data |
---|---|---|
14c35dc6 BA |
1 | import { ChessRules } from "@/base_rules"; |
2 | import { CoregalRules } from "@/variants/Coregal"; | |
3 | ||
4 | export class TwokingsRules extends CoregalRules { | |
5 | static get PawnSpecs() { | |
6 | return Object.assign( | |
7 | {}, | |
8 | ChessRules.PawnSpecs, | |
9 | { promotions: ChessRules.PawnSpecs.promotions.concat([V.KING]) } | |
10 | ); | |
11 | } | |
12 | ||
13 | static IsGoodPosition(position) { | |
14 | if (position.length == 0) return false; | |
15 | const rows = position.split("/"); | |
16 | if (rows.length != V.size.x) return false; | |
17 | let kings = { "w": 0, "b": 0 }; | |
18 | for (let row of rows) { | |
19 | let sumElts = 0; | |
20 | for (let i = 0; i < row.length; i++) { | |
21 | if (['K','k'].includes(row[i])) kings[row[i]]++; | |
22 | if (V.PIECES.includes(row[i].toLowerCase())) sumElts++; | |
23 | else { | |
e50a8025 | 24 | const num = parseInt(row[i], 10); |
14c35dc6 BA |
25 | if (isNaN(num)) return false; |
26 | sumElts += num; | |
27 | } | |
28 | } | |
29 | if (sumElts != V.size.y) return false; | |
30 | } | |
31 | // Two kings (at least) per side should be present: | |
32 | if (Object.values(kings).some(v => v < 2)) return false; | |
33 | return true; | |
34 | } | |
35 | ||
36 | // Not scanning king positions. In this variant, scan the board everytime. | |
d54f6261 | 37 | scanKings() {} |
14c35dc6 | 38 | |
af34341d BA |
39 | getCheckSquares() { |
40 | const color = this.turn; | |
14c35dc6 BA |
41 | let squares = []; |
42 | const oppCol = V.GetOppCol(color); | |
43 | for (let i=0; i<V.size.x; i++) { | |
44 | for (let j=0; j<V.size.y; j++) { | |
45 | if ( | |
46 | this.getColor(i, j) == color && | |
47 | this.getPiece(i, j) == V.KING && | |
48 | this.isAttacked([i, j], oppCol) | |
49 | ) { | |
50 | squares.push([i, j]); | |
51 | } | |
52 | } | |
53 | } | |
54 | return squares; | |
55 | } | |
56 | ||
57 | static GenRandInitFen(randomness) { | |
305ede7e BA |
58 | if (randomness == 0) |
59 | return "rnqkkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNQKKBNR w 0 adehadeh -"; | |
60 | ||
61 | const replaceBishop = (fen, first, ch1, ch2) => { | |
62 | // Remove and re-add final part: | |
63 | const suffix = fen.substr(-15); | |
64 | fen = fen.slice(0, -15); | |
65 | if (first) fen = fen.replace(ch1, ch2); | |
66 | else { | |
67 | fen = | |
68 | fen.split("").reverse().join("") | |
69 | .replace(ch1, ch2) | |
70 | .split("").reverse().join("") | |
71 | } | |
72 | return fen + suffix; | |
73 | }; | |
74 | ||
75 | const sameIndexReplace = (fen) => { | |
76 | const first = (Math.random() < 0.5); | |
77 | return replaceBishop( | |
78 | replaceBishop(fen, first, 'B', 'Q'), | |
79 | first, | |
80 | 'b', | |
81 | 'q' | |
82 | ); | |
83 | }; | |
84 | ||
85 | const fen = | |
86 | CoregalRules.GenRandInitFen(randomness) | |
87 | .replace("q", "k").replace("Q", "K"); | |
88 | // Now replace a bishop by the queen, | |
89 | // so that bishops are of different colors: | |
90 | if (randomness == 1) return sameIndexReplace(fen); | |
91 | const wOdd = fen.indexOf('B') % 2; | |
92 | const bOdd = fen.indexOf('b') % 2; | |
93 | // Since there are 7 slashes, different oddities means symmetric | |
94 | if (wOdd != bOdd) return sameIndexReplace(fen); | |
95 | const wFirst = (Math.random() < 0.5); | |
96 | return replaceBishop( | |
97 | replaceBishop(fen, wFirst, 'B', 'Q'), | |
98 | !wFirst, | |
99 | 'b', | |
100 | 'q' | |
101 | ); | |
14c35dc6 BA |
102 | } |
103 | ||
104 | underCheck(color) { | |
105 | const oppCol = V.GetOppCol(color); | |
106 | for (let i=0; i<V.size.x; i++) { | |
107 | for (let j=0; j<V.size.y; j++) { | |
108 | if ( | |
109 | this.getColor(i, j) == color && | |
110 | this.getPiece(i, j) == V.KING && | |
111 | this.isAttacked([i, j], oppCol) | |
112 | ) { | |
113 | return true; | |
114 | } | |
115 | } | |
116 | } | |
117 | return false; | |
118 | } | |
119 | ||
120 | postPlay(move) { | |
121 | const piece = move.vanish[0].p; | |
122 | super.updateCastleFlags(move, piece, "twoKings"); | |
123 | } | |
124 | ||
125 | postUndo() {} | |
126 | }; |