d5731a63c0d70e4c8a5071575e1ca01c80cbe998
[vchess.git] / public / javascripts / variants / Magnetic.js
1 class MagneticRules extends ChessRules
2 {
3 getEpSquare(move)
4 {
5 return undefined; //no en-passant
6 }
7
8 getPotentialMovesFrom([x,y])
9 {
10 const standardMoves = super.getPotentialMovesFrom([x,y]);
11 let moves = [];
12 standardMoves.forEach(m => {
13 let newMove_s = this.applyMagneticLaws(m);
14 if (newMove_s.length == 1)
15 moves.push(newMove_s[0]);
16 else //promotion
17 moves = moves.concat(moves, newMove_s);
18 });
19 }
20
21 // Complete a move with magnetic actions
22 applyMagneticLaws(standardMove)
23 {
24 const [x,y] = [moves.start.x, move.start.y];
25 let move = JSON.parse(JSON.stringify(standardMove));
26 this.play(standardMove);
27 const color = this.getColor(x,y);
28 const [sizeX,sizeY] = VariantRules.size;
29 for (let step of [[-1,0],[1,0],[0,-1],[0,1]])
30 {
31 let [i,j] = [x+step[0],y+step[1]];
32 while (i>=0 && i<sizeX && j>=0 && j<sizeY)
33 {
34 if (this.board[i][j] != VariantRules.EMPTY)
35 {
36 // Found something. Same color or not?
37 if (this.getColor(i,j) != color)
38 {
39 // Attraction
40 if ((Math.abs(i-x)>=2 || Math.abs(j-y)>=2)
41 && this.getPiece(i,j) != VariantRules.KING)
42 {
43 move.vanish.push(
44 new PiPo({
45 p:this.getPiece(i,j),
46 c:this.getColor(i,j),
47 x:i,
48 y:j
49 })
50 );
51 move.appear.push(
52 new PiPo({
53 p:this.getPiece(i,j),
54 c:this.getColor(i,j),
55 x:x+step[0],
56 y:y+step[1]
57 })
58 );
59 }
60 }
61 else
62 {
63 // Repulsion
64 if (this.getPiece(i,j) != VariantRules.KING)
65 {
66 // Push it until we meet an obstacle or edge of the board
67 let [ii,jj] = [i+step[0],j+step[1]];
68 while (ii>=0 && ii<sizeX && jj>=0 && jj<sizeY)
69 {
70 if (this.board[ii][jj] != VariantRules.EMPTY)
71 break;
72 ii += step[0];
73 jj += step[1];
74 }
75 ii -= step[0];
76 jj -= step[1];
77 if (Math.abs(ii-i)>=1 || Math.abs(jj-j)>=1)
78 {
79 move.vanish.push(
80 new PiPo({
81 p:this.getPiece(i,j),
82 c:this.getColor(i,j),
83 x:i,
84 y:j
85 })
86 );
87 move.appear.push(
88 new PiPo({
89 p:this.getPiece(i,j),
90 c:this.getColor(i,j),
91 x:ii,
92 y:jj
93 })
94 );
95 }
96 }
97 }
98 break;
99 }
100 i += step[0];
101 j += step[1];
102 }
103 }
104 this.undo(standardMove);
105 let moves = [];
106 if (..condition pawn promote)
107 {
108 move. ... = ... //loop
109 moves.push(...);
110 }
111 else
112 moves.push(move);
113 return moves;
114 }
115
116 // TODO: verify this assertion
117 atLeastOneMove()
118 {
119 return true; //always at least one possible move
120 }
121
122 underCheck(move)
123 {
124 return false; //there is no check
125 }
126
127 getCheckSquares(move)
128 {
129 const c = this.getOppCol(this.turn); //opponent
130 const saveKingPos = this.kingPos[c]; //king might be taken
131 this.play(move);
132 // The only way to be "under check" is to have lost the king (thus game over)
133 let res = this.kingPos[c][0] < 0
134 ? [ JSON.parse(JSON.stringify(saveKingPos)) ]
135 : [ ];
136 this.undo(move);
137 return res;
138 }
139
140 updateVariables(move)
141 {
142 super.updateVariables(move);
143 const c = this.getColor(move.start.x,move.start.y);
144 if (c != this.getColor(move.end.x,move.end.y)
145 && this.board[move.end.x][move.end.y] != VariantRules.EMPTY
146 && this.getPiece(move.end.x,move.end.y) == VariantRules.KING)
147 {
148 // We took opponent king !
149 const oppCol = this.getOppCol(c);
150 this.kingPos[oppCol] = [-1,-1];
151 this.castleFlags[oppCol] = [false,false];
152 }
153 }
154
155 unupdateVariables(move)
156 {
157 super.unupdateVariables(move);
158 const c = this.getColor(move.start.x,move.start.y);
159 const oppCol = this.getOppCol(c);
160 if (this.kingPos[oppCol][0] < 0)
161 {
162 // Last move took opponent's king
163 for (let psq of move.vanish)
164 {
165 if (psq.p == 'k')
166 {
167 this.kingPos[oppCol] = [psq.x, psq.y];
168 break;
169 }
170 }
171 }
172 }
173
174 checkGameOver()
175 {
176 if (this.checkRepetition())
177 return "1/2";
178
179 const color = this.turn;
180 // TODO: do we need "atLeastOneMove()"?
181 if (this.atLeastOneMove() && this.kingPos[color][0] >= 0)
182 return "*";
183
184 return this.checkGameEnd();
185 }
186
187 checkGameEnd()
188 {
189 // No valid move: our king disappeared
190 return this.turn == "w" ? "0-1" : "1-0";
191 }
192 }