More balanced Shinobi according to Couch Tomato + Fables tests
[vchess.git] / client / src / variants / Avalam2.js
1 import { ChessRules, Move, PiPo } from "@/base_rules";
2 import { randInt } from "@/utils/alea";
3
4 export class Avalam2Rules extends ChessRules {
5
6 static get HasFlags() {
7 return false;
8 }
9
10 static get HasEnpassant() {
11 return false;
12 }
13
14 static get Monochrome() {
15 return true;
16 }
17
18 get showFirstTurn() {
19 return true;
20 }
21
22 getPpath(b) {
23 return "Avalam/" + b;
24 }
25
26 static get PIECES() {
27 // Towers of 1, 2, 3, 4 and 5
28 return ['b', 'c', 'd', 'e', 'f'];
29 }
30
31 static IsGoodPosition(position) {
32 if (position.length == 0) return false;
33 const rows = position.split("/");
34 if (rows.length != V.size.x) return false;
35 for (let row of rows) {
36 let sumElts = 0;
37 for (let i = 0; i < row.length; i++) {
38 if (['x'].concat(V.PIECES).includes(row[i].toLowerCase())) sumElts++;
39 else {
40 const num = parseInt(row[i], 10);
41 if (isNaN(num)) return false;
42 sumElts += num;
43 }
44 }
45 if (sumElts != V.size.y) return false;
46 }
47 return true;
48 }
49
50 static GenRandInitFen() {
51 return (
52 "BbBbBbBb/bBbBbBbB/BbBbBbBb/bBbBbBbB/" +
53 "BbBbBbBb/bBbBbBbB/BbBbBbBb/bBbBbBbB w 0"
54 );
55 }
56
57 canIplay(side) {
58 return this.turn == side;
59 }
60
61 getColor() {
62 return this.turn; //:-)
63 }
64
65 getBasicMove([x1, y1], [x2, y2]) {
66 const cp1 = this.board[x1][y1],
67 cp2 = this.board[x2][y2];
68 const newPiece =
69 String.fromCharCode(cp1.charCodeAt(1) + cp2.charCodeAt(1) - 97);
70 return (
71 new Move({
72 vanish: [
73 new PiPo({ x: x1, y: y1, c: cp1[0], p: cp1[1] }),
74 new PiPo({ x: x2, y: y2, c: cp2[0], p: cp2[1] })
75 ],
76 appear: [
77 new PiPo({ x: x2, y: y2, c: cp1[0], p: newPiece })
78 ]
79 })
80 );
81 }
82
83 getPotentialMovesFrom([x, y]) {
84 const height = this.board[x][y].charCodeAt(1) - 97;
85 if (height == 5) return [];
86 let moves = [];
87 for (let s of V.steps[V.ROOK].concat(V.steps[V.BISHOP])) {
88 const [i, j] = [x + s[0], y + s[1]];
89 if (
90 V.OnBoard(i, j) &&
91 this.board[i][j] != V.EMPTY &&
92 (height + this.board[i][j].charCodeAt(1) - 97 <= 5)
93 ) {
94 moves.push(this.getBasicMove([x, y], [i, j]));
95 }
96 }
97 return moves;
98 }
99
100 filterValid(moves) {
101 return moves;
102 }
103
104 getCheckSquares() {
105 return [];
106 }
107
108 getCurrentScore() {
109 let towersCount = { w: 0, b: 0 };
110 for (let i = 0; i < V.size.x; i++) {
111 for (let j = 0; j < V.size.y; j++) {
112 if (this.board[i][j] != V.EMPTY) {
113 if (this.getPotentialMovesFrom([i, j]).length > 0) return '*';
114 towersCount[ this.board[i][j][0] ]++;
115 }
116 }
117 }
118 if (towersCount['w'] > towersCount['b']) return "1-0";
119 if (towersCount['b'] > towersCount['w']) return "0-1";
120 return "1/2";
121 }
122
123 getComputerMove() {
124 // Random mover (TODO)
125 const moves = super.getAllValidMoves();
126 if (moves.length == 0) return null;
127 return moves[randInt(moves.length)];
128 }
129
130 };