Add temporary patch for preset challenges
[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(randomness) {
40 if (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' && 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,
99 V.steps[V.BISHOP].concat([ [forward, 0] ]),
100 "oneStep"
101 );
102 }
103
104 getPotentialQueenMoves(sq) {
105 return this.getSlideNJumpMoves(
106 sq,
107 V.steps[V.BISHOP],
108 "oneStep"
109 );
110 }
111
112 isAttacked(sq, color) {
113 return (
114 super.isAttacked(sq, color) || this.isAttackedByPromoted(sq, color)
115 );
116 }
117
118 isAttackedByBishop(sq, color) {
119 const forward = (color == 'w' ? 1 : -1);
120 return this.isAttackedBySlideNJump(
121 sq,
122 color,
123 V.BISHOP,
124 V.steps[V.BISHOP].concat([ [forward, 0] ]),
125 "oneStep"
126 );
127 }
128
129 isAttackedByQueen(sq, color) {
130 return this.isAttackedBySlideNJump(
131 sq,
132 color,
133 V.QUEEN,
134 V.steps[V.BISHOP],
135 "oneStep"
136 );
137 }
138
139 isAttackedByPromoted(sq, color) {
140 return super.isAttackedBySlideNJump(
141 sq,
142 color,
143 V.PROMOTED,
144 V.steps[V.BISHOP],
145 "oneStep"
146 );
147 }
148
149 static get VALUES() {
150 return {
151 p: 1,
152 r: 5,
153 n: 3,
154 b: 3,
155 q: 2,
156 f: 2,
157 k: 1000
158 };
159 }
160
161 };