let challenges = {}; //variantName --> socketId, name
let games = {}; //gameId --> gameInfo (vname, fen, players, options, time)
-let moveHash = {}; //gameId --> set of hashes seen so far
let sockets = {}; //socketId --> socket
const variants = require("./variants.js");
const Crypto = require("crypto");
vname: vname,
players: players,
options: options,
- time: Date.now()
+ time: Date.now(),
+ moveHash: {} //set of moves hashes seen so far
};
return gid;
}
// Provide seed in case of, so that both players initialize with same FEN
function launchGame(gid) {
- moveHash[gid] = {};
const gameInfo = Object.assign(
{seed: Math.floor(Math.random() * 19840), gid: gid},
games[gid]
const hash = Crypto.createHash("md5")
.update(JSON.stringify(obj.fen))
.digest("hex");
- if (moveHash[hash])
+ if (games[obj.gid].moveHash[hash])
break;
- moveHash[hash] = true;
+ games[obj.gid].moveHash[hash] = true;
games[obj.gid].fen = obj.fen;
- games[obj.gid].time = Date.now(); //update timestamp in case of
+ games[obj.gid].time = Date.now(); //update useful if verrry slow game
const playingWhite = (games[obj.gid].players[0].sid == sid);
const oppSid = games[obj.gid].players[playingWhite ? 1 : 0].sid;
send(oppSid, "newmove", {moves: obj.moves});
{name: 'Absorption', desc: 'Absorb powers'},
{name: 'Alapo', desc: 'Geometric Chess'},
{name: 'Alice', desc: 'Both sides of the mirror'},
-// {name: 'Align4', desc: 'Align four pawns'},
+ {name: 'Align4', desc: 'Align four pawns'},
// {name: 'Allmate', desc: 'Mate any piece'},
{name: 'Ambiguous', desc: "Play opponent's pieces"},
// {name: 'Antiking1', desc: 'Keep antiking in check', disp: 'Anti-King'},
--- /dev/null
+import ChessRules from "/base_rules.js";
+
+export default class Align4Rules extends ChessRules {
+
+ static get Options() {
+ return {
+ select: [{
+ label: "Randomness",
+ variable: "randomness",
+ defaut: 0,
+ options: [
+ {label: "Deterministic", value: 0},
+ {label: "Random", value: 1}
+ ]
+ }],
+ styles: ["atomic", "capture", "cylinder"]
+ };
+ }
+
+ get hasReserve() {
+ return true;
+ }
+ get hasReserveFen() {
+ return false;
+ }
+
+ genRandInitFen(seed) {
+ const baseFen = super.genRandInitFen(seed);
+ return "4k3/8" + baseFen.substring(17, 50) + " -"; //TODO: + flags 1188
+ }
+
+ setOtherVariables(fenParsed) {
+ super.setOtherVariables(fenParsed);
+ this.reserve = { b: { p: 1 } };
+ }
+
+ // Just do not update any reserve (infinite supply)
+ updateReserve() {}
+
+ getCastleMoves([x, y]) {
+ if (this.GetColor(x, y) == 'b')
+ return [];
+ return super.getCastleMoves([x, y]);
+ }
+
+ getCurrentScore(move) {
+ const score = super.getCurrentScore(move);
+ if (score != "*")
+ return score;
+ // Check pawns connection:
+ for (let i = 0; i < this.size.x; i++) {
+ for (let j = 0; j < this.size.y; j++) {
+ if (
+ this.board[i][j] != "" &&
+ this.getColor(i, j) == 'b' &&
+ this.getPiece(i, j) == 'p'
+ ) {
+ // Exploration "rightward + downward" is enough
+ for (let step of [[1, 0], [0, 1], [1, 1], [-1, 1]]) {
+ let [ii, jj] = [i + step[0], j + step[1]];
+ let kounter = 1;
+ while (
+ this.onBoard(ii, jj) &&
+ this.board[ii][jj] != "" &&
+ this.getColor(ii, jj) == 'b' &&
+ this.getPiece(ii, jj) == 'p'
+ ) {
+ kounter++;
+ ii += step[0];
+ jj += step[1];
+ }
+ if (kounter == 4)
+ return "0-1";
+ }
+ }
+ }
+ }
+ return "*";
+ }
+
+};
--- /dev/null
+<p>
+ Black goal is to align 4 pawns, either orthogonaly or diagonaly.
+ White goal is to checkmate the black king.
+</p>
+
+<p class="author">Fynmorph [Discord] (2021).</p>
--- /dev/null
+@import url("/base_pieces.css");