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 | } |