Several small improvements + integrate options + first working draft of Cwda
[vchess.git] / client / src / variants / Arena.js
1 import { ChessRules } from "@/base_rules";
2
3 export class ArenaRules extends ChessRules {
4
5 static get Lines() {
6 return [
7 [[2, 0], [2, 8]],
8 [[6, 0], [6, 8]]
9 ];
10 }
11
12 static get HasFlags() {
13 return false;
14 }
15
16 static get PawnSpecs() {
17 return Object.assign(
18 {},
19 ChessRules.PawnSpecs,
20 { captureBackward: true }
21 );
22 }
23
24 static IsGoodPosition(position) {
25 if (position.length == 0) return false;
26 const rows = position.split("/");
27 if (rows.length != V.size.x) return false;
28 // At most and at least one king or queen per color
29 let royals = { "k": 0, "K": 0, "q": 0, "Q": 0 };
30 for (let row of rows) {
31 let sumElts = 0;
32 for (let i = 0; i < row.length; i++) {
33 if (['K','k','Q','q'].includes(row[i])) royals[row[i]]++;
34 if (V.PIECES.includes(row[i].toLowerCase())) sumElts++;
35 else {
36 const num = parseInt(row[i], 10);
37 if (isNaN(num)) return false;
38 sumElts += num;
39 }
40 }
41 if (sumElts != V.size.y) return false;
42 }
43 if (
44 Object.values(royals).some(v => v >= 2) ||
45 royals['K'] + royals['Q'] == 0 ||
46 royals['k'] + royals['q'] == 0
47 ) {
48 return false;
49 }
50 return true;
51 }
52
53 scanKings() {}
54
55 static GenRandInitFen(options) {
56 return ChessRules.GenRandInitFen(options).slice(0, -6) + "-";
57 }
58
59 static InArena(x) {
60 return Math.abs(3.5 - x) <= 1.5;
61 }
62
63 getPotentialMovesFrom([x, y]) {
64 const moves = super.getPotentialMovesFrom([x, y]);
65 // Eliminate moves which neither enter the arena or capture something
66 return moves.filter(m => {
67 const startInArena = V.InArena(m.start.x);
68 const endInArena = V.InArena(m.end.x);
69 return (
70 (startInArena && endInArena && m.vanish.length == 2) ||
71 (!startInArena && endInArena)
72 );
73 });
74
75 return moves;
76 }
77
78 getPotentialQueenMoves(sq) {
79 return super.getSlideNJumpMoves(
80 sq, V.steps[V.ROOK].concat(V.steps[V.BISHOP]), 3);
81 }
82
83 getPotentialKingMoves(sq) {
84 return super.getSlideNJumpMoves(
85 sq, V.steps[V.ROOK].concat(V.steps[V.BISHOP]), 3);
86 }
87
88 getCheckSquares() {
89 return [];
90 }
91
92 filterValid(moves) {
93 // No check conditions
94 return moves;
95 }
96
97 postPlay() {} //no kingPos no castleFlags
98 postUndo() {}
99
100 getCurrentScore() {
101 const color = this.turn;
102 if (!this.atLeastOneMove())
103 // I cannot move anymore
104 return color == "w" ? "0-1" : "1-0";
105 // Win if the opponent has no more pieces left (in the Arena),
106 // (and/)or if he lost both his dukes.
107 let someUnitRemain = false;
108 let atLeastOneDuke = false;
109 let somethingInArena = false;
110 outerLoop: for (let i=0; i<V.size.x; i++) {
111 for (let j=0; j<V.size.y; j++) {
112 if (this.getColor(i,j) == color) {
113 someUnitRemain = true;
114 if (this.movesCount >= 2 && V.InArena(i)) {
115 somethingInArena = true;
116 if (atLeastOneDuke)
117 break outerLoop;
118 }
119 if ([V.QUEEN,V.KING].includes(this.getPiece(i,j))) {
120 atLeastOneDuke = true;
121 if (this.movesCount < 2 || somethingInArena)
122 break outerLoop;
123 }
124 }
125 }
126 }
127 if (
128 !someUnitRemain ||
129 !atLeastOneDuke ||
130 (this.movesCount >= 2 && !somethingInArena)
131 ) {
132 return color == "w" ? "0-1" : "1-0";
133 }
134 return "*";
135 }
136
137 static get SEARCH_DEPTH() {
138 return 4;
139 }
140
141 };