Commit | Line | Data |
---|---|---|
f55a0a67 | 1 | import ChessRules from "/base_rules.js"; |
f3e90e30 BA |
2 | import {ArrayFun} from "/utils/array.js"; |
3 | import {Random} from "/utils/alea.js"; | |
f55a0a67 BA |
4 | |
5 | export default class AlapoRules extends ChessRules { | |
6 | ||
6b9320bb BA |
7 | static get Options() { |
8 | return { | |
9 | select: C.Options.select, | |
10 | styles: C.Options.styles.filter(s => s != "teleport") | |
11 | }; | |
12 | } | |
13 | ||
f55a0a67 BA |
14 | get hasFlags() { |
15 | return false; | |
16 | } | |
17 | get hasEnpassant() { | |
18 | return false; | |
19 | } | |
20 | ||
21 | getSvgChessboard() { | |
22 | let board = super.getSvgChessboard().slice(0, -6); | |
23 | // Add lines to delimitate goals | |
24 | board += ` | |
25 | <line x1="0" y1="10" x2="60" y2="10" stroke="black" stroke-width="0.1"/> | |
26 | <line x1="0" y1="50" x2="60" y2="50" stroke="black" stroke-width="0.1"/> | |
27 | </svg>`; | |
28 | return board; | |
29 | } | |
30 | ||
31 | genRandInitFen(seed) { | |
32 | if (this.options["randomness"] == 0) | |
33 | return "rbqqbr/tcssct/6/6/TCSSCT/RBQQBR w 0"; | |
34 | ||
35 | Random.setSeed(seed); | |
36 | ||
37 | const piece2pawn = { | |
38 | r: 't', | |
39 | q: 's', | |
40 | b: 'c' | |
41 | }; | |
42 | ||
43 | let pieces = { w: new Array(6), b: new Array(6) }; | |
44 | // Shuffle pieces on first (and last rank if randomness == 2) | |
45 | for (let c of ["w", "b"]) { | |
46 | if (c == 'b' && this.options["randomness"] == 1) { | |
47 | pieces['b'] = pieces['w']; | |
48 | break; | |
49 | } | |
50 | ||
51 | let positions = ArrayFun.range(6); | |
52 | ||
53 | // Get random squares for bishops | |
54 | let randIndex = 2 * Random.randInt(3); | |
55 | const bishop1Pos = positions[randIndex]; | |
56 | let randIndex_tmp = 2 * Random.randInt(3) + 1; | |
57 | const bishop2Pos = positions[randIndex_tmp]; | |
58 | positions.splice(Math.max(randIndex, randIndex_tmp), 1); | |
59 | positions.splice(Math.min(randIndex, randIndex_tmp), 1); | |
60 | ||
61 | // Get random square for queens | |
62 | randIndex = Random.randInt(4); | |
63 | const queen1Pos = positions[randIndex]; | |
64 | positions.splice(randIndex, 1); | |
65 | randIndex = Random.randInt(3); | |
66 | const queen2Pos = positions[randIndex]; | |
67 | positions.splice(randIndex, 1); | |
68 | ||
69 | // Rooks positions are now fixed, | |
70 | const rook1Pos = positions[0]; | |
71 | const rook2Pos = positions[1]; | |
72 | ||
73 | pieces[c][rook1Pos] = "r"; | |
74 | pieces[c][bishop1Pos] = "b"; | |
75 | pieces[c][queen1Pos] = "q"; | |
76 | pieces[c][queen2Pos] = "q"; | |
77 | pieces[c][bishop2Pos] = "b"; | |
78 | pieces[c][rook2Pos] = "r"; | |
79 | } | |
80 | ||
81 | return ( | |
82 | pieces["b"].join("") + "/" + | |
83 | pieces["b"].map(p => piece2pawn[p]).join("") + | |
84 | "/6/6/" + | |
85 | pieces["w"].map(p => piece2pawn[p].toUpperCase()).join("") + "/" + | |
86 | pieces["w"].join("").toUpperCase() + | |
87 | " w 0" | |
88 | ); | |
89 | } | |
90 | ||
65cf1690 | 91 | // Triangles are rotated from opponent viewpoint (=> suffix "_inv") |
f55a0a67 | 92 | pieces(color, x, y) { |
65cf1690 | 93 | const allSpecs = super.pieces(color, x, y); |
f55a0a67 | 94 | return { |
65cf1690 BA |
95 | 'r': allSpecs['r'], |
96 | 'q': allSpecs['q'], | |
97 | 'b': Object.assign({}, allSpecs['b'], | |
98 | {"class": "bishop" + (this.playerColor != color ? "_inv" : "")}), | |
f55a0a67 BA |
99 | 's': { //"square" |
100 | "class": "babyrook", | |
101 | moves: [ | |
102 | { | |
103 | steps: [[0, 1], [0, -1], [1, 0], [-1, 0]], | |
104 | range: 1 | |
105 | } | |
106 | ] | |
107 | }, | |
108 | 'c': { //"circle" | |
109 | "class": "babyqueen", | |
110 | moves: [ | |
111 | { | |
112 | steps: [ | |
113 | [0, 1], [0, -1], [1, 0], [-1, 0], | |
114 | [1, 1], [1, -1], [-1, 1], [-1, -1] | |
115 | ], | |
116 | range: 1 | |
117 | } | |
118 | ] | |
119 | }, | |
120 | 't': { //"triangle" | |
121 | "class": "babybishop" + (this.playerColor != color ? "_inv" : ""), | |
122 | moves: [ | |
123 | { | |
124 | steps: [[1, 1], [1, -1], [-1, 1], [-1, -1]], | |
125 | range: 1 | |
126 | } | |
127 | ] | |
128 | } | |
129 | }; | |
130 | } | |
131 | ||
132 | get size() { | |
133 | return { | |
134 | x: 6, | |
135 | y: 6 | |
136 | }; | |
137 | } | |
138 | ||
139 | filterValid(moves) { | |
140 | return moves; | |
141 | } | |
142 | ||
143 | getCurrentScore() { | |
144 | // Try both colors (to detect potential suicides) | |
145 | let won = {}; | |
146 | for (let c of ['w', 'b']) { | |
147 | const oppCol = C.GetOppCol(c); | |
148 | const goal = (c == 'w' ? 0 : 5); | |
149 | won[c] = this.board[goal].some((b,j) => { | |
150 | return ( | |
151 | this.getColor(goal, j) == c && | |
6b9320bb BA |
152 | !this.findCapturesOn( |
153 | [goal, j], | |
154 | { | |
155 | one: true, | |
156 | oppCol: oppCol, | |
157 | segments: this.options["cylinder"] | |
158 | } | |
159 | ) | |
f55a0a67 BA |
160 | ); |
161 | }); | |
162 | } | |
163 | if (won['w'] && won['b']) | |
164 | return "?"; //no idea who won, not relevant anyway :) | |
165 | return (won['w'] ? "1-0" : (won['b'] ? "0-1" : "*")); | |
166 | } | |
167 | ||
168 | }; |