Generalize pawn movements: cleaner and smaller code
[vchess.git] / client / src / variants / Arena.js
1 import { ChessRules } from "@/base_rules";
2
3 export class ArenaRules extends ChessRules {
4 static get HasFlags() {
5 return false;
6 }
7
8 static get PawnSpecs() {
9 return Object.assign(
10 {},
11 ChessRules.PawnSpecs,
12 { captureBackward: true }
13 );
14 }
15
16 static GenRandInitFen(randomness) {
17 return ChessRules.GenRandInitFen(randomness).slice(0, -6) + "-";
18 }
19
20 static InArena(x) {
21 return Math.abs(3.5 - x) <= 1.5;
22 }
23
24 getPotentialMovesFrom([x, y]) {
25 const moves = super.getPotentialMovesFrom([x, y]);
26 // Eliminate moves which neither enter the arena or capture something
27 return moves.filter(m => {
28 const startInArena = V.InArena(m.start.x);
29 const endInArena = V.InArena(m.end.x);
30 return (
31 (startInArena && endInArena && m.vanish.length == 2) ||
32 (!startInArena && endInArena)
33 );
34 });
35
36 return moves;
37 }
38
39 getPotentialQueenMoves(sq) {
40 return this.getSlideNJumpMoves(
41 sq,
42 V.steps[V.ROOK].concat(V.steps[V.BISHOP])
43 ).filter(m => {
44 // Filter out moves longer than 3 squares
45 return Math.max(
46 Math.abs(m.end.x - m.start.x),
47 Math.abs(m.end.y - m.start.y)) <= 3;
48 });
49 }
50
51 getPotentialKingMoves(sq) {
52 return this.getSlideNJumpMoves(
53 sq,
54 V.steps[V.ROOK].concat(V.steps[V.BISHOP])
55 ).filter(m => {
56 // Filter out moves longer than 3 squares
57 return Math.max(
58 Math.abs(m.end.x - m.start.x),
59 Math.abs(m.end.y - m.start.y)) <= 3;
60 });
61 }
62
63 getCheckSquares() {
64 return [];
65 }
66
67 filterValid(moves) {
68 // No check conditions
69 return moves;
70 }
71
72 getCurrentScore() {
73 const color = this.turn;
74 if (!this.atLeastOneMove())
75 // I cannot move anymore
76 return color == "w" ? "0-1" : "1-0";
77 // Win if the opponent has no more pieces left (in the Arena),
78 // (and/)or if he lost both his dukes.
79 let someUnitRemain = false;
80 let atLeastOneDuke = false;
81 let somethingInArena = false;
82 outerLoop: for (let i=0; i<V.size.x; i++) {
83 for (let j=0; j<V.size.y; j++) {
84 if (this.getColor(i,j) == color) {
85 someUnitRemain = true;
86 if (this.movesCount >= 2 && V.InArena(i)) {
87 somethingInArena = true;
88 if (atLeastOneDuke)
89 break outerLoop;
90 }
91 if ([V.QUEEN,V.KING].includes(this.getPiece(i,j))) {
92 atLeastOneDuke = true;
93 if (this.movesCount < 2 || somethingInArena)
94 break outerLoop;
95 }
96 }
97 }
98 }
99 if (
100 !someUnitRemain ||
101 !atLeastOneDuke ||
102 (this.movesCount >= 2 && !somethingInArena)
103 ) {
104 return color == "w" ? "0-1" : "1-0";
105 }
106 return "*";
107 }
108
109 static get SEARCH_DEPTH() {
110 return 4;
111 }
112 };