Add Makruk, Shako and Shogi + a few fixes
[vchess.git] / client / src / variants / Makruk.js
CommitLineData
cd49e617
BA
1import { ChessRules, Move, PiPo } from "@/base_rules";
2import { ArrayFun } from "@/utils/array";
3import { randInt, shuffle } from "@/utils/alea";
4
5export class MakrukRules extends ChessRules {
6 static get HasFlags() {
7 return false;
8 }
9
10 static get HasEnpassant() {
11 return false;
12 }
13
14 static get PawnSpecs() {
15 return Object.assign(
16 {},
17 ChessRules.PawnSpecs,
18 {
19 twoSquares: false,
20 promotions: [V.QUEEN]
21 }
22 );
23 }
24
25 static get PIECES() {
26 return ChessRules.PIECES.concat(V.PROMOTED);
27 }
28
29 static get PROMOTED() {
30 return 'f';
31 }
32
33 static GenRandInitFen(randomness) {
34 if (randomness == 0)
35 return "rnbqkbnr/8/pppppppp/8/8/PPPPPPPP/8/RNBKQBNR w 0";
36
37 let pieces = { w: new Array(8), b: new Array(8) };
38 for (let c of ["w", "b"]) {
39 if (c == 'b' && randomness == 1) {
40 pieces['b'] = pieces['w'];
41 break;
42 }
43
44 // Get random squares for every piece, totally freely (no castling)
45 let positions = shuffle(ArrayFun.range(8));
46 const composition = ['b', 'b', 'r', 'r', 'n', 'n', 'k', 'q'];
47 for (let i = 0; i < 8; i++) pieces[c][positions[i]] = composition[i];
48 }
49 return (
50 pieces["b"].join("") +
51 "/8/pppppppp/8/8/PPPPPPPP/8/" +
52 pieces["w"].join("").toUpperCase() +
53 " w 0"
54 );
55 }
56
57 getPpath(b) {
58 return "Makruk/" + b;
59 }
60
61 getPotentialMovesFrom([x, y]) {
62 if (this.getPiece(x, y) == V.PROMOTED)
63 return this.getPotentialQueenMoves([x, y]);
64 return super.getPotentialMovesFrom([x, y]);
65 }
66
67 getPotentialPawnMoves([x, y]) {
68 const color = this.turn;
69 const shiftX = V.PawnSpecs.directions[color];
70 const sixthRank = (color == 'w' ? 2 : 5);
71 const tr = (x + shiftX == sixthRank ? { p: V.PROMOTED, c: color } : null);
72 let moves = [];
73 if (this.board[x + shiftX][y] == V.EMPTY)
74 // One square forward
75 moves.push(this.getBasicMove([x, y], [x + shiftX, y], tr));
76 // Captures
77 for (let shiftY of [-1, 1]) {
78 if (
79 y + shiftY >= 0 && y + shiftY < 8 &&
80 this.board[x + shiftX][y + shiftY] != V.EMPTY &&
81 this.canTake([x, y], [x + shiftX, y + shiftY])
82 ) {
83 moves.push(this.getBasicMove([x, y], [x + shiftX, y + shiftY], tr));
84 }
85 }
86 return moves;
87 }
88
89 getPotentialBishopMoves(sq) {
90 const forward = (this.turn == 'w' ? -1 : 1);
91 return this.getSlideNJumpMoves(
92 sq,
93 V.steps[V.BISHOP].concat([ [forward, 0] ]),
94 "oneStep"
95 );
96 }
97
98 getPotentialQueenMoves(sq) {
99 return this.getSlideNJumpMoves(
100 sq,
101 V.steps[V.BISHOP],
102 "oneStep"
103 );
104 }
105
106 isAttackedByBishop(sq, color) {
107 const forward = (this.turn == 'w' ? 1 : -1);
108 return this.isAttackedBySlideNJump(
109 sq,
110 color,
111 V.BISHOP,
112 V.steps[V.BISHOP].concat([ [forward, 0] ]),
113 "oneStep"
114 );
115 }
116
117 isAttackedByQueen(sq, color) {
118 return this.isAttackedBySlideNJump(
119 sq,
120 color,
121 V.QUEEN,
122 V.steps[V.BISHOP],
123 "oneStep"
124 );
125 }
126
127 static get VALUES() {
128 return {
129 p: 1,
130 r: 5,
131 n: 3,
132 b: 3,
133 q: 2,
134 f: 2,
135 k: 1000
136 };
137 }
138};