Add Forward + Doubleorda variants
[vchess.git] / client / src / variants / Doubleorda.js
CommitLineData
0b8bd121
BA
1import { ChessRules } from "@/base_rules";
2import { OrdaRules } from "@/variants/Orda";
3import { ArrayFun } from "@/utils/array";
4import { randInt } from "@/utils/alea";
5
6export class DoubleordaRules extends OrdaRules {
7 static get PawnSpecs() {
8 return Object.assign(
9 {},
10 ChessRules.PawnSpecs,
11 { promotions: [V.LANCER, V.ARCHER, V.KHESHIG, V.FALCON] }
12 );
13 }
14
15 static get HasFlags() {
16 return false;
17 }
18
19 static get HasEnpassant() {
20 return false;
21 }
22
23 getPpath(b) {
24 return "Orda/" + b;
25 }
26
27 static GenRandInitFen(randomness) {
28 if (randomness == 0)
29 return "lhafkahl/8/pppppppp/8/8/PPPPPPPP/8/LHAFKAHL w 0 ah -";
30
31 let pieces = { w: new Array(8), b: new Array(8) };
32 // Shuffle pieces on first (and last rank if randomness == 2)
33 for (let c of ["w", "b"]) {
34 if (c == 'b' && randomness == 1) {
35 pieces['b'] = pieces['w'];
36 break;
37 }
38
39 let positions = ArrayFun.range(8);
40
41 let randIndex = 2 * randInt(4);
42 const bishop1Pos = positions[randIndex];
43 let randIndex_tmp = 2 * randInt(4) + 1;
44 const bishop2Pos = positions[randIndex_tmp];
45 positions.splice(Math.max(randIndex, randIndex_tmp), 1);
46 positions.splice(Math.min(randIndex, randIndex_tmp), 1);
47
48 randIndex = randInt(6);
49 const knight1Pos = positions[randIndex];
50 positions.splice(randIndex, 1);
51 randIndex = randInt(5);
52 const knight2Pos = positions[randIndex];
53 positions.splice(randIndex, 1);
54
55 randIndex = randInt(4);
56 const queenPos = positions[randIndex];
57 positions.splice(randIndex, 1);
58
59 const rook1Pos = positions[0];
60 const kingPos = positions[1];
61 const rook2Pos = positions[2];
62
63 pieces[c][rook1Pos] = "l";
64 pieces[c][knight1Pos] = "h";
65 pieces[c][bishop1Pos] = "a";
66 pieces[c][queenPos] = "f";
67 pieces[c][kingPos] = "k";
68 pieces[c][bishop2Pos] = "a";
69 pieces[c][knight2Pos] = "h";
70 pieces[c][rook2Pos] = "l";
71 }
72 return (
73 pieces["b"].join("") +
74 "/8/pppppppp/8/8/PPPPPPPP/8/" +
75 pieces["w"].join("").toUpperCase() +
76 " w 0"
77 );
78 }
79
80 static get FALCON() {
81 return 'f';
82 }
83
84 static get PIECES() {
85 return [V.LANCER, V.ARCHER, V.KHESHIG, V.FALCON, V.KING];
86 }
87
88 getPotentialMovesFrom(sq) {
89 switch (this.getPiece(sq[0], sq[1])) {
90 case V.PAWN:
91 return super.getPotentialPawnMoves(sq);
92 case V.LANCER:
93 return super.getPotentialLancerMoves(sq);
94 case V.ARCHER:
95 return super.getPotentialArcherMoves(sq);
96 case V.KHESHIG:
97 return super.getPotentialKheshigMoves(sq);
98 case V.FALCON:
99 return this.getPotentialFalconMoves(sq);
100 case V.KING:
101 return super.getPotentialKingMoves(sq)
102 }
103 return []; //never reached
104 }
105
106 getPotentialFalconMoves(sq) {
107 const onlyMoves = this.getSlideNJumpMoves(
108 sq,
109 V.steps[V.ROOK].concat(V.steps[V.BISHOP]),
110 null,
111 { onlyMove: true }
112 );
113 const onlyTakes = this.getSlideNJumpMoves(
114 sq,
115 V.steps[V.KNIGHT],
116 "oneStep",
117 { onlyTake: true }
118 );
119 return onlyMoves.concat(onlyTakes);
120 }
121
122 isAttacked(sq, color) {
123 return (
124 super.isAttackedByPawn(sq, color) ||
125 super.isAttackedByLancer(sq, color) ||
126 super.isAttackedByKheshig(sq, color) ||
127 super.isAttackedByArcher(sq, color) ||
128 this.isAttackedByFalcon(sq, color) ||
129 super.isAttackedByKing(sq, color)
130 );
131 }
132
133 isAttackedByFalcon(sq, color) {
134 return this.isAttackedBySlideNJump(
135 sq, color, V.FALCON, V.steps[V.KNIGHT], "oneStep");
136 }
137
138 static get VALUES() {
139 return {
140 p: 1,
141 f: 7,
142 a: 4,
143 h: 7,
144 l: 4,
145 k: 1000
146 };
147 }
148};