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