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