1 import AbstractClickFillRules
from "/variants/_ClickFill/class.js";
2 import PiPo
from "/utils/PiPo.js";
3 import Move
from "/utils/Move.js";
5 export default class HexRules
extends AbstractClickFillRules
{
44 this.playerColor
!= this.turn
||
46 this.board
[coords
.x
][coords
.y
] != "" &&
47 (!this.options
["swap"] || this.movesCount
>= 2)
53 start: {x: coords
.x
, y: coords
.y
},
64 if (this.board
[coords
.x
][coords
.y
] != "") {
69 c: C
.GetOppTurn(this.turn
),
77 genRandInitBaseFen() {
78 // NOTE: size.x == size.y (square boards)
79 const emptyCount
= C
.FenEmptySquares(this.size
.x
);
81 fen: (emptyCount
+ "/").repeat(this.size
.x
- 1) + emptyCount
,
87 // NOTE: with small margin seems nicer
88 let width
= 173.2 * this.size
.y
+ 173.2 * (this.size
.y
-1) / 2 + 30,
89 height
= 50 + Math
.floor(150 * this.size
.x
) + 30,
92 if (this.size
.ratio
< 1) {
93 // Rotate by 30 degrees to display vertically
94 [width
, height
] = [height
, width
];
95 [min_x
, min_y
] = [min_y
, min_x
];
99 viewBox="${min_x} ${min_y} ${width} ${height}"
100 class="chessboard_SVG">
104 style="stroke:#000000;stroke-width:1"
105 points="0,-100.0 86.6,-50.0 86.6,50.0 0,100.0 -86.6,50.0 -86.6,-50.0"
110 if (this.size
.ratio
< 1)
111 board
+= ` transform="rotate(30)"`
113 for (let i
=0; i
< this.size
.x
; i
++) {
114 for (let j
=0; j
< this.size
.y
; j
++) {
118 class="neutral-square"
119 id="${this.coordsToId({x: i, y: j})}"
120 x="${173.2*j + 86.6*i}"
125 board
+= `</g><g style="fill:none;stroke-width:10"`;
126 if (this.size
.ratio
< 1)
127 board
+= ` transform="rotate(30)"`
128 // Goals: up/down/left/right
129 board
+= `><polyline style="stroke:red" points="`
130 for (let i
=0; i
<=2*this.size
.y
; i
++)
131 board
+= ((i
-1)*86.6) + ',' + (i
% 2 == 0 ? -50 : -100) + ' ';
132 board
+= `"/><polyline style="stroke:red" points="`;
133 for (let i
=1; i
<=2*this.size
.y
; i
++) {
134 const jShift
= 200 * Math
.floor((this.size
.y
+1)/2) +
135 100 * (Math
.floor(this.size
.y
/2) - 1) +
136 (i
% 2 == 0 ? -50 : 0) +
137 (this.size
.y
% 2 == 0 ? 50 : 0);
138 board
+= ((i
+this.size
.y
-2)*86.6) + ',' + jShift
+ ' ';
140 board
+= `"/><polyline style="stroke:blue" points="`;
142 for (let i
=0; i
<=2*this.size
.x
; i
++) {
143 board
+= ((Math
.floor(i
/2)-1) * 86.6) + ',' +
144 (sumY
+= (i
% 2 == 0 ? 50 : 100)) + ' ';
146 board
+= `"/><polyline style="stroke:blue" points="`;
148 for (let i
=0; i
<2*this.size
.x
; i
++) {
149 board
+= (173.2*this.size
.x
+ (Math
.floor(i
/2)-1) * 86.6) + ',' +
150 (sumY
+= (i
% 2 == 0 ? 50 : 100)) + ' ';
152 board
+= `"/></g></svg>`;
157 const baseRatio
= 1.6191907514450865; //2801.2 / 1730, "widescreen"
159 document
.getElementById(this.containerId
).getBoundingClientRect();
160 const rotate
= rc
.width
< rc
.height
; //"vertical screen"
162 x: this.options
["bsize"],
163 y: this.options
["bsize"],
164 ratio: (rotate
? 1 / baseRatio : baseRatio
)
169 this.playOnBoard(move);
171 this.turn
= C
.GetOppTurn(this.turn
);
175 const oppCol
= C
.GetOppTurn(this.turn
);
176 // Search for connecting path of opp color:
177 let explored
= {}, component
;
179 const getIndex
= (x
, y
) => x
+ "." + y
;
180 // Explore one connected component:
181 const neighborsSearch
= ([x
, y
], index
) => {
182 // Let's say "white" connects on x and "black" on y
183 const z
= (oppCol
== 'w' ? x : y
);
188 explored
[index
] = true;
189 component
[index
] = true;
190 for (let [dx
, dy
] of super.pieces()['k'].both
[0].steps
) {
191 const [nx
, ny
] = [x
+ dx
, y
+ dy
];
192 const nidx
= getIndex(nx
, ny
);
194 this.onBoard(nx
, ny
) &&
195 this.getColor(nx
, ny
) == oppCol
&&
198 neighborsSearch([nx
, ny
], nidx
);
202 // Explore all components:
203 for (let i
=0; i
<this.size
.x
; i
++) {
204 for (let j
=0; j
<this.size
.y
; j
++) {
205 const index
= getIndex(i
, j
);
206 if (this.getColor(i
, j
) == oppCol
&& !explored
[index
]) {
208 [min
, max
] = [this.size
.x
, 0];
209 neighborsSearch([i
, j
], index
);
210 if (max
- min
== this.size
.x
- 1)
211 return (oppCol
== "w" ? "1-0" : "0-1");