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 { | |
24 | const num = parseInt(row[i]); | |
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 BA |
38 | |
39 | getCheckSquares(color) { | |
40 | let squares = []; | |
41 | const oppCol = V.GetOppCol(color); | |
42 | for (let i=0; i<V.size.x; i++) { | |
43 | for (let j=0; j<V.size.y; j++) { | |
44 | if ( | |
45 | this.getColor(i, j) == color && | |
46 | this.getPiece(i, j) == V.KING && | |
47 | this.isAttacked([i, j], oppCol) | |
48 | ) { | |
49 | squares.push([i, j]); | |
50 | } | |
51 | } | |
52 | } | |
53 | return squares; | |
54 | } | |
55 | ||
56 | static GenRandInitFen(randomness) { | |
305ede7e BA |
57 | if (randomness == 0) |
58 | return "rnqkkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNQKKBNR w 0 adehadeh -"; | |
59 | ||
60 | const replaceBishop = (fen, first, ch1, ch2) => { | |
61 | // Remove and re-add final part: | |
62 | const suffix = fen.substr(-15); | |
63 | fen = fen.slice(0, -15); | |
64 | if (first) fen = fen.replace(ch1, ch2); | |
65 | else { | |
66 | fen = | |
67 | fen.split("").reverse().join("") | |
68 | .replace(ch1, ch2) | |
69 | .split("").reverse().join("") | |
70 | } | |
71 | return fen + suffix; | |
72 | }; | |
73 | ||
74 | const sameIndexReplace = (fen) => { | |
75 | const first = (Math.random() < 0.5); | |
76 | return replaceBishop( | |
77 | replaceBishop(fen, first, 'B', 'Q'), | |
78 | first, | |
79 | 'b', | |
80 | 'q' | |
81 | ); | |
82 | }; | |
83 | ||
84 | const fen = | |
85 | CoregalRules.GenRandInitFen(randomness) | |
86 | .replace("q", "k").replace("Q", "K"); | |
87 | // Now replace a bishop by the queen, | |
88 | // so that bishops are of different colors: | |
89 | if (randomness == 1) return sameIndexReplace(fen); | |
90 | const wOdd = fen.indexOf('B') % 2; | |
91 | const bOdd = fen.indexOf('b') % 2; | |
92 | // Since there are 7 slashes, different oddities means symmetric | |
93 | if (wOdd != bOdd) return sameIndexReplace(fen); | |
94 | const wFirst = (Math.random() < 0.5); | |
95 | return replaceBishop( | |
96 | replaceBishop(fen, wFirst, 'B', 'Q'), | |
97 | !wFirst, | |
98 | 'b', | |
99 | 'q' | |
100 | ); | |
14c35dc6 BA |
101 | } |
102 | ||
103 | underCheck(color) { | |
104 | const oppCol = V.GetOppCol(color); | |
105 | for (let i=0; i<V.size.x; i++) { | |
106 | for (let j=0; j<V.size.y; j++) { | |
107 | if ( | |
108 | this.getColor(i, j) == color && | |
109 | this.getPiece(i, j) == V.KING && | |
110 | this.isAttacked([i, j], oppCol) | |
111 | ) { | |
112 | return true; | |
113 | } | |
114 | } | |
115 | } | |
116 | return false; | |
117 | } | |
118 | ||
119 | postPlay(move) { | |
120 | const piece = move.vanish[0].p; | |
121 | super.updateCastleFlags(move, piece, "twoKings"); | |
122 | } | |
123 | ||
124 | postUndo() {} | |
125 | }; |