--- /dev/null
+Full detection of repeated positions (including turn)
+Debug HalfChess
+Implement UltimaChess
// END OF GAME
// Basic check for 3 repetitions (in the last moves only)
+ // TODO: extend to usual 3-repetition recognition (storing FEN with move?)
checkRepetition()
{
if (this.moves.length >= 8)
// Setup the initial random (assymetric) position
static GenRandInitFen()
{
- let pieces = [new Array(8), new Array(8)];
+ let pieces = { "w": new Array(8), "b": new Array(8) };
// Shuffle pieces on first and last rank
- for (let c = 0; c <= 1; c++)
+ for (let c of ["w","b"])
{
let positions = _.range(8);
pieces[c][knight2Pos] = 'n';
pieces[c][rook2Pos] = 'r';
}
- let fen = pieces[0].join("") +
+ let fen = pieces["b"].join("") +
"/pppppppp/8/8/8/8/PPPPPPPP/" +
- pieces[1].join("").toUpperCase() +
+ pieces["w"].join("").toUpperCase() +
" 1111"; //add flags
return fen;
}
},
render(h) {
const [sizeX,sizeY] = VariantRules.size;
+ console.log(sizeX + " " + sizeY);
const smallScreen = (screen.width <= 420);
// Precompute hints squares to facilitate rendering
let hintSquares = doubleArray(sizeX, sizeY, false);
--- /dev/null
+class HalfRules extends ChessRules
+{
+ // Standard rules on a 4x8 board with no pawns
+
+ initVariables(fen) { } //nothing to do
+
+ setFlags(fen)
+ {
+ // No castling, hence no flags; but flags defined for compatibility
+ this.castleFlags = { "w":[false,false], "b":[false,false] };
+ }
+
+ static get size() { return [8,4]; }
+
+ getPotentialKingMoves(sq)
+ {
+ const V = VariantRules;
+ // No castling
+ return this.getSlideNJumpMoves(sq,
+ V.steps[V.ROOK].concat(V.steps[V.BISHOP]), "oneStep");
+ }
+
+ isAttacked(sq, colors)
+ {
+ return (this.isAttackedByRook(sq, colors)
+ || this.isAttackedByKnight(sq, colors)
+ || this.isAttackedByBishop(sq, colors)
+ || this.isAttackedByQueen(sq, colors)
+ || this.isAttackedByKing(sq, colors));
+ }
+
+ // Unused:
+ updateVariables(move) { }
+ unupdateVariables(move) { }
+
+ static get SEARCH_DEPTH() { return 4; }
+
+ static GenRandInitFen()
+ {
+ let minorPieces = { "w": new Array(4), "b": new Array(4) };
+ let majorPieces = { "w": new Array(4), "b": new Array(4) };
+ for (let c of ["w","b"])
+ {
+ // Minor pieces first (on 2nd rank)
+ let positions = _.range(4);
+
+ // Get random squares for bishops
+ let randIndex = 2 * _.random(1);
+ let bishop1Pos = positions[randIndex];
+ let randIndex_tmp = 2 * _.random(1) + 1;
+ let bishop2Pos = positions[randIndex_tmp];
+ positions.splice(Math.max(randIndex,randIndex_tmp), 1);
+ positions.splice(Math.min(randIndex,randIndex_tmp), 1);
+
+ // Get random squares for knights
+ randIndex = _.random(1);
+ let knight1Pos = positions[randIndex];
+ positions.splice(randIndex, 1);
+ let knight2Pos = positions[0];
+
+ minorPieces[c][bishop1Pos] = 'b';
+ minorPieces[c][bishop2Pos] = 'b';
+ minorPieces[c][knight1Pos] = 'n';
+ minorPieces[c][knight2Pos] = 'n';
+
+ // Major pieces then (on 1st rank)
+ positions = _.range(4);
+
+ // Get random square for queen
+ randIndex = _.random(3);
+ let queenPos = positions[randIndex];
+ positions.splice(randIndex, 1);
+
+ // Rooks and king positions:
+ let rook1Pos = positions[0];
+ let kingPos = positions[1];
+ let rook2Pos = positions[2];
+
+ majorPieces[c][rook1Pos] = 'r';
+ majorPieces[c][rook2Pos] = 'r';
+ majorPieces[c][kingPos] = 'k';
+ majorPieces[c][queenPos] = 'q';
+ }
+ return majorPieces["b"].join("") + "/" + minorPieces["b"].join("") + "/4/4/4/4/" +
+ minorPieces["w"].join("").toUpperCase() + "/" +
+ majorPieces["w"].join("").toUpperCase() + " 0000"; //TODO: flags?!
+ }
+}
// Unused:
updateVariables(move) { }
unupdateVariables(move) { }
- parseFlags(flags) { }
getFlagsFen()
{
--- /dev/null
+class UltimaRules extends ChessRules
+{
+ // TODO: think about move UI for "removing an immobilized piece from the board"
+ // (extend game.js and feedback Rules.js with "there was a click, is it a move?")
+
+ // TODO: Keep usual pieces names here (but comment with Ultima pieces names)
+ // Just change moving + capturing modes.
+}
display: inline-block
position: relative
+div.board4
+ width: 25%
+ padding-bottom: 25%
+
div.board8
width: 12.5%
padding-bottom: 12.5%
{ "name": "Crazyhouse", "description": "Captures reborn" },
{ "name": "Switching", "description": "Exchange pieces positions" },
{ "name": "Extinction", "description": "Capture all of a kind" },
+ { "name": "Ultima", "description": "Non-standard captures" },
+ { "name": "Half", "description": "Small board" },
];
--- /dev/null
+p.boxed
+ | 8x4 board with no pawns. Orthodox rules.
+
+figure.diagram-container
+ .diagram
+ | fen:rkqr/nbbn/4/4/4/4/NBBN/RKQR:
+ figcaption Initial position (non-random)
+
+h3 Specifications
+
+ul
+ li Chessboard: 8x4 (see diagram).
+ li Material: no pawns.
+ li Non-capturing moves: standard.
+ li Special moves: none.
+ li Captures: standard.
+ li End of game: standard.
+
+h3 Credits
+
+p
+ | This variant is shortly described on
+ a(href="https://www.chessvariants.com/small.dir/halfchess.html") chessvariants.com
+ | .
--- /dev/null
+p.boxed
+ | Pieces look the same but behave very differently.
+ | They generally move like an orthodox queen,
+ | but capturing rules are complex: you need to read on :)
+
+h3 Specifications
+
+ul
+ li Chessboard: standard.
+ li Material: "standard".
+ li Non-capturing moves: often like queen.
+ li Special moves: none.
+ li Captures: very special.
+ li End of game: standard; see below.
+
+h3 Non-capturing moves
+
+// TODO: short paragraph, only the king moves like an orthodox king
+
+h3 Capturing moves
+
+// TODO...
+
+h3 End of the game
+
+// TODO: show the situation from Wikipedia page
+
+h3 Credits
+
+p.
+ A good starting point is the
+ #[a(href="https://en.wikipedia.org/wiki/Baroque_chess") Wikipedia page],
+ which also gives pointers to other interesting pages (including chessvariants.com,
+ as usual).
Very few resources about this variation:
#[a(href="http://play.chessvariants.org/erf/ZenChess.html") this webpage]
and #[a(href="http://www.pathguy.com/chess/ZenChess.htm") this one].
- Ed Friedlander developed the Zen Chess applet from the link above.