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