91a0fe67ce89e3394388d004fc6a6588fca9c33f
1 import ChessRules
from "/base_rules.js";
2 import PiPo
from "/utils/PiPo.js";
3 import Move
from "/utils/Move.js";
5 export default class HexRules
extends ChessRules
{
42 this.playerColor
!= this.turn
||
44 this.board
[coords
.x
][coords
.y
] != "" &&
45 (!this.options
["swap"] || this.movesCount
>= 2)
51 start: {x: coords
.x
, y: coords
.y
},
62 if (this.board
[coords
.x
][coords
.y
] != "") {
67 c: C
.GetOppCol(this.turn
),
76 // NOTE: size.x == size.y (square boards)
77 const emptyCount
= C
.FenEmptySquares(this.size
.x
);
78 return (emptyCount
+ "/").repeat(this.size
.x
).slice(0, -1) + " w 0";
81 // TODO: enable vertical board (rotate?)
83 // NOTE: with small margin seems nicer
84 let width
= 173.2 * this.size
.y
+ 173.2 * (this.size
.y
-1) / 2 + 30,
85 height
= 50 + Math
.floor(150 * this.size
.x
) + 30,
88 // if (this.size.ratio < 1) {
89 // [width, height] = [height, width];
90 // [min_x, min_y] = [min_y, min_x];
94 viewBox="${min_x} ${min_y} ${width} ${height}"
95 class="chessboard_SVG"`;
96 // if (this.size.ratio < 1)
97 // board += ` transform="rotate(90 ${min_x} ${min_y})"`
102 style="stroke:#000000;stroke-width:1"
103 points="0,-100.0 86.6,-50.0 86.6,50.0 0,100.0 -86.6,50.0 -86.6,-50.0"
108 for (let i
=0; i
< this.size
.x
; i
++) {
109 for (let j
=0; j
< this.size
.y
; j
++) {
113 class="neutral-square"
114 id="${this.coordsToId({x: i, y: j})}"
115 x="${173.2*j + 86.6*i}"
120 board
+= `</g><g style="fill:none;stroke-width:10">`;
121 // Goals: up/down/left/right
122 board
+= `<polyline style="stroke:red" points="`
123 for (let i
=0; i
<=2*this.size
.y
; i
++)
124 board
+= ((i
-1)*86.6) + ',' + (i
% 2 == 0 ? -50 : -100) + ' ';
125 board
+= `"/><polyline style="stroke:red" points="`;
126 for (let i
=1; i
<=2*this.size
.y
; i
++) {
127 const jShift
= 200 * Math
.floor((this.size
.y
+1)/2) +
128 100 * (Math
.floor(this.size
.y
/2) - 1) +
129 (i
% 2 == 0 ? -50 : 0) +
130 (this.size
.y
% 2 == 0 ? 50 : 0);
131 board
+= ((i
+this.size
.y
-2)*86.6) + ',' + jShift
+ ' ';
133 board
+= `"/><polyline style="stroke:blue" points="`;
135 for (let i
=0; i
<=2*this.size
.x
; i
++) {
136 board
+= ((Math
.floor(i
/2)-1) * 86.6) + ',' +
137 (sumY
+= (i
% 2 == 0 ? 50 : 100)) + ' ';
139 board
+= `"/><polyline style="stroke:blue" points="`;
141 for (let i
=0; i
<2*this.size
.x
; i
++) {
142 board
+= (173.2*this.size
.x
+ (Math
.floor(i
/2)-1) * 86.6) + ',' +
143 (sumY
+= (i
% 2 == 0 ? 50 : 100)) + ' ';
145 board
+= `"/></g></svg>`;
150 for (let i
=0; i
<this.size
.x
; i
++) {
151 for (let j
=0; j
<this.size
.y
; j
++) {
152 if (this.board
[i
][j
] != "") {
153 const sqColor
= (this.getColor(i
, j
) == 'w' ? "white" : "black");
154 const elt
= document
.getElementById(this.coordsToId({x: i
, y: j
}));
155 elt
.classList
.remove("neutral-square");
156 elt
.classList
.add("bg-" + sqColor
);
163 const mousedown
= (e
) => {
164 if (e
.touches
&& e
.touches
.length
> 1)
166 const cd
= this.idToCoords(e
.target
.id
);
168 const move = this.doClick(cd
);
170 this.playPlusVisual(move);
174 if ('onmousedown' in window
) {
175 document
.addEventListener("mousedown", mousedown
);
176 document
.addEventListener("wheel",
177 (e
) => this.rescale(e
.deltaY
< 0 ? "up" : "down"));
179 if ('ontouchstart' in window
)
180 document
.addEventListener("touchstart", mousedown
, {passive: false});
183 // TODO: enable rotation
185 const baseRatio
= 1.619191; // 2801.2 / 1730, "widescreen"
186 const rotate
= false; //window.innerWidth < window.innerHeight; //"vertical screen"
188 x: this.options
["bsize"],
189 y: this.options
["bsize"],
190 ratio: (rotate
? 1 / baseRatio : baseRatio
)
195 this.playOnBoard(move);
197 this.turn
= C
.GetOppCol(this.turn
);
200 getCurrentScore(move) {
201 const oppCol
= C
.GetOppCol(this.turn
);
202 // Search for connecting path of opp color:
203 let explored
= {}, component
;
205 const getIndex
= (x
, y
) => x
+ "." + y
;
206 // Explore one connected component:
207 const neighborsSearch
= ([x
, y
], index
) => {
208 // Let's say "white" connects on x and "black" on y
209 const z
= (oppCol
== 'w' ? x : y
);
214 explored
[index
] = true;
215 component
[index
] = true;
216 for (let [dx
, dy
] of super.pieces()['k'].moves
[0].steps
) {
217 const [nx
, ny
] = [x
+ dx
, y
+ dy
];
218 const nidx
= getIndex(nx
, ny
);
220 this.onBoard(nx
, ny
) &&
221 this.getColor(nx
, ny
) == oppCol
&&
224 neighborsSearch([nx
, ny
], nidx
);
228 // Explore all components:
229 for (let i
=0; i
<this.size
.x
; i
++) {
230 for (let j
=0; j
<this.size
.y
; j
++) {
231 const index
= getIndex(i
, j
);
232 if (this.getColor(i
, j
) == oppCol
&& !explored
[index
]) {
234 [min
, max
] = [this.size
.x
, 0];
235 neighborsSearch([i
, j
], index
);
236 if (max
- min
== this.size
.x
- 1)
237 return (oppCol
== "w" ? "1-0" : "0-1");
245 move.vanish
.forEach(v
=> {
246 let elt
= document
.getElementById(this.coordsToId({x: v
.x
, y: v
.y
}));
247 elt
.classList
.remove("bg-" + (v
.c
== 'w' ? "white" : "black"));
249 move.appear
.forEach(a
=> {
250 let elt
= document
.getElementById(this.coordsToId({x: a
.x
, y: a
.y
}));
251 elt
.classList
.add("bg-" + (a
.c
== 'w' ? "white" : "black"));