Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
99 | pmbaty | 1 | /* |
2 | Texel - A UCI chess engine. |
||
3 | Copyright (C) 2014 Peter Ă–sterlund, peterosterlund2@gmail.com |
||
4 | |||
5 | This program is free software: you can redistribute it and/or modify |
||
6 | it under the terms of the GNU General Public License as published by |
||
7 | the Free Software Foundation, either version 3 of the License, or |
||
8 | (at your option) any later version. |
||
9 | |||
10 | This program is distributed in the hope that it will be useful, |
||
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
||
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||
13 | GNU General Public License for more details. |
||
14 | |||
15 | You should have received a copy of the GNU General Public License |
||
16 | along with this program. If not, see <http://www.gnu.org/licenses/>. |
||
17 | */ |
||
18 | |||
19 | /* |
||
20 | * tbprobe.cpp |
||
21 | * |
||
22 | * Created on: Jun 2, 2014 |
||
23 | * Author: petero |
||
24 | */ |
||
25 | |||
26 | #include "tbprobe.hpp" |
||
27 | #include "gtb/gtb-probe.h" |
||
28 | #include "syzygy/rtb-probe.hpp" |
||
29 | #include "bitBoard.hpp" |
||
30 | #include "position.hpp" |
||
31 | #include "moveGen.hpp" |
||
32 | #include "constants.hpp" |
||
33 | #include <unordered_map> |
||
34 | #include <cassert> |
||
35 | |||
36 | #include "util/timeUtil.hpp" |
||
37 | |||
38 | static std::string currentGtbPath; |
||
39 | static int currentGtbCacheMB; |
||
40 | static int currentGtbWdlFraction; |
||
41 | static std::string currentRtbPath; |
||
42 | |||
43 | static const char** gtbPaths = nullptr; |
||
44 | static int gtbMaxPieces = 0; |
||
45 | |||
46 | static std::unordered_map<int,int> maxDTM; // MatId -> Max DTM value in GTB TB |
||
47 | static std::unordered_map<int,int> maxDTZ; // MatId -> Max DTZ value in RTB TB |
||
48 | struct IIPairHash { |
||
49 | size_t operator()(const std::pair<int,int>& p) const { |
||
50 | return p.first * 0x714d3559 + p.second; |
||
51 | } |
||
52 | }; |
||
53 | // (MatId,maxPawnMoves) -> Max DTM in sub TBs |
||
54 | static std::unordered_map<std::pair<int,int>,int,IIPairHash> maxSubDTM; |
||
55 | |||
56 | |||
57 | void |
||
58 | TBProbe::initialize(const std::string& gtbPath, int cacheMB, |
||
59 | const std::string& rtbPath) { |
||
60 | if (rtbPath != currentRtbPath) { |
||
61 | Syzygy::init(rtbPath); |
||
62 | currentRtbPath = rtbPath; |
||
63 | } |
||
64 | |||
65 | int wdlFraction = (Syzygy::TBLargest >= 5) ? 8 : 96; |
||
66 | if ((gtbPath != currentGtbPath) || |
||
67 | (cacheMB != currentGtbCacheMB) || |
||
68 | (wdlFraction != currentGtbWdlFraction)) { |
||
69 | gtbInitialize(gtbPath, cacheMB, wdlFraction); |
||
70 | currentGtbPath = gtbPath; |
||
71 | currentGtbCacheMB = cacheMB; |
||
72 | currentGtbWdlFraction = wdlFraction; |
||
73 | } |
||
74 | |||
75 | static bool initialized = false; |
||
76 | if (!initialized) { |
||
77 | initWDLBounds(); |
||
78 | initialized = true; |
||
79 | } |
||
80 | } |
||
81 | |||
82 | bool |
||
83 | TBProbe::tbEnabled() { |
||
84 | return Syzygy::TBLargest > 0 || gtbMaxPieces > 0; |
||
85 | } |
||
86 | |||
87 | bool |
||
88 | TBProbe::tbProbe(Position& pos, int ply, int alpha, int beta, |
||
89 | TranspositionTable::TTEntry& ent) { |
||
90 | const int nPieces = BitBoard::bitCount(pos.occupiedBB()); |
||
91 | bool mateSearch = SearchConst::isLoseScore(alpha) || SearchConst::isWinScore(beta); |
||
92 | |||
93 | if (mateSearch || pos.getHalfMoveClock() > 0) { |
||
94 | // Need DTM or DTZ probe |
||
95 | int dtmScore; |
||
96 | bool hasDtm = false; |
||
97 | if (nPieces <= gtbMaxPieces && gtbProbeDTM(pos, ply, dtmScore)) { |
||
98 | if (SearchConst::MATE0 - 1 - abs(dtmScore) - ply <= 100 - pos.getHalfMoveClock()) { |
||
99 | ent.setScore(dtmScore, ply); |
||
100 | ent.setType(TType::T_EXACT); |
||
101 | return true; |
||
102 | } |
||
103 | hasDtm = true; |
||
104 | } |
||
105 | int dtzScore; |
||
106 | if (nPieces <= Syzygy::TBLargest && rtbProbeDTZ(pos, ply, dtzScore)) { |
||
107 | ent.setScore(dtzScore, ply); |
||
108 | if (dtzScore > 0) |
||
109 | ent.setType(TType::T_GE); |
||
110 | else if (dtzScore < 0) |
||
111 | ent.setType(TType::T_LE); |
||
112 | else |
||
113 | ent.setType(TType::T_EXACT); |
||
114 | return true; |
||
115 | } |
||
116 | if (hasDtm) { |
||
117 | ent.setScore(dtmScore, ply); |
||
118 | ent.setType(TType::T_EXACT); |
||
119 | return true; |
||
120 | } |
||
121 | } |
||
122 | |||
123 | if (pos.getHalfMoveClock() == 0) { |
||
124 | // Try WDL probe if DTM/DTZ not needed or not available |
||
125 | int wdlScore; |
||
126 | if ((nPieces <= Syzygy::TBLargest && rtbProbeWDL(pos, ply, wdlScore)) || |
||
127 | (nPieces <= gtbMaxPieces && gtbProbeWDL(pos, ply, wdlScore))) { |
||
128 | ent.setScore(wdlScore, ply); |
||
129 | if (wdlScore > 0) |
||
130 | ent.setType(TType::T_GE); |
||
131 | else if (wdlScore < 0) |
||
132 | ent.setType(TType::T_LE); |
||
133 | else |
||
134 | ent.setType(TType::T_EXACT); |
||
135 | return true; |
||
136 | } |
||
137 | } |
||
138 | return false; |
||
139 | } |
||
140 | |||
141 | bool |
||
142 | TBProbe::getSearchMoves(Position& pos, const MoveList& legalMoves, |
||
143 | std::vector<Move>& movesToSearch) { |
||
144 | const int mate0 = SearchConst::MATE0; |
||
145 | const int ply = 0; |
||
146 | TranspositionTable::TTEntry rootEnt; |
||
147 | if (!tbProbe(pos, ply, -mate0, mate0, rootEnt) || rootEnt.getType() == TType::T_LE) |
||
148 | return false; |
||
149 | const int rootScore = rootEnt.getScore(ply); |
||
150 | if (!SearchConst::isWinScore(rootScore)) |
||
151 | return false; |
||
152 | |||
153 | // Root position is TB win |
||
154 | bool hasProgress = false; |
||
155 | UndoInfo ui; |
||
156 | for (int mi = 0; mi < legalMoves.size; mi++) { |
||
157 | const Move& m = legalMoves[mi]; |
||
158 | pos.makeMove(m, ui); |
||
159 | TranspositionTable::TTEntry ent; |
||
160 | ent.clear(); |
||
161 | bool progressMove = false; |
||
162 | bool badMove = false; |
||
163 | if (tbProbe(pos, ply+1, -mate0, mate0, ent)) { |
||
164 | const int type = ent.getType(); |
||
165 | const int score = -ent.getScore(ply+1); |
||
166 | if (score >= rootScore && (type == TType::T_EXACT || type == TType::T_LE)) |
||
167 | progressMove = true; |
||
168 | if ((score < rootScore)) // && (type == TType::T_EXACT || type == TType::T_GE)) |
||
169 | badMove = true; |
||
170 | } |
||
171 | if (progressMove) |
||
172 | hasProgress = true; |
||
173 | if (!badMove) |
||
174 | movesToSearch.push_back(m); |
||
175 | pos.unMakeMove(m, ui); |
||
176 | } |
||
177 | |||
178 | return !hasProgress && !movesToSearch.empty(); |
||
179 | } |
||
180 | |||
181 | void |
||
182 | TBProbe::extendPV(const Position& rootPos, std::vector<Move>& pv) { |
||
183 | Position pos(rootPos); |
||
184 | UndoInfo ui; |
||
185 | int ply = 0; |
||
186 | int score; |
||
187 | for (int i = 0; i < (int)pv.size(); i++) { |
||
188 | const Move& m = pv[i]; |
||
189 | pos.makeMove(m, ui); |
||
190 | if (TBProbe::gtbProbeDTM(pos, ply, score) && SearchConst::isWinScore(std::abs(score)) && |
||
191 | (SearchConst::MATE0 - 1 - abs(score) - ply <= 100 - pos.getHalfMoveClock())) { |
||
192 | // TB win, replace rest of PV since it may be inaccurate |
||
193 | pv.erase(pv.begin()+i+1, pv.end()); |
||
194 | break; |
||
195 | } |
||
196 | } |
||
197 | if (!TBProbe::gtbProbeDTM(pos, ply, score) || !SearchConst::isWinScore(std::abs(score))) |
||
198 | return; // No TB win |
||
199 | if (SearchConst::MATE0 - 1 - abs(score) - ply > 100 - pos.getHalfMoveClock()) |
||
200 | return; // Mate too far away, perhaps 50-move draw |
||
201 | if (!pos.isWhiteMove()) |
||
202 | score = -score; |
||
203 | while (true) { |
||
204 | MoveList moveList; |
||
205 | MoveGen::pseudoLegalMoves(pos, moveList); |
||
206 | MoveGen::removeIllegal(pos, moveList); |
||
207 | bool extended = false; |
||
208 | for (int mi = 0; mi < moveList.size; mi++) { |
||
209 | const Move& m = moveList[mi]; |
||
210 | pos.makeMove(m, ui); |
||
211 | int newScore; |
||
212 | if (TBProbe::gtbProbeDTM(pos, ply+1, newScore)) { |
||
213 | if (!pos.isWhiteMove()) |
||
214 | newScore = -newScore; |
||
215 | if (newScore == score) { |
||
216 | pv.push_back(m); |
||
217 | ply++; |
||
218 | extended = true; |
||
219 | break; |
||
220 | } |
||
221 | } |
||
222 | pos.unMakeMove(m, ui); |
||
223 | } |
||
224 | if (!extended) |
||
225 | break; |
||
226 | } |
||
227 | } |
||
228 | |||
229 | template <typename ProbeFunc> |
||
230 | static void handleEP(Position& pos, int ply, int& score, bool& ret, ProbeFunc probeFunc) { |
||
231 | const bool inCheck = MoveGen::inCheck(pos); |
||
232 | MoveList moveList; |
||
233 | if (inCheck) MoveGen::checkEvasions(pos, moveList); |
||
234 | else MoveGen::pseudoLegalMoves(pos, moveList); |
||
235 | const int pawn = pos.isWhiteMove() ? Piece::WPAWN : Piece::BPAWN; |
||
236 | int bestEP = std::numeric_limits<int>::min(); |
||
237 | UndoInfo ui; |
||
238 | for (int m = 0; m < moveList.size; m++) { |
||
239 | const Move& move = moveList[m]; |
||
240 | if ((move.to() == pos.getEpSquare()) && (pos.getPiece(move.from()) == pawn)) { |
||
241 | if (MoveGen::isLegal(pos, move, inCheck)) { |
||
242 | pos.makeMove(move, ui); |
||
243 | int score2; |
||
244 | bool ret2 = probeFunc(pos, ply+1, score2); |
||
245 | pos.unMakeMove(move, ui); |
||
246 | if (!ret2) { |
||
247 | ret = false; |
||
248 | return; |
||
249 | } |
||
250 | bestEP = std::max(bestEP, -score2); |
||
251 | } |
||
252 | } else if (MoveGen::isLegal(pos, move, inCheck)) |
||
253 | return; |
||
254 | } |
||
255 | if (bestEP != std::numeric_limits<int>::min()) |
||
256 | score = bestEP; |
||
257 | } |
||
258 | |||
259 | bool |
||
260 | TBProbe::gtbProbeDTM(Position& pos, int ply, int& score) { |
||
261 | if (BitBoard::bitCount(pos.occupiedBB()) > gtbMaxPieces) |
||
262 | return false; |
||
263 | |||
264 | GtbProbeData gtbData; |
||
265 | getGTBProbeData(pos, gtbData); |
||
266 | bool ret = gtbProbeDTM(gtbData, ply, score); |
||
267 | if (ret && score == 0 && pos.getEpSquare() != -1) |
||
268 | handleEP(pos, ply, score, ret, [](Position& pos, int ply, int& score) -> bool { |
||
269 | return TBProbe::gtbProbeDTM(pos, ply, score); |
||
270 | }); |
||
271 | return ret; |
||
272 | } |
||
273 | |||
274 | bool |
||
275 | TBProbe::gtbProbeWDL(Position& pos, int ply, int& score) { |
||
276 | if (BitBoard::bitCount(pos.occupiedBB()) > gtbMaxPieces) |
||
277 | return false; |
||
278 | |||
279 | GtbProbeData gtbData; |
||
280 | getGTBProbeData(pos, gtbData); |
||
281 | bool ret = gtbProbeWDL(gtbData, ply, score); |
||
282 | if (ret && score == 0 && pos.getEpSquare() != -1) |
||
283 | handleEP(pos, ply, score, ret, [](Position& pos, int ply, int& score) -> bool { |
||
284 | return TBProbe::gtbProbeWDL(pos, ply, score); |
||
285 | }); |
||
286 | return ret; |
||
287 | } |
||
288 | |||
289 | bool |
||
290 | TBProbe::rtbProbeDTZ(Position& pos, int ply, int& score) { |
||
291 | const int nPieces = BitBoard::bitCount(pos.occupiedBB()); |
||
292 | if (nPieces > Syzygy::TBLargest) |
||
293 | return false; |
||
294 | if (pos.getCastleMask()) |
||
295 | return false; |
||
296 | |||
297 | int success; |
||
298 | const int dtz = Syzygy::probe_dtz(pos, &success); |
||
299 | if (!success) |
||
300 | return false; |
||
301 | if (dtz == 0) { |
||
302 | score = 0; |
||
303 | return true; |
||
304 | } |
||
305 | const int maxHalfMoveClock = std::abs(dtz) + pos.getHalfMoveClock(); |
||
306 | if (abs(dtz) <= 2) { |
||
307 | if (maxHalfMoveClock > 101) { |
||
308 | score = 0; |
||
309 | return true; |
||
310 | } else if (maxHalfMoveClock == 101) |
||
311 | return false; // DTZ can be wrong when mate-in-1 |
||
312 | } else { |
||
313 | if (maxHalfMoveClock > 100) { |
||
314 | score = 0; |
||
315 | return true; |
||
316 | } |
||
317 | // FIXME!! Are there positions where maxHalfMoveclock==101 needs special handling? |
||
318 | } |
||
319 | int plyToMate = getMaxSubMate(pos) + std::abs(dtz); |
||
320 | if (dtz > 0) { |
||
321 | score = SearchConst::MATE0 - ply - plyToMate - 2; |
||
322 | } else { |
||
323 | score = -(SearchConst::MATE0 - ply - plyToMate - 2); |
||
324 | } |
||
325 | return true; |
||
326 | } |
||
327 | |||
328 | bool |
||
329 | TBProbe::rtbProbeWDL(Position& pos, int ply, int& score) { |
||
330 | if (BitBoard::bitCount(pos.occupiedBB()) > Syzygy::TBLargest) |
||
331 | return false; |
||
332 | if (pos.getCastleMask()) |
||
333 | return false; |
||
334 | |||
335 | int success; |
||
336 | int wdl = Syzygy::probe_wdl(pos, &success); |
||
337 | if (!success) |
||
338 | return false; |
||
339 | int plyToMate; |
||
340 | switch (wdl) { |
||
341 | case 0: case 1: case -1: |
||
342 | score = 0; |
||
343 | break; |
||
344 | case 2: |
||
345 | plyToMate = getMaxSubMate(pos) + getMaxDTZ(pos.materialId()); |
||
346 | score = SearchConst::MATE0 - ply - plyToMate - 2; |
||
347 | break; |
||
348 | case -2: |
||
349 | plyToMate = getMaxSubMate(pos) + getMaxDTZ(pos.materialId()); |
||
350 | score = -(SearchConst::MATE0 - ply - plyToMate - 2); |
||
351 | break; |
||
352 | default: |
||
353 | return false; |
||
354 | } |
||
355 | |||
356 | return true; |
||
357 | } |
||
358 | |||
359 | void |
||
360 | TBProbe::gtbInitialize(const std::string& path, int cacheMB, int wdlFraction) { |
||
361 | static_assert((int)tb_A1 == (int)A1, "Incompatible square numbering"); |
||
362 | static_assert((int)tb_A8 == (int)A8, "Incompatible square numbering"); |
||
363 | static_assert((int)tb_H1 == (int)H1, "Incompatible square numbering"); |
||
364 | static_assert((int)tb_H8 == (int)H8, "Incompatible square numbering"); |
||
365 | |||
366 | tbpaths_done(gtbPaths); |
||
367 | |||
368 | gtbMaxPieces = 0; |
||
369 | gtbPaths = tbpaths_init(); |
||
370 | gtbPaths = tbpaths_add(gtbPaths, path.c_str()); |
||
371 | |||
372 | TB_compression_scheme scheme = tb_CP4; |
||
373 | int verbose = 0; |
||
374 | int cacheSize = 1024 * 1024 * cacheMB; |
||
375 | static bool isInitialized = false; |
||
376 | if (isInitialized) { |
||
377 | tb_restart(verbose, scheme, gtbPaths); |
||
378 | tbcache_restart(cacheSize, wdlFraction); |
||
379 | } else { |
||
380 | tb_init(verbose, scheme, gtbPaths); |
||
381 | tbcache_init(cacheSize, wdlFraction); |
||
382 | } |
||
383 | isInitialized = true; |
||
384 | |||
385 | unsigned int av = tb_availability(); |
||
386 | if (av & 3) |
||
387 | gtbMaxPieces = 3; |
||
388 | if (av & 12) |
||
389 | gtbMaxPieces = 4; |
||
390 | if (av & 48) |
||
391 | gtbMaxPieces = 5; |
||
392 | } |
||
393 | |||
394 | void |
||
395 | TBProbe::getGTBProbeData(const Position& pos, GtbProbeData& gtbData) { |
||
396 | gtbData.stm = pos.isWhiteMove() ? tb_WHITE_TO_MOVE : tb_BLACK_TO_MOVE; |
||
397 | gtbData.epsq = pos.getEpSquare() >= 0 ? pos.getEpSquare() : tb_NOSQUARE; |
||
398 | |||
399 | gtbData.castles = 0; |
||
400 | if (pos.a1Castle()) gtbData.castles |= tb_WOOO; |
||
401 | if (pos.h1Castle()) gtbData.castles |= tb_WOO; |
||
402 | if (pos.a8Castle()) gtbData.castles |= tb_BOOO; |
||
403 | if (pos.h8Castle()) gtbData.castles |= tb_BOO; |
||
404 | |||
405 | int cnt = 0; |
||
406 | U64 m = pos.whiteBB(); |
||
407 | while (m != 0) { |
||
408 | int sq = BitBoard::extractSquare(m); |
||
409 | gtbData.wSq[cnt] = sq; |
||
410 | switch (pos.getPiece(sq)) { |
||
411 | case Piece::WKING: gtbData.wP[cnt] = tb_KING; break; |
||
412 | case Piece::WQUEEN: gtbData.wP[cnt] = tb_QUEEN; break; |
||
413 | case Piece::WROOK: gtbData.wP[cnt] = tb_ROOK; break; |
||
414 | case Piece::WBISHOP: gtbData.wP[cnt] = tb_BISHOP; break; |
||
415 | case Piece::WKNIGHT: gtbData.wP[cnt] = tb_KNIGHT; break; |
||
416 | case Piece::WPAWN: gtbData.wP[cnt] = tb_PAWN; break; |
||
417 | default: |
||
418 | assert(false); |
||
419 | } |
||
420 | cnt++; |
||
421 | } |
||
422 | gtbData.wSq[cnt] = tb_NOSQUARE; |
||
423 | gtbData.wP[cnt] = tb_NOPIECE; |
||
424 | |||
425 | cnt = 0; |
||
426 | m = pos.blackBB(); |
||
427 | while (m != 0) { |
||
428 | int sq = BitBoard::extractSquare(m); |
||
429 | gtbData.bSq[cnt] = sq; |
||
430 | switch (pos.getPiece(sq)) { |
||
431 | case Piece::BKING: gtbData.bP[cnt] = tb_KING; break; |
||
432 | case Piece::BQUEEN: gtbData.bP[cnt] = tb_QUEEN; break; |
||
433 | case Piece::BROOK: gtbData.bP[cnt] = tb_ROOK; break; |
||
434 | case Piece::BBISHOP: gtbData.bP[cnt] = tb_BISHOP; break; |
||
435 | case Piece::BKNIGHT: gtbData.bP[cnt] = tb_KNIGHT; break; |
||
436 | case Piece::BPAWN: gtbData.bP[cnt] = tb_PAWN; break; |
||
437 | default: |
||
438 | assert(false); |
||
439 | } |
||
440 | cnt++; |
||
441 | } |
||
442 | gtbData.bSq[cnt] = tb_NOSQUARE; |
||
443 | gtbData.bP[cnt] = tb_NOPIECE; |
||
444 | gtbData.materialId = pos.materialId(); |
||
445 | } |
||
446 | |||
447 | bool |
||
448 | TBProbe::gtbProbeDTM(const GtbProbeData& gtbData, int ply, int& score) { |
||
449 | unsigned int tbInfo; |
||
450 | unsigned int plies; |
||
451 | if (!tb_probe_hard(gtbData.stm, gtbData.epsq, gtbData.castles, |
||
452 | gtbData.wSq, gtbData.bSq, |
||
453 | gtbData.wP, gtbData.bP, |
||
454 | &tbInfo, &plies)) |
||
455 | return false; |
||
456 | |||
457 | switch (tbInfo) { |
||
458 | case tb_DRAW: |
||
459 | score = 0; |
||
460 | break; |
||
461 | case tb_WMATE: |
||
462 | score = SearchConst::MATE0 - ply - plies - 1; |
||
463 | break; |
||
464 | case tb_BMATE: |
||
465 | score = -(SearchConst::MATE0 - ply - (int)plies - 1); // Pierre-Marie Baty -- added type cast |
||
466 | break; |
||
467 | default: |
||
468 | return false; |
||
469 | }; |
||
470 | |||
471 | if (gtbData.stm == tb_BLACK_TO_MOVE) |
||
472 | score = -score; |
||
473 | |||
474 | return true; |
||
475 | } |
||
476 | |||
477 | bool |
||
478 | TBProbe::gtbProbeWDL(const GtbProbeData& gtbData, int ply, int& score) { |
||
479 | unsigned int tbInfo; |
||
480 | if (!tb_probe_WDL_hard(gtbData.stm, gtbData.epsq, gtbData.castles, |
||
481 | gtbData.wSq, gtbData.bSq, |
||
482 | gtbData.wP, gtbData.bP, |
||
483 | &tbInfo)) |
||
484 | return false; |
||
485 | |||
486 | switch (tbInfo) { |
||
487 | case tb_DRAW: |
||
488 | score = 0; |
||
489 | break; |
||
490 | case tb_WMATE: |
||
491 | score = maxDTM[gtbData.materialId] - ply; |
||
492 | break; |
||
493 | case tb_BMATE: |
||
494 | score = -(maxDTM[gtbData.materialId] - ply); |
||
495 | break; |
||
496 | default: |
||
497 | return false; |
||
498 | }; |
||
499 | |||
500 | if (gtbData.stm == tb_BLACK_TO_MOVE) |
||
501 | score = -score; |
||
502 | return true; |
||
503 | } |
||
504 | |||
505 | void |
||
506 | TBProbe::initWDLBounds() { |
||
507 | initMaxDTM(); |
||
508 | initMaxDTZ(); |
||
509 | |||
510 | // Pre-calculate all interesting maxSubDTM values |
||
511 | for (int wp = 0; wp <= 4; wp++) { |
||
512 | std::vector<int> pieces(Piece::nPieceTypes); |
||
513 | pieces[Piece::WPAWN] = wp; |
||
514 | pieces[Piece::BPAWN] = 4 - wp; |
||
515 | getMaxSubMate(pieces, 4*5); |
||
516 | } |
||
517 | } |
||
518 | |||
519 | /** Maximum DTZ value for a given material configuration. */ |
||
520 | int |
||
521 | TBProbe::getMaxDTZ(int matId) { |
||
522 | auto it = maxDTZ.find(matId); |
||
523 | if (it == maxDTZ.end()) |
||
524 | return 100; |
||
525 | int val = it->second; |
||
526 | if (val < 0) |
||
527 | return 0; |
||
528 | else |
||
529 | return std::min(val+2, 100); // RTB DTZ values are not exact |
||
530 | } |
||
531 | |||
532 | static int |
||
533 | getMaxPawnMoves(const Position& pos) { |
||
534 | int maxPawnMoves = 0; |
||
535 | U64 m = pos.pieceTypeBB(Piece::WPAWN); |
||
536 | while (m != 0) { |
||
537 | int sq = BitBoard::extractSquare(m); |
||
538 | maxPawnMoves += 6 - Position::getY(sq); |
||
539 | } |
||
540 | m = pos.pieceTypeBB(Piece::BPAWN); |
||
541 | while (m != 0) { |
||
542 | int sq = BitBoard::extractSquare(m); |
||
543 | maxPawnMoves += Position::getY(sq) - 1; |
||
544 | } |
||
545 | return maxPawnMoves; |
||
546 | } |
||
547 | |||
548 | /** Get upper bound on longest mate in all possible material configurations |
||
549 | * after the next zeroing move. */ |
||
550 | int |
||
551 | TBProbe::getMaxSubMate(const Position& pos) { |
||
552 | int maxPawnMoves = getMaxPawnMoves(pos); |
||
553 | int matId = pos.materialId(); |
||
554 | matId = std::min(matId, MatId::mirror(matId)); |
||
555 | auto it = maxSubDTM.find(std::make_pair(matId,maxPawnMoves)); |
||
556 | if (it != maxSubDTM.end()) |
||
557 | return it->second; |
||
558 | |||
559 | std::vector<int> pieces(Piece::nPieceTypes); |
||
560 | for (int p = 0; p < Piece::nPieceTypes; p++) |
||
561 | pieces[p] = BitBoard::bitCount(pos.pieceTypeBB((Piece::Type)p)); |
||
562 | pieces[Piece::EMPTY] = pieces[Piece::WKING] = pieces[Piece::BKING] = 0; |
||
563 | return getMaxSubMate(pieces, maxPawnMoves); |
||
564 | } |
||
565 | |||
566 | int |
||
567 | TBProbe::getMaxSubMate(std::vector<int>& pieces, int pawnMoves) { |
||
568 | assert(pawnMoves >= 0); |
||
569 | if (pawnMoves > (pieces[Piece::WPAWN] + pieces[Piece::BPAWN]) * 5) |
||
570 | return 0; |
||
571 | |||
572 | MatId matId; |
||
573 | for (int p = 0; p < Piece::nPieceTypes; p++) |
||
574 | matId.addPieceCnt(p, pieces[p]); |
||
575 | |||
576 | const int matIdMin = std::min(matId(), MatId::mirror(matId())); |
||
577 | auto it = maxSubDTM.find(std::make_pair(matIdMin, pawnMoves)); |
||
578 | if (it != maxSubDTM.end()) |
||
579 | return it->second; |
||
580 | |||
581 | int maxSubMate = 0; |
||
582 | if (pawnMoves > 0) { // Pawn move |
||
583 | maxSubMate = getMaxSubMate(pieces, pawnMoves-1) + getMaxDTZ(matId()); |
||
584 | } |
||
585 | for (int p = 0; p < Piece::nPieceTypes; p++) { // Capture |
||
586 | if (pieces[p] > 0) { |
||
587 | pieces[p]--; |
||
588 | matId.removePiece(p); |
||
589 | int maxRemovedPawnMoves = 0; |
||
590 | if (p == Piece::WPAWN || p == Piece::BPAWN) |
||
591 | maxRemovedPawnMoves = 5; |
||
592 | for (int i = 0; i <= maxRemovedPawnMoves; i++) { |
||
593 | int newPawnMoves = pawnMoves - i; |
||
594 | if (newPawnMoves >= 0) { |
||
595 | int tmp = getMaxSubMate(pieces, newPawnMoves) + getMaxDTZ(matId()); |
||
596 | maxSubMate = std::max(maxSubMate, tmp); |
||
597 | } |
||
598 | } |
||
599 | pieces[p]++; |
||
600 | matId.addPiece(p); |
||
601 | } |
||
602 | } |
||
603 | for (int c = 0; c < 2; c++) { // Promotion |
||
604 | const int pawn = (c == 0) ? Piece::WPAWN : Piece::BPAWN; |
||
605 | if (pieces[pawn] > 0) { |
||
606 | const int p0 = (c == 0) ? Piece::WQUEEN : Piece::BQUEEN; |
||
607 | const int p1 = (c == 0) ? Piece::WKNIGHT : Piece::BKNIGHT; |
||
608 | for (int p = p0; p <= p1; p++) { |
||
609 | pieces[pawn]--; |
||
610 | pieces[p]++; |
||
611 | matId.removePiece(pawn); |
||
612 | matId.addPiece(p); |
||
613 | int tmp = getMaxSubMate(pieces, pawnMoves) + getMaxDTZ(matId()); |
||
614 | maxSubMate = std::max(maxSubMate, tmp); |
||
615 | pieces[pawn]++; |
||
616 | pieces[p]--; |
||
617 | matId.addPiece(pawn); |
||
618 | matId.removePiece(p); |
||
619 | } |
||
620 | } |
||
621 | } |
||
622 | |||
623 | #if 0 |
||
624 | std::cout << "wQ:" << pieces[Piece::WQUEEN] |
||
625 | << " wR:" << pieces[Piece::WROOK] |
||
626 | << " wB:" << pieces[Piece::WBISHOP] |
||
627 | << " wN:" << pieces[Piece::WKNIGHT] |
||
628 | << " wP:" << pieces[Piece::WPAWN] |
||
629 | << " bQ:" << pieces[Piece::BQUEEN] |
||
630 | << " bR:" << pieces[Piece::BROOK] |
||
631 | << " bB:" << pieces[Piece::BBISHOP] |
||
632 | << " bN:" << pieces[Piece::BKNIGHT] |
||
633 | << " bP:" << pieces[Piece::BPAWN] |
||
634 | << " pMoves:" << pawnMoves << " : " << maxSubMate << std::endl; |
||
635 | #endif |
||
636 | maxSubDTM[std::make_pair(matIdMin, pawnMoves)] = maxSubMate; |
||
637 | return maxSubMate; |
||
638 | } |
||
639 | |||
640 | void |
||
641 | TBProbe::initMaxDTM() { |
||
642 | using MI = MatId; |
||
643 | auto add = [](int id, int value) { |
||
644 | maxDTM[id] = value; |
||
645 | maxDTM[MatId::mirror(id)] = value; |
||
646 | }; |
||
647 | |||
648 | add(MI::WQ, 31979); |
||
649 | add(MI::WR, 31967); |
||
650 | add(MI::WP, 31943); |
||
651 | |||
652 | add(MI::WQ*2, 31979); |
||
653 | add(MI::WQ+MI::WR, 31967); |
||
654 | add(MI::WQ+MI::WB, 31979); |
||
655 | add(MI::WQ+MI::WN, 31979); |
||
656 | add(MI::WQ+MI::WP, 31943); |
||
657 | add(MI::WR*2, 31967); |
||
658 | add(MI::WR+MI::WB, 31967); |
||
659 | add(MI::WR+MI::WN, 31967); |
||
660 | add(MI::WR+MI::WP, 31943); |
||
661 | add(MI::WB*2, 31961); |
||
662 | add(MI::WB+MI::WN, 31933); |
||
663 | add(MI::WB+MI::WP, 31937); |
||
664 | add(MI::WN*2, 31998); |
||
665 | add(MI::WN+MI::WP, 31943); |
||
666 | add(MI::WP*2, 31935); |
||
667 | add(MI::WQ+MI::BQ, 31974); |
||
668 | add(MI::WR+MI::BQ, 31929); |
||
669 | add(MI::WR+MI::BR, 31961); |
||
670 | add(MI::WB+MI::BQ, 31965); |
||
671 | add(MI::WB+MI::BR, 31941); |
||
672 | add(MI::WB+MI::BB, 31998); |
||
673 | add(MI::WN+MI::BQ, 31957); |
||
674 | add(MI::WN+MI::BR, 31919); |
||
675 | add(MI::WN+MI::BB, 31998); |
||
676 | add(MI::WN+MI::BN, 31998); |
||
677 | add(MI::WP+MI::BQ, 31942); |
||
678 | add(MI::WP+MI::BR, 31914); |
||
679 | add(MI::WP+MI::BB, 31942); |
||
680 | add(MI::WP+MI::BN, 31942); |
||
681 | add(MI::WP+MI::BP, 31933); |
||
682 | |||
683 | add(MI::WQ*3, 31991); |
||
684 | add(MI::WQ*2+MI::WR, 31987); |
||
685 | add(MI::WQ*2+MI::WB, 31983); |
||
686 | add(MI::WQ*2+MI::WN, 31981); |
||
687 | add(MI::WQ*2+MI::WP, 31979); |
||
688 | add(MI::WQ+MI::WR*2, 31985); |
||
689 | add(MI::WQ+MI::WR+MI::WB, 31967); |
||
690 | add(MI::WQ+MI::WR+MI::WN, 31967); |
||
691 | add(MI::WQ+MI::WR+MI::WP, 31967); |
||
692 | add(MI::WQ+MI::WB*2, 31961); |
||
693 | add(MI::WQ+MI::WB+MI::WN, 31933); |
||
694 | add(MI::WQ+MI::WB+MI::WP, 31937); |
||
695 | add(MI::WQ+MI::WN*2, 31981); |
||
696 | add(MI::WQ+MI::WN+MI::WP, 31945); |
||
697 | add(MI::WQ+MI::WP*2, 31935); |
||
698 | add(MI::WR*3, 31985); |
||
699 | add(MI::WR*2+MI::WB, 31967); |
||
700 | add(MI::WR*2+MI::WN, 31967); |
||
701 | add(MI::WR*2+MI::WP, 31967); |
||
702 | add(MI::WR+MI::WB*2, 31961); |
||
703 | add(MI::WR+MI::WB+MI::WN, 31933); |
||
704 | add(MI::WR+MI::WB+MI::WP, 31937); |
||
705 | add(MI::WR+MI::WN*2, 31967); |
||
706 | add(MI::WR+MI::WN+MI::WP, 31945); |
||
707 | add(MI::WR+MI::WP*2, 31935); |
||
708 | add(MI::WB*3, 31961); |
||
709 | add(MI::WB*2+MI::WN, 31933); |
||
710 | add(MI::WB*2+MI::WP, 31937); |
||
711 | add(MI::WB+MI::WN*2, 31931); |
||
712 | add(MI::WB+MI::WN+MI::WP, 31933); |
||
713 | add(MI::WB+MI::WP*2, 31935); |
||
714 | add(MI::WN*3, 31957); |
||
715 | add(MI::WN*2+MI::WP, 31943); |
||
716 | add(MI::WN+MI::WP*2, 31935); |
||
717 | add(MI::WP*3, 31933); |
||
718 | add(MI::WQ*2+MI::BQ, 31939); |
||
719 | add(MI::WQ*2+MI::BR, 31929); |
||
720 | add(MI::WQ*2+MI::BB, 31965); |
||
721 | add(MI::WQ*2+MI::BN, 31957); |
||
722 | add(MI::WQ*2+MI::BP, 31939); |
||
723 | add(MI::WQ+MI::WR+MI::BQ, 31865); |
||
724 | add(MI::WQ+MI::WR+MI::BR, 31929); |
||
725 | add(MI::WQ+MI::WR+MI::BB, 31941); |
||
726 | add(MI::WQ+MI::WR+MI::BN, 31919); |
||
727 | add(MI::WQ+MI::WR+MI::BP, 31865); |
||
728 | add(MI::WQ+MI::WB+MI::BQ, 31933); |
||
729 | add(MI::WQ+MI::WB+MI::BR, 31919); |
||
730 | add(MI::WQ+MI::WB+MI::BB, 31965); |
||
731 | add(MI::WQ+MI::WB+MI::BN, 31957); |
||
732 | add(MI::WQ+MI::WB+MI::BP, 31933); |
||
733 | add(MI::WQ+MI::WN+MI::BQ, 31917); |
||
734 | add(MI::WQ+MI::WN+MI::BR, 31918); |
||
735 | add(MI::WQ+MI::WN+MI::BB, 31965); |
||
736 | add(MI::WQ+MI::WN+MI::BN, 31957); |
||
737 | add(MI::WQ+MI::WN+MI::BP, 31917); |
||
738 | add(MI::WQ+MI::WP+MI::BQ, 31752); |
||
739 | add(MI::WQ+MI::WP+MI::BR, 31913); |
||
740 | add(MI::WQ+MI::WP+MI::BB, 31941); |
||
741 | add(MI::WQ+MI::WP+MI::BN, 31939); |
||
742 | add(MI::WQ+MI::WP+MI::BP, 31755); |
||
743 | add(MI::WR*2+MI::BQ, 31901); |
||
744 | add(MI::WR*2+MI::BR, 31937); |
||
745 | add(MI::WR*2+MI::BB, 31941); |
||
746 | add(MI::WR*2+MI::BN, 31919); |
||
747 | add(MI::WR*2+MI::BP, 31900); |
||
748 | add(MI::WR+MI::WB+MI::BQ, 31859); |
||
749 | add(MI::WR+MI::WB+MI::BR, 31870); |
||
750 | add(MI::WR+MI::WB+MI::BB, 31939); |
||
751 | add(MI::WR+MI::WB+MI::BN, 31919); |
||
752 | add(MI::WR+MI::WB+MI::BP, 31860); |
||
753 | add(MI::WR+MI::WN+MI::BQ, 31861); |
||
754 | add(MI::WR+MI::WN+MI::BR, 31918); |
||
755 | add(MI::WR+MI::WN+MI::BB, 31937); |
||
756 | add(MI::WR+MI::WN+MI::BN, 31919); |
||
757 | add(MI::WR+MI::WN+MI::BP, 31864); |
||
758 | add(MI::WR+MI::WP+MI::BQ, 31792); |
||
759 | add(MI::WR+MI::WP+MI::BR, 31851); |
||
760 | add(MI::WR+MI::WP+MI::BB, 31853); |
||
761 | add(MI::WR+MI::WP+MI::BN, 31891); |
||
762 | add(MI::WR+MI::WP+MI::BP, 31794); |
||
763 | add(MI::WB*2+MI::BQ, 31837); |
||
764 | add(MI::WB*2+MI::BR, 31938); |
||
765 | add(MI::WB*2+MI::BB, 31955); |
||
766 | add(MI::WB*2+MI::BN, 31843); |
||
767 | add(MI::WB*2+MI::BP, 31834); |
||
768 | add(MI::WB+MI::WN+MI::BQ, 31893); |
||
769 | add(MI::WB+MI::WN+MI::BR, 31918); |
||
770 | add(MI::WB+MI::WN+MI::BB, 31921); |
||
771 | add(MI::WB+MI::WN+MI::BN, 31786); |
||
772 | add(MI::WB+MI::WN+MI::BP, 31791); |
||
773 | add(MI::WB+MI::WP+MI::BQ, 31899); |
||
774 | add(MI::WB+MI::WP+MI::BR, 31910); |
||
775 | add(MI::WB+MI::WP+MI::BB, 31898); |
||
776 | add(MI::WB+MI::WP+MI::BN, 31800); |
||
777 | add(MI::WB+MI::WP+MI::BP, 31865); |
||
778 | add(MI::WN*2+MI::BQ, 31855); |
||
779 | add(MI::WN*2+MI::BR, 31918); |
||
780 | add(MI::WN*2+MI::BB, 31992); |
||
781 | add(MI::WN*2+MI::BN, 31986); |
||
782 | add(MI::WN*2+MI::BP, 31770); |
||
783 | add(MI::WN+MI::WP+MI::BQ, 31875); |
||
784 | add(MI::WN+MI::WP+MI::BR, 31866); |
||
785 | add(MI::WN+MI::WP+MI::BB, 31914); |
||
786 | add(MI::WN+MI::WP+MI::BN, 31805); |
||
787 | add(MI::WN+MI::WP+MI::BP, 31884); |
||
788 | add(MI::WP*2+MI::BQ, 31752); |
||
789 | add(MI::WP*2+MI::BR, 31892); |
||
790 | add(MI::WP*2+MI::BB, 31913); |
||
791 | add(MI::WP*2+MI::BN, 31899); |
||
792 | add(MI::WP*2+MI::BP, 31745); |
||
793 | } |
||
794 | |||
795 | void |
||
796 | TBProbe::initMaxDTZ() { |
||
797 | using MI = MatId; |
||
798 | auto add = [](int id, int value) { |
||
799 | maxDTZ[id] = value; |
||
800 | maxDTZ[MatId::mirror(id)] = value; |
||
801 | }; |
||
802 | |||
803 | // 2-men |
||
804 | add(0, -1); |
||
805 | |||
806 | // 3-men |
||
807 | add(MI::WQ, 20); |
||
808 | add(MI::WR, 32); |
||
809 | add(MI::WB, -1); |
||
810 | add(MI::WN, -1); |
||
811 | add(MI::WP, 20); |
||
812 | |||
813 | // 4-men |
||
814 | add(MI::WQ+MI::BQ, 19); |
||
815 | add(MI::WN*2, 1); |
||
816 | add(MI::WQ*2, 6); |
||
817 | add(MI::WP*2, 14); |
||
818 | add(MI::WR*2, 10); |
||
819 | add(MI::WR+MI::BR, 7); |
||
820 | add(MI::WQ+MI::WB, 12); |
||
821 | add(MI::WQ+MI::WR, 8); |
||
822 | add(MI::WQ+MI::WN, 14); |
||
823 | add(MI::WR+MI::BB, 35); |
||
824 | add(MI::WB+MI::BB, 1); |
||
825 | add(MI::WQ+MI::WP, 6); |
||
826 | add(MI::WB*2, 37); |
||
827 | add(MI::WB+MI::BN, 2); |
||
828 | add(MI::WR+MI::WP, 6); |
||
829 | add(MI::WN+MI::BN, 1); |
||
830 | add(MI::WR+MI::BN, 53); |
||
831 | add(MI::WP+MI::BP, 21); |
||
832 | add(MI::WB+MI::BP, 7); |
||
833 | add(MI::WR+MI::WB, 24); |
||
834 | add(MI::WQ+MI::BN, 38); |
||
835 | add(MI::WR+MI::WN, 24); |
||
836 | add(MI::WB+MI::WP, 26); |
||
837 | add(MI::WN+MI::BP, 16); |
||
838 | add(MI::WN+MI::WP, 26); |
||
839 | add(MI::WQ+MI::BR, 62); |
||
840 | add(MI::WQ+MI::BB, 24); |
||
841 | add(MI::WR+MI::BP, 25); |
||
842 | add(MI::WQ+MI::BP, 52); |
||
843 | add(MI::WB+MI::WN, 65); |
||
844 | |||
845 | // 5-men |
||
846 | add(MI::WQ*3, 6); |
||
847 | add(MI::WQ*2+MI::WR, 6); |
||
848 | add(MI::WR*3, 8); |
||
849 | add(MI::WQ*2+MI::WB, 6); |
||
850 | add(MI::WQ*2+MI::WN, 8); |
||
851 | add(MI::WQ*2+MI::WP, 6); |
||
852 | add(MI::WQ+MI::WR+MI::WN, 8); |
||
853 | add(MI::WQ+MI::WR*2, 8); |
||
854 | add(MI::WQ+MI::WR+MI::WB, 8); |
||
855 | add(MI::WQ+MI::WP*2, 6); |
||
856 | add(MI::WQ+MI::WB+MI::WN, 8); |
||
857 | add(MI::WR*2+MI::WP, 6); |
||
858 | add(MI::WQ+MI::WB*2, 12); |
||
859 | add(MI::WB*3, 20); |
||
860 | add(MI::WR*2+MI::WN, 10); |
||
861 | add(MI::WR*2+MI::WB, 10); |
||
862 | add(MI::WQ+MI::WR+MI::WP, 6); |
||
863 | add(MI::WQ+MI::WN*2, 14); |
||
864 | add(MI::WQ+MI::WB+MI::WP, 6); |
||
865 | add(MI::WQ+MI::WN+MI::WP, 6); |
||
866 | add(MI::WR+MI::WP*2, 6); |
||
867 | add(MI::WR+MI::WB*2, 20); |
||
868 | add(MI::WP*3, 14); |
||
869 | add(MI::WR+MI::WN*2, 20); |
||
870 | add(MI::WQ*2+MI::BQ, 50); |
||
871 | add(MI::WQ*2+MI::BN, 8); |
||
872 | add(MI::WQ*2+MI::BB, 8); |
||
873 | add(MI::WR+MI::WB+MI::WN, 14); |
||
874 | add(MI::WB+MI::WP*2, 18); |
||
875 | add(MI::WB*2+MI::WP, 24); |
||
876 | add(MI::WQ*2+MI::BR, 28); |
||
877 | add(MI::WB*2+MI::WN, 26); |
||
878 | add(MI::WN+MI::WP*2, 12); |
||
879 | add(MI::WQ+MI::WB+MI::BQ, 59); |
||
880 | add(MI::WB+MI::WN*2, 26); |
||
881 | add(MI::WN*2+MI::WP, 16); |
||
882 | add(MI::WQ*2+MI::BP, 6); |
||
883 | add(MI::WN*3, 41); |
||
884 | add(MI::WQ+MI::WN+MI::BQ, 69); |
||
885 | add(MI::WQ+MI::WR+MI::BQ, 100); |
||
886 | add(MI::WQ+MI::WR+MI::BN, 10); |
||
887 | add(MI::WQ+MI::WR+MI::BB, 10); |
||
888 | add(MI::WQ+MI::WR+MI::BR, 30); |
||
889 | add(MI::WR+MI::WB+MI::WP, 8); |
||
890 | add(MI::WQ+MI::WB+MI::BN, 14); |
||
891 | add(MI::WQ+MI::WB+MI::BR, 38); |
||
892 | add(MI::WQ+MI::WB+MI::BB, 16); |
||
893 | add(MI::WB+MI::WN+MI::WP, 10); |
||
894 | add(MI::WR+MI::WN+MI::WP, 8); |
||
895 | add(MI::WR*2+MI::BQ, 40); |
||
896 | add(MI::WQ+MI::WN+MI::BN, 18); |
||
897 | add(MI::WR+MI::WB+MI::BR, 100); |
||
898 | add(MI::WQ+MI::WN+MI::BB, 18); |
||
899 | add(MI::WQ+MI::WR+MI::BP, 6); |
||
900 | add(MI::WR+MI::WB+MI::BQ, 82); |
||
901 | add(MI::WQ+MI::WP+MI::BQ, 100); |
||
902 | add(MI::WQ+MI::WP+MI::BP, 10); |
||
903 | add(MI::WQ+MI::WB+MI::BP, 22); |
||
904 | add(MI::WR+MI::WN+MI::BR, 64); |
||
905 | add(MI::WR*2+MI::BN, 14); |
||
906 | add(MI::WR*2+MI::BP, 18); |
||
907 | add(MI::WQ+MI::WN+MI::BR, 44); |
||
908 | add(MI::WR+MI::WN+MI::BQ, 92); |
||
909 | add(MI::WR*2+MI::BB, 20); |
||
910 | add(MI::WQ+MI::WN+MI::BP, 34); |
||
911 | add(MI::WR*2+MI::BR, 50); |
||
912 | add(MI::WB*2+MI::BR, 16); |
||
913 | add(MI::WB*2+MI::BB, 11); |
||
914 | add(MI::WQ+MI::WP+MI::BN, 12); |
||
915 | add(MI::WR+MI::WB+MI::BN, 42); |
||
916 | add(MI::WQ+MI::WP+MI::BB, 10); |
||
917 | add(MI::WB+MI::WN+MI::BR, 24); |
||
918 | add(MI::WB+MI::WN+MI::BB, 24); |
||
919 | add(MI::WB*2+MI::BN, 100); |
||
920 | add(MI::WB+MI::WN+MI::BN, 100); |
||
921 | add(MI::WQ+MI::WP+MI::BR, 34); |
||
922 | add(MI::WR+MI::WP+MI::BP, 19); |
||
923 | add(MI::WR+MI::WP+MI::BR, 70); |
||
924 | add(MI::WR+MI::WB+MI::BB, 50); |
||
925 | add(MI::WB*2+MI::BP, 42); |
||
926 | add(MI::WB*2+MI::BQ, 100); |
||
927 | add(MI::WR+MI::WB+MI::BP, 22); |
||
928 | add(MI::WN*2+MI::BR, 20); |
||
929 | add(MI::WN*2+MI::BB, 6); |
||
930 | add(MI::WB+MI::WP+MI::BR, 36); |
||
931 | add(MI::WN*2+MI::BN, 12); |
||
932 | add(MI::WB+MI::WP+MI::BB, 50); |
||
933 | add(MI::WR+MI::WN+MI::BN, 48); |
||
934 | add(MI::WN+MI::WP+MI::BR, 78); |
||
935 | add(MI::WN*2+MI::BQ, 100); |
||
936 | add(MI::WR+MI::WN+MI::BB, 50); |
||
937 | add(MI::WR+MI::WN+MI::BP, 29); |
||
938 | add(MI::WB+MI::WP+MI::BN, 60); |
||
939 | add(MI::WB+MI::WN+MI::BQ, 84); |
||
940 | add(MI::WB+MI::WP+MI::BP, 74); |
||
941 | add(MI::WN*2+MI::BP, 100); |
||
942 | add(MI::WN+MI::WP+MI::BB, 48); |
||
943 | add(MI::WP*2+MI::BB, 24); |
||
944 | add(MI::WP*2+MI::BQ, 58); |
||
945 | add(MI::WP*2+MI::BP, 42); |
||
946 | add(MI::WP*2+MI::BN, 27); |
||
947 | add(MI::WP*2+MI::BR, 30); |
||
948 | add(MI::WN+MI::WP+MI::BN, 59); |
||
949 | add(MI::WN+MI::WP+MI::BP, 46); |
||
950 | add(MI::WR+MI::WP+MI::BN, 62); |
||
951 | add(MI::WR+MI::WP+MI::BB, 100); |
||
952 | add(MI::WN+MI::WP+MI::BQ, 86); |
||
953 | add(MI::WB+MI::WN+MI::BP, 40); |
||
954 | add(MI::WR+MI::WP+MI::BQ, 100); |
||
955 | add(MI::WB+MI::WP+MI::BQ, 84); |
||
956 | |||
957 | // 6-men |
||
958 | add(MI::WB*4, 20); |
||
959 | add(MI::WB*3+MI::BB, 40); |
||
960 | add(MI::WB*3+MI::BN, 28); |
||
961 | add(MI::WB*3+MI::BP, 24); |
||
962 | add(MI::WB*3+MI::BQ, 100); |
||
963 | add(MI::WB*3+MI::BR, 100); |
||
964 | add(MI::WB*3+MI::WN, 26); |
||
965 | add(MI::WB*3+MI::WP, 24); |
||
966 | add(MI::WB*2+MI::BB*2, 11); |
||
967 | add(MI::WB*2+MI::BB+MI::BN, 40); |
||
968 | add(MI::WB*2+MI::BB+MI::BP, 69); |
||
969 | add(MI::WB*2+MI::BN*2, 56); |
||
970 | add(MI::WB*2+MI::BN+MI::BP, 100); |
||
971 | add(MI::WB*2+MI::BP*2, 39); |
||
972 | add(MI::WB*2+MI::WN+MI::BB, 72); |
||
973 | add(MI::WB*2+MI::WN+MI::BN, 62); |
||
974 | add(MI::WB*2+MI::WN+MI::BP, 32); |
||
975 | add(MI::WB*2+MI::WN+MI::BQ, 100); |
||
976 | add(MI::WB*2+MI::WN+MI::BR, 100); |
||
977 | add(MI::WB*2+MI::WN*2, 20); |
||
978 | add(MI::WB*2+MI::WN+MI::WP, 10); |
||
979 | add(MI::WB*2+MI::WP+MI::BB, 56); |
||
980 | add(MI::WB*2+MI::WP+MI::BN, 100); |
||
981 | add(MI::WB*2+MI::WP+MI::BP, 29); |
||
982 | add(MI::WB*2+MI::WP+MI::BQ, 100); |
||
983 | add(MI::WB*2+MI::WP+MI::BR, 100); |
||
984 | add(MI::WB*2+MI::WP*2, 12); |
||
985 | add(MI::WB+MI::WN+MI::BB+MI::BN, 17); |
||
986 | add(MI::WB+MI::WN+MI::BB+MI::BP, 56); |
||
987 | add(MI::WB+MI::WN+MI::BN*2, 24); |
||
988 | add(MI::WB+MI::WN+MI::BN+MI::BP, 98); |
||
989 | add(MI::WB+MI::WN+MI::BP*2, 48); |
||
990 | add(MI::WB+MI::WN*2+MI::BB, 76); |
||
991 | add(MI::WB+MI::WN*2+MI::BN, 58); |
||
992 | add(MI::WB+MI::WN*2+MI::BP, 33); |
||
993 | add(MI::WB+MI::WN*2+MI::BQ, 98); |
||
994 | add(MI::WB+MI::WN*2+MI::BR, 96); |
||
995 | add(MI::WB+MI::WN*3, 20); |
||
996 | add(MI::WB+MI::WN*2+MI::WP, 10); |
||
997 | add(MI::WB+MI::WN+MI::WP+MI::BB, 86); |
||
998 | add(MI::WB+MI::WN+MI::WP+MI::BN, 77); |
||
999 | add(MI::WB+MI::WN+MI::WP+MI::BP, 21); |
||
1000 | add(MI::WB+MI::WN+MI::WP+MI::BQ, 100); |
||
1001 | add(MI::WB+MI::WN+MI::WP+MI::BR, 100); |
||
1002 | add(MI::WB+MI::WN+MI::WP*2, 10); |
||
1003 | add(MI::WB+MI::WP+MI::BB+MI::BP, 65); |
||
1004 | add(MI::WB+MI::WP+MI::BN*2, 48); |
||
1005 | add(MI::WB+MI::WP+MI::BN+MI::BP, 62); |
||
1006 | add(MI::WB+MI::WP+MI::BP*2, 75); |
||
1007 | add(MI::WB+MI::WP*2+MI::BB, 86); |
||
1008 | add(MI::WB+MI::WP*2+MI::BN, 100); |
||
1009 | add(MI::WB+MI::WP*2+MI::BP, 61); |
||
1010 | add(MI::WB+MI::WP*2+MI::BQ, 78); |
||
1011 | add(MI::WB+MI::WP*2+MI::BR, 66); |
||
1012 | add(MI::WB+MI::WP*3, 18); |
||
1013 | add(MI::WN*2+MI::BN*2, 13); |
||
1014 | add(MI::WN*2+MI::BN+MI::BP, 56); |
||
1015 | add(MI::WN*2+MI::BP*2, 100); |
||
1016 | add(MI::WN*3+MI::BB, 100); |
||
1017 | add(MI::WN*3+MI::BN, 100); |
||
1018 | add(MI::WN*3+MI::BP, 41); |
||
1019 | add(MI::WN*3+MI::BQ, 70); |
||
1020 | add(MI::WN*3+MI::BR, 22); |
||
1021 | add(MI::WN*4, 22); |
||
1022 | add(MI::WN*3+MI::WP, 12); |
||
1023 | add(MI::WN*2+MI::WP+MI::BB, 100); |
||
1024 | add(MI::WN*2+MI::WP+MI::BN, 100); |
||
1025 | add(MI::WN*2+MI::WP+MI::BP, 33); |
||
1026 | add(MI::WN*2+MI::WP+MI::BQ, 100); |
||
1027 | add(MI::WN*2+MI::WP+MI::BR, 91); |
||
1028 | add(MI::WN*2+MI::WP*2, 12); |
||
1029 | add(MI::WN+MI::WP+MI::BN+MI::BP, 57); |
||
1030 | add(MI::WN+MI::WP+MI::BP*2, 66); |
||
1031 | add(MI::WN+MI::WP*2+MI::BB, 97); |
||
1032 | add(MI::WN+MI::WP*2+MI::BN, 96); |
||
1033 | add(MI::WN+MI::WP*2+MI::BP, 40); |
||
1034 | add(MI::WN+MI::WP*2+MI::BQ, 78); |
||
1035 | add(MI::WN+MI::WP*2+MI::BR, 81); |
||
1036 | add(MI::WN+MI::WP*3, 10); |
||
1037 | add(MI::WP*2+MI::BP*2, 31); |
||
1038 | add(MI::WP*3+MI::BB, 36); |
||
1039 | add(MI::WP*3+MI::BN, 42); |
||
1040 | add(MI::WP*3+MI::BP, 40); |
||
1041 | add(MI::WP*3+MI::BQ, 65); |
||
1042 | add(MI::WP*3+MI::BR, 44); |
||
1043 | add(MI::WP*4, 14); |
||
1044 | add(MI::WQ+MI::WB*3, 12); |
||
1045 | add(MI::WQ+MI::WB*2+MI::BB, 16); |
||
1046 | add(MI::WQ+MI::WB*2+MI::BN, 14); |
||
1047 | add(MI::WQ+MI::WB*2+MI::BP, 10); |
||
1048 | add(MI::WQ+MI::WB*2+MI::BQ, 100); |
||
1049 | add(MI::WQ+MI::WB*2+MI::BR, 40); |
||
1050 | add(MI::WQ+MI::WB*2+MI::WN, 10); |
||
1051 | add(MI::WQ+MI::WB*2+MI::WP, 6); |
||
1052 | add(MI::WQ+MI::WB+MI::BB*2, 26); |
||
1053 | add(MI::WQ+MI::WB+MI::BB+MI::BN, 32); |
||
1054 | add(MI::WQ+MI::WB+MI::BB+MI::BP, 44); |
||
1055 | add(MI::WQ+MI::WB+MI::BN*2, 26); |
||
1056 | add(MI::WQ+MI::WB+MI::BN+MI::BP, 53); |
||
1057 | add(MI::WQ+MI::WB+MI::BP*2, 34); |
||
1058 | add(MI::WQ+MI::WB+MI::BQ+MI::BB, 91); |
||
1059 | add(MI::WQ+MI::WB+MI::BQ+MI::BN, 72); |
||
1060 | add(MI::WQ+MI::WB+MI::BQ+MI::BP, 100); |
||
1061 | add(MI::WQ+MI::WB+MI::BR+MI::BB, 83); |
||
1062 | add(MI::WQ+MI::WB+MI::BR+MI::BN, 54); |
||
1063 | add(MI::WQ+MI::WB+MI::BR+MI::BP, 77); |
||
1064 | add(MI::WQ+MI::WB+MI::BR*2, 100); |
||
1065 | add(MI::WQ+MI::WB+MI::WN+MI::BB, 14); |
||
1066 | add(MI::WQ+MI::WB+MI::WN+MI::BN, 12); |
||
1067 | add(MI::WQ+MI::WB+MI::WN+MI::BP, 8); |
||
1068 | add(MI::WQ+MI::WB+MI::WN+MI::BQ, 100); |
||
1069 | add(MI::WQ+MI::WB+MI::WN+MI::BR, 44); |
||
1070 | add(MI::WQ+MI::WB+MI::WN*2, 10); |
||
1071 | add(MI::WQ+MI::WB+MI::WN+MI::WP, 6); |
||
1072 | add(MI::WQ+MI::WB+MI::WP+MI::BB, 12); |
||
1073 | add(MI::WQ+MI::WB+MI::WP+MI::BN, 12); |
||
1074 | add(MI::WQ+MI::WB+MI::WP+MI::BP, 8); |
||
1075 | add(MI::WQ+MI::WB+MI::WP+MI::BQ, 100); |
||
1076 | add(MI::WQ+MI::WB+MI::WP+MI::BR, 62); |
||
1077 | add(MI::WQ+MI::WB+MI::WP*2, 8); |
||
1078 | add(MI::WQ+MI::WN+MI::BB*2, 30); |
||
1079 | add(MI::WQ+MI::WN+MI::BB+MI::BN, 34); |
||
1080 | add(MI::WQ+MI::WN+MI::BB+MI::BP, 67); |
||
1081 | add(MI::WQ+MI::WN+MI::BN*2, 32); |
||
1082 | add(MI::WQ+MI::WN+MI::BN+MI::BP, 62); |
||
1083 | add(MI::WQ+MI::WN+MI::BP*2, 44); |
||
1084 | add(MI::WQ+MI::WN+MI::BQ+MI::BN, 57); |
||
1085 | add(MI::WQ+MI::WN+MI::BQ+MI::BP, 100); |
||
1086 | add(MI::WQ+MI::WN+MI::BR+MI::BB, 52); |
||
1087 | add(MI::WQ+MI::WN+MI::BR+MI::BN, 80); |
||
1088 | add(MI::WQ+MI::WN+MI::BR+MI::BP, 83); |
||
1089 | add(MI::WQ+MI::WN+MI::BR*2, 100); |
||
1090 | add(MI::WQ+MI::WN*2+MI::BB, 22); |
||
1091 | add(MI::WQ+MI::WN*2+MI::BN, 18); |
||
1092 | add(MI::WQ+MI::WN*2+MI::BP, 20); |
||
1093 | add(MI::WQ+MI::WN*2+MI::BQ, 100); |
||
1094 | add(MI::WQ+MI::WN*2+MI::BR, 44); |
||
1095 | add(MI::WQ+MI::WN*3, 10); |
||
1096 | add(MI::WQ+MI::WN*2+MI::WP, 6); |
||
1097 | add(MI::WQ+MI::WN+MI::WP+MI::BB, 12); |
||
1098 | add(MI::WQ+MI::WN+MI::WP+MI::BN, 12); |
||
1099 | add(MI::WQ+MI::WN+MI::WP+MI::BP, 12); |
||
1100 | add(MI::WQ+MI::WN+MI::WP+MI::BQ, 100); |
||
1101 | add(MI::WQ+MI::WN+MI::WP+MI::BR, 42); |
||
1102 | add(MI::WQ+MI::WN+MI::WP*2, 10); |
||
1103 | add(MI::WQ+MI::WP+MI::BB*2, 44); |
||
1104 | add(MI::WQ+MI::WP+MI::BB+MI::BN, 36); |
||
1105 | add(MI::WQ+MI::WP+MI::BB+MI::BP, 99); |
||
1106 | add(MI::WQ+MI::WP+MI::BN*2, 92); |
||
1107 | add(MI::WQ+MI::WP+MI::BN+MI::BP, 54); |
||
1108 | add(MI::WQ+MI::WP+MI::BP*2, 35); |
||
1109 | add(MI::WQ+MI::WP+MI::BQ+MI::BP, 100); |
||
1110 | add(MI::WQ+MI::WP+MI::BR+MI::BB, 100); |
||
1111 | add(MI::WQ+MI::WP+MI::BR+MI::BN, 100); |
||
1112 | add(MI::WQ+MI::WP+MI::BR+MI::BP, 100); |
||
1113 | add(MI::WQ+MI::WP+MI::BR*2, 100); |
||
1114 | add(MI::WQ+MI::WP*2+MI::BB, 12); |
||
1115 | add(MI::WQ+MI::WP*2+MI::BN, 12); |
||
1116 | add(MI::WQ+MI::WP*2+MI::BP, 10); |
||
1117 | add(MI::WQ+MI::WP*2+MI::BQ, 100); |
||
1118 | add(MI::WQ+MI::WP*2+MI::BR, 42); |
||
1119 | add(MI::WQ+MI::WP*3, 6); |
||
1120 | add(MI::WQ*2+MI::WB*2, 6); |
||
1121 | add(MI::WQ*2+MI::WB+MI::BB, 10); |
||
1122 | add(MI::WQ*2+MI::WB+MI::BN, 10); |
||
1123 | add(MI::WQ*2+MI::WB+MI::BP, 6); |
||
1124 | add(MI::WQ*2+MI::WB+MI::BQ, 58); |
||
1125 | add(MI::WQ*2+MI::WB+MI::BR, 52); |
||
1126 | add(MI::WQ*2+MI::WB+MI::WN, 8); |
||
1127 | add(MI::WQ*2+MI::WB+MI::WP, 6); |
||
1128 | add(MI::WQ*2+MI::BB*2, 16); |
||
1129 | add(MI::WQ*2+MI::BB+MI::BN, 16); |
||
1130 | add(MI::WQ*2+MI::BB+MI::BP, 12); |
||
1131 | add(MI::WQ*2+MI::BN*2, 14); |
||
1132 | add(MI::WQ*2+MI::BN+MI::BP, 11); |
||
1133 | add(MI::WQ*2+MI::BP*2, 6); |
||
1134 | add(MI::WQ*2+MI::BQ+MI::BB, 100); |
||
1135 | add(MI::WQ*2+MI::BQ+MI::BN, 100); |
||
1136 | add(MI::WQ*2+MI::BQ+MI::BP, 79); |
||
1137 | add(MI::WQ*2+MI::BQ*2, 87); |
||
1138 | add(MI::WQ*2+MI::BQ+MI::BR, 100); |
||
1139 | add(MI::WQ*2+MI::BR+MI::BB, 27); |
||
1140 | add(MI::WQ*2+MI::BR+MI::BN, 28); |
||
1141 | add(MI::WQ*2+MI::BR+MI::BP, 38); |
||
1142 | add(MI::WQ*2+MI::BR*2, 36); |
||
1143 | add(MI::WQ*2+MI::WN+MI::BB, 8); |
||
1144 | add(MI::WQ*2+MI::WN+MI::BN, 10); |
||
1145 | add(MI::WQ*2+MI::WN+MI::BP, 6); |
||
1146 | add(MI::WQ*2+MI::WN+MI::BQ, 56); |
||
1147 | add(MI::WQ*2+MI::WN+MI::BR, 48); |
||
1148 | add(MI::WQ*2+MI::WN*2, 8); |
||
1149 | add(MI::WQ*2+MI::WN+MI::WP, 6); |
||
1150 | add(MI::WQ*2+MI::WP+MI::BB, 8); |
||
1151 | add(MI::WQ*2+MI::WP+MI::BN, 10); |
||
1152 | add(MI::WQ*2+MI::WP+MI::BP, 6); |
||
1153 | add(MI::WQ*2+MI::WP+MI::BQ, 70); |
||
1154 | add(MI::WQ*2+MI::WP+MI::BR, 48); |
||
1155 | add(MI::WQ*2+MI::WP*2, 6); |
||
1156 | add(MI::WQ*3+MI::WB, 6); |
||
1157 | add(MI::WQ*3+MI::BB, 6); |
||
1158 | add(MI::WQ*3+MI::BN, 8); |
||
1159 | add(MI::WQ*3+MI::BP, 6); |
||
1160 | add(MI::WQ*3+MI::BQ, 38); |
||
1161 | add(MI::WQ*3+MI::BR, 40); |
||
1162 | add(MI::WQ*3+MI::WN, 6); |
||
1163 | add(MI::WQ*3+MI::WP, 6); |
||
1164 | add(MI::WQ*4, 6); |
||
1165 | add(MI::WQ*3+MI::WR, 6); |
||
1166 | add(MI::WQ*2+MI::WR+MI::WB, 6); |
||
1167 | add(MI::WQ*2+MI::WR+MI::BB, 8); |
||
1168 | add(MI::WQ*2+MI::WR+MI::BN, 10); |
||
1169 | add(MI::WQ*2+MI::WR+MI::BP, 6); |
||
1170 | add(MI::WQ*2+MI::WR+MI::BQ, 56); |
||
1171 | add(MI::WQ*2+MI::WR+MI::BR, 48); |
||
1172 | add(MI::WQ*2+MI::WR+MI::WN, 8); |
||
1173 | add(MI::WQ*2+MI::WR+MI::WP, 6); |
||
1174 | add(MI::WQ*2+MI::WR*2, 6); |
||
1175 | add(MI::WQ+MI::WR+MI::WB*2, 8); |
||
1176 | add(MI::WQ+MI::WR+MI::WB+MI::BB, 10); |
||
1177 | add(MI::WQ+MI::WR+MI::WB+MI::BN, 10); |
||
1178 | add(MI::WQ+MI::WR+MI::WB+MI::BP, 6); |
||
1179 | add(MI::WQ+MI::WR+MI::WB+MI::BQ, 98); |
||
1180 | add(MI::WQ+MI::WR+MI::WB+MI::BR, 50); |
||
1181 | add(MI::WQ+MI::WR+MI::WB+MI::WN, 8); |
||
1182 | add(MI::WQ+MI::WR+MI::WB+MI::WP, 8); |
||
1183 | add(MI::WQ+MI::WR+MI::BB*2, 24); |
||
1184 | add(MI::WQ+MI::WR+MI::BB+MI::BN, 22); |
||
1185 | add(MI::WQ+MI::WR+MI::BB+MI::BP, 28); |
||
1186 | add(MI::WQ+MI::WR+MI::BN*2, 21); |
||
1187 | add(MI::WQ+MI::WR+MI::BN+MI::BP, 26); |
||
1188 | add(MI::WQ+MI::WR+MI::BP*2, 12); |
||
1189 | add(MI::WQ+MI::WR+MI::BQ+MI::BB, 100); |
||
1190 | add(MI::WQ+MI::WR+MI::BQ+MI::BN, 100); |
||
1191 | add(MI::WQ+MI::WR+MI::BQ+MI::BP, 100); |
||
1192 | add(MI::WQ+MI::WR+MI::BQ+MI::BR, 100); |
||
1193 | add(MI::WQ+MI::WR+MI::BR+MI::BB, 42); |
||
1194 | add(MI::WQ+MI::WR+MI::BR+MI::BN, 42); |
||
1195 | add(MI::WQ+MI::WR+MI::BR+MI::BP, 44); |
||
1196 | add(MI::WQ+MI::WR+MI::BR*2, 68); |
||
1197 | add(MI::WQ+MI::WR+MI::WN+MI::BB, 8); |
||
1198 | add(MI::WQ+MI::WR+MI::WN+MI::BN, 12); |
||
1199 | add(MI::WQ+MI::WR+MI::WN+MI::BP, 7); |
||
1200 | add(MI::WQ+MI::WR+MI::WN+MI::BQ, 100); |
||
1201 | add(MI::WQ+MI::WR+MI::WN+MI::BR, 48); |
||
1202 | add(MI::WQ+MI::WR+MI::WN*2, 8); |
||
1203 | add(MI::WQ+MI::WR+MI::WN+MI::WP, 8); |
||
1204 | add(MI::WQ+MI::WR+MI::WP+MI::BB, 8); |
||
1205 | add(MI::WQ+MI::WR+MI::WP+MI::BN, 10); |
||
1206 | add(MI::WQ+MI::WR+MI::WP+MI::BP, 7); |
||
1207 | add(MI::WQ+MI::WR+MI::WP+MI::BQ, 100); |
||
1208 | add(MI::WQ+MI::WR+MI::WP+MI::BR, 60); |
||
1209 | add(MI::WQ+MI::WR+MI::WP*2, 6); |
||
1210 | add(MI::WQ+MI::WR*2+MI::WB, 8); |
||
1211 | add(MI::WQ+MI::WR*2+MI::BB, 8); |
||
1212 | add(MI::WQ+MI::WR*2+MI::BN, 10); |
||
1213 | add(MI::WQ+MI::WR*2+MI::BP, 6); |
||
1214 | add(MI::WQ+MI::WR*2+MI::BQ, 82); |
||
1215 | add(MI::WQ+MI::WR*2+MI::BR, 46); |
||
1216 | add(MI::WQ+MI::WR*2+MI::WN, 8); |
||
1217 | add(MI::WQ+MI::WR*2+MI::WP, 6); |
||
1218 | add(MI::WQ+MI::WR*3, 8); |
||
1219 | add(MI::WR+MI::WB*3, 20); |
||
1220 | add(MI::WR+MI::WB*2+MI::BB, 36); |
||
1221 | add(MI::WR+MI::WB*2+MI::BN, 23); |
||
1222 | add(MI::WR+MI::WB*2+MI::BP, 24); |
||
1223 | add(MI::WR+MI::WB*2+MI::BQ, 88); |
||
1224 | add(MI::WR+MI::WB*2+MI::BR, 71); |
||
1225 | add(MI::WR+MI::WB*2+MI::WN, 14); |
||
1226 | add(MI::WR+MI::WB*2+MI::WP, 10); |
||
1227 | add(MI::WR+MI::WB+MI::BB*2, 100); |
||
1228 | add(MI::WR+MI::WB+MI::BB+MI::BN, 100); |
||
1229 | add(MI::WR+MI::WB+MI::BB+MI::BP, 76); |
||
1230 | add(MI::WR+MI::WB+MI::BN*2, 100); |
||
1231 | add(MI::WR+MI::WB+MI::BN+MI::BP, 90); |
||
1232 | add(MI::WR+MI::WB+MI::BP*2, 47); |
||
1233 | add(MI::WR+MI::WB+MI::BR+MI::BB, 33); |
||
1234 | add(MI::WR+MI::WB+MI::BR+MI::BN, 40); |
||
1235 | add(MI::WR+MI::WB+MI::BR+MI::BP, 94); |
||
1236 | add(MI::WR+MI::WB+MI::WN+MI::BB, 26); |
||
1237 | add(MI::WR+MI::WB+MI::WN+MI::BN, 24); |
||
1238 | add(MI::WR+MI::WB+MI::WN+MI::BP, 31); |
||
1239 | add(MI::WR+MI::WB+MI::WN+MI::BQ, 100); |
||
1240 | add(MI::WR+MI::WB+MI::WN+MI::BR, 72); |
||
1241 | add(MI::WR+MI::WB+MI::WN*2, 14); |
||
1242 | add(MI::WR+MI::WB+MI::WN+MI::WP, 10); |
||
1243 | add(MI::WR+MI::WB+MI::WP+MI::BB, 20); |
||
1244 | add(MI::WR+MI::WB+MI::WP+MI::BN, 20); |
||
1245 | add(MI::WR+MI::WB+MI::WP+MI::BP, 21); |
||
1246 | add(MI::WR+MI::WB+MI::WP+MI::BQ, 100); |
||
1247 | add(MI::WR+MI::WB+MI::WP+MI::BR, 100); |
||
1248 | add(MI::WR+MI::WB+MI::WP*2, 8); |
||
1249 | add(MI::WR+MI::WN+MI::BB*2, 100); |
||
1250 | add(MI::WR+MI::WN+MI::BB+MI::BN, 100); |
||
1251 | add(MI::WR+MI::WN+MI::BB+MI::BP, 100); |
||
1252 | add(MI::WR+MI::WN+MI::BN*2, 100); |
||
1253 | add(MI::WR+MI::WN+MI::BN+MI::BP, 100); |
||
1254 | add(MI::WR+MI::WN+MI::BP*2, 48); |
||
1255 | add(MI::WR+MI::WN+MI::BR+MI::BN, 41); |
||
1256 | add(MI::WR+MI::WN+MI::BR+MI::BP, 72); |
||
1257 | add(MI::WR+MI::WN*2+MI::BB, 24); |
||
1258 | add(MI::WR+MI::WN*2+MI::BN, 25); |
||
1259 | add(MI::WR+MI::WN*2+MI::BP, 30); |
||
1260 | add(MI::WR+MI::WN*2+MI::BQ, 81); |
||
1261 | add(MI::WR+MI::WN*2+MI::BR, 78); |
||
1262 | add(MI::WR+MI::WN*3, 14); |
||
1263 | add(MI::WR+MI::WN*2+MI::WP, 8); |
||
1264 | add(MI::WR+MI::WN+MI::WP+MI::BB, 26); |
||
1265 | add(MI::WR+MI::WN+MI::WP+MI::BN, 20); |
||
1266 | add(MI::WR+MI::WN+MI::WP+MI::BP, 27); |
||
1267 | add(MI::WR+MI::WN+MI::WP+MI::BQ, 100); |
||
1268 | add(MI::WR+MI::WN+MI::WP+MI::BR, 100); |
||
1269 | add(MI::WR+MI::WN+MI::WP*2, 10); |
||
1270 | add(MI::WR+MI::WP+MI::BB*2, 79); |
||
1271 | add(MI::WR+MI::WP+MI::BB+MI::BN, 100); |
||
1272 | add(MI::WR+MI::WP+MI::BB+MI::BP, 100); |
||
1273 | add(MI::WR+MI::WP+MI::BN*2, 84); |
||
1274 | add(MI::WR+MI::WP+MI::BN+MI::BP, 100); |
||
1275 | add(MI::WR+MI::WP+MI::BP*2, 31); |
||
1276 | add(MI::WR+MI::WP+MI::BR+MI::BP, 73); |
||
1277 | add(MI::WR+MI::WP*2+MI::BB, 36); |
||
1278 | add(MI::WR+MI::WP*2+MI::BN, 36); |
||
1279 | add(MI::WR+MI::WP*2+MI::BP, 26); |
||
1280 | add(MI::WR+MI::WP*2+MI::BQ, 100); |
||
1281 | add(MI::WR+MI::WP*2+MI::BR, 90); |
||
1282 | add(MI::WR+MI::WP*3, 6); |
||
1283 | add(MI::WR*2+MI::WB*2, 12); |
||
1284 | add(MI::WR*2+MI::WB+MI::BB, 14); |
||
1285 | add(MI::WR*2+MI::WB+MI::BN, 12); |
||
1286 | add(MI::WR*2+MI::WB+MI::BP, 8); |
||
1287 | add(MI::WR*2+MI::WB+MI::BQ, 100); |
||
1288 | add(MI::WR*2+MI::WB+MI::BR, 62); |
||
1289 | add(MI::WR*2+MI::WB+MI::WN, 12); |
||
1290 | add(MI::WR*2+MI::WB+MI::WP, 8); |
||
1291 | add(MI::WR*2+MI::BB*2, 74); |
||
1292 | add(MI::WR*2+MI::BB+MI::BN, 51); |
||
1293 | add(MI::WR*2+MI::BB+MI::BP, 52); |
||
1294 | add(MI::WR*2+MI::BN*2, 66); |
||
1295 | add(MI::WR*2+MI::BN+MI::BP, 50); |
||
1296 | add(MI::WR*2+MI::BP*2, 50); |
||
1297 | add(MI::WR*2+MI::BR+MI::BB, 100); |
||
1298 | add(MI::WR*2+MI::BR+MI::BN, 100); |
||
1299 | add(MI::WR*2+MI::BR+MI::BP, 100); |
||
1300 | add(MI::WR*2+MI::BR*2, 35); |
||
1301 | add(MI::WR*2+MI::WN+MI::BB, 14); |
||
1302 | add(MI::WR*2+MI::WN+MI::BN, 14); |
||
1303 | add(MI::WR*2+MI::WN+MI::BP, 18); |
||
1304 | add(MI::WR*2+MI::WN+MI::BQ, 100); |
||
1305 | add(MI::WR*2+MI::WN+MI::BR, 66); |
||
1306 | add(MI::WR*2+MI::WN*2, 12); |
||
1307 | add(MI::WR*2+MI::WN+MI::WP, 8); |
||
1308 | add(MI::WR*2+MI::WP+MI::BB, 14); |
||
1309 | add(MI::WR*2+MI::WP+MI::BN, 12); |
||
1310 | add(MI::WR*2+MI::WP+MI::BP, 22); |
||
1311 | add(MI::WR*2+MI::WP+MI::BQ, 100); |
||
1312 | add(MI::WR*2+MI::WP+MI::BR, 56); |
||
1313 | add(MI::WR*2+MI::WP*2, 6); |
||
1314 | add(MI::WR*3+MI::WB, 10); |
||
1315 | add(MI::WR*3+MI::BB, 10); |
||
1316 | add(MI::WR*3+MI::BN, 12); |
||
1317 | add(MI::WR*3+MI::BP, 6); |
||
1318 | add(MI::WR*3+MI::BQ, 100); |
||
1319 | add(MI::WR*3+MI::BR, 42); |
||
1320 | add(MI::WR*3+MI::WN, 10); |
||
1321 | add(MI::WR*3+MI::WP, 8); |
||
1322 | add(MI::WR*4, 8); |
||
1323 | } |