Fix HalfChess, more random Loser initial position, continue draft of Ultima
[vchess.git] / public / javascripts / variants / Half.js
1 // Standard rules on a 4x8 board with no pawns
2 class HalfRules extends ChessRules
3 {
4 initVariables(fen)
5 {
6 this.kingPos = {'w':[-1,-1], 'b':[-1,-1]};
7 const fenParts = fen.split(" ");
8 const position = fenParts[0].split("/");
9 for (let i=0; i<position.length; i++)
10 {
11 let k = 0;
12 for (let j=0; j<position[i].length; j++)
13 {
14 switch (position[i].charAt(j))
15 {
16 case 'k':
17 this.kingPos['b'] = [i,k];
18 break;
19 case 'K':
20 this.kingPos['w'] = [i,k];
21 break;
22 default:
23 let num = parseInt(position[i].charAt(j));
24 if (!isNaN(num))
25 k += (num-1);
26 }
27 k++;
28 }
29 }
30 // No pawns so no ep., but otherwise we must redefine play()
31 this.epSquares = [];
32 }
33
34 setFlags(fen)
35 {
36 // No castling, hence no flags; but flags defined for compatibility
37 this.castleFlags = { "w":[false,false], "b":[false,false] };
38 }
39
40 static get size() { return [4,8]; }
41
42 getPotentialKingMoves(sq)
43 {
44 const V = VariantRules;
45 // No castling
46 return this.getSlideNJumpMoves(sq,
47 V.steps[V.ROOK].concat(V.steps[V.BISHOP]), "oneStep");
48 }
49
50 isAttacked(sq, colors)
51 {
52 return (this.isAttackedByRook(sq, colors)
53 || this.isAttackedByKnight(sq, colors)
54 || this.isAttackedByBishop(sq, colors)
55 || this.isAttackedByQueen(sq, colors)
56 || this.isAttackedByKing(sq, colors));
57 }
58
59 updateVariables(move)
60 {
61 // Just update king position
62 const piece = this.getPiece(move.start.x,move.start.y);
63 const c = this.getColor(move.start.x,move.start.y);
64 if (piece == VariantRules.KING)
65 {
66 this.kingPos[c][0] = move.appear[0].x;
67 this.kingPos[c][1] = move.appear[0].y;
68 }
69 }
70
71 static GenRandInitFen()
72 {
73 let minorPieces = { "w": new Array(4), "b": new Array(4) };
74 let majorPieces = { "w": new Array(4), "b": new Array(4) };
75 for (let c of ["w","b"])
76 {
77 // Minor pieces first (on 2nd rank)
78 let positions = _.range(4);
79
80 // Get random squares for bishops
81 let randIndex = 2 * _.random(1);
82 let bishop1Pos = positions[randIndex];
83 let randIndex_tmp = 2 * _.random(1) + 1;
84 let bishop2Pos = positions[randIndex_tmp];
85 positions.splice(Math.max(randIndex,randIndex_tmp), 1);
86 positions.splice(Math.min(randIndex,randIndex_tmp), 1);
87
88 // Get random squares for knights
89 randIndex = _.random(1);
90 let knight1Pos = positions[randIndex];
91 positions.splice(randIndex, 1);
92 let knight2Pos = positions[0];
93
94 minorPieces[c][bishop1Pos] = 'b';
95 minorPieces[c][bishop2Pos] = 'b';
96 minorPieces[c][knight1Pos] = 'n';
97 minorPieces[c][knight2Pos] = 'n';
98
99 // Major pieces then (on 1st rank)
100 positions = _.range(4);
101
102 // Get random square for queen
103 randIndex = _.random(3);
104 let queenPos = positions[randIndex];
105 positions.splice(randIndex, 1);
106
107 // Random square for king (no castle)
108 randIndex = _.random(2);
109 let kingPos = positions[randIndex];
110 positions.splice(randIndex, 1);
111
112 // Rooks and king positions:
113 let rook1Pos = positions[0];
114 let rook2Pos = positions[1];
115
116 majorPieces[c][rook1Pos] = 'r';
117 majorPieces[c][rook2Pos] = 'r';
118 majorPieces[c][kingPos] = 'k';
119 majorPieces[c][queenPos] = 'q';
120 }
121 let fen = "";
122 for (let i=0; i<4; i++)
123 {
124 fen += majorPieces["b"][i] + minorPieces["b"][i] + "4" +
125 minorPieces["w"][i].toUpperCase() + majorPieces["w"][i].toUpperCase();
126 if (i < 3)
127 fen += "/";
128 }
129 fen += " 0000"; //TODO: flags?!
130 return fen;
131 }
132 }