00001
00002
00003
00004 #ifndef EVAL_ML_MAJORPIECE_H
00005 #define EVAL_ML_MAJORPIECE_H
00006
00007 #include "osl/eval/weights.h"
00008 #include "osl/eval/midgame.h"
00009 #include "osl/numEffectState.h"
00010 #include <cstdlib>
00011
00012 namespace osl
00013 {
00014 namespace eval
00015 {
00016 namespace ml
00017 {
00018 template <bool Opening, Ptype MajorBasic>
00019 class MajorY
00020 {
00021 private:
00022 static CArray<int, 18> table;
00023 static int index(Piece piece)
00024 {
00025 return ((piece.owner() == BLACK) ? (piece.square().y() - 1) :
00026 (9 - piece.square().y())) + (piece.isPromoted() ? 9 : 0);
00027 }
00028 public:
00029 enum { DIM = 18 };
00030 static void setUp(const Weights &weights);
00031 static int eval(const NumEffectState &state)
00032 {
00033 int value = 0;
00034 for (int i = PtypeTraits<MajorBasic>::indexMin;
00035 i < PtypeTraits<MajorBasic>::indexLimit;
00036 ++i)
00037 {
00038 const Piece piece = state.pieceOf(i);
00039 if (piece.isOnBoard())
00040 {
00041 if (piece.owner() == BLACK)
00042 value += table[index(piece)];
00043 else
00044 value -= table[index(piece)];
00045 }
00046 }
00047 return value;
00048 }
00049 };
00050
00051 class RookYOpening : public MajorY<true, ROOK>
00052 {
00053 };
00054 class RookYEnding : public MajorY<false, ROOK>
00055 {
00056 };
00057 class BishopYOpening : public MajorY<true, BISHOP>
00058 {
00059 };
00060 class BishopYEnding : public MajorY<false, BISHOP>
00061 {
00062 };
00063
00064 template <bool Opening>
00065 class RookPawn
00066 {
00067 public:
00068 enum { DIM = 1 };
00069 static void setUp(const Weights &weights);
00070 static int eval(const NumEffectState &state);
00071 private:
00072 static int weight;
00073 };
00074 class RookPawnOpening : public RookPawn<true>
00075 {
00076 };
00077 class RookPawnEnding : public RookPawn<false>
00078 {
00079 };
00080
00081 class RookPawnY
00082 {
00083 friend class RookPawnYX;
00084 public:
00085 enum { ONE_DIM = 180, DIM = ONE_DIM * EvalStages };
00086 static void setUp(const Weights &weights);
00087 static MultiInt eval(const NumEffectState &state,
00088 const CArray2d<int, 2, 9> &pawns);
00089 private:
00090 static int index(const Piece rook, const int pawn_y)
00091 {
00092 const int rook_y =
00093 (rook.owner() == BLACK ? rook.square().y() : 10 - rook.square().y());
00094 return (rook_y - 1) * 10 + pawn_y + (rook.isPromoted() ? 90 : 0);
00095 }
00096 static int indexY(const Square king,
00097 const Piece rook, int pawn_y)
00098 {
00099 const int x_diff = std::abs(rook.square().x() - king.x());
00100 const int rook_y =
00101 (rook.owner() == BLACK ? rook.square().y() : 10 - rook.square().y());
00102 return x_diff * 10 * 9 + (rook_y - 1) * 10 + pawn_y + (rook.isPromoted() ? 810 : 0);
00103 }
00104 static CArray<MultiInt, 180> table;
00105 static CArray<MultiInt, 1620> y_attack_table;
00106 static CArray<MultiInt, 1620> y_defense_table;
00107 };
00108
00109 class RookPawnYX
00110 {
00111 public:
00112 enum { ONE_DIM = 1620, DIM = ONE_DIM * 2*EvalStages };
00113 static void setUp(const Weights &weights);
00114 };
00115
00116 class AllMajor
00117 {
00118 public:
00119 enum { DIM = 1 };
00120 static void setUp(const Weights &weights,int stage);
00121 static MultiInt eval(int black_major_count)
00122 {
00123 if (black_major_count == 4)
00124 return weight;
00125 else if (black_major_count == 0)
00126 return -weight;
00127
00128 return MultiInt();
00129 }
00130 private:
00131 static MultiInt weight;
00132 };
00133
00134 template <bool Opening>
00135 class MajorGoldSilverAttacked
00136 {
00137 public:
00138 enum { DIM = 32 };
00139 static void setUp(const Weights &weights);
00140 static int eval(const NumEffectState &state);
00141 static int index(const NumEffectState &state, Piece piece);
00142 template <Ptype PTYPE>
00143 static int evalOne(const NumEffectState &state);
00144 private:
00145 static CArray<int, 32> table;
00146 };
00147
00148 class MajorGoldSilverAttackedOpening : public MajorGoldSilverAttacked<true>
00149 {
00150 };
00151 class MajorGoldSilverAttackedEnding : public MajorGoldSilverAttacked<false>
00152 {
00153 };
00154
00155 class RookEffectBase
00156 {
00157 friend class RookEffectPiece;
00158 public:
00159 enum { ONE_DIM = 612, DIM = ONE_DIM * 2 };
00160 static MultiInt eval(const NumEffectState &state);
00161 protected:
00162 template<Player P>
00163 static MultiInt evalOne(const NumEffectState& state,
00164 Square rook,
00165 Square myKing,
00166 Square opKing,
00167 Square up,
00168 Square dp,
00169 Square rp,
00170 Square lp,
00171 bool isP);
00177 static int index(int abs_x_diff, int y_diff, bool horizontal, bool is_promoted)
00178 {
00179 return y_diff + 8 + abs_x_diff * 17 + (horizontal ? 153 : 0) +
00180 (is_promoted ? 306 : 0);
00181 }
00190 static int index0(int abs_x_diff,int y_diff,
00191 PtypeO ptypeO,
00192 bool horizontal, bool promoted){
00193 return y_diff+8+abs_x_diff*17+(ptypeO - PTYPEO_MIN) * 17 * 9 +
00194 (horizontal ? 4896 : 0) + (promoted ? 9792 : 0);
00195 }
00205 static int index1(Square king,Square from,PtypeO ptypeO,bool isP)
00206 {
00207 int y_diff=from.y()-king.y();
00208 int x_diff=from.x()-king.x();
00209 return index1(x_diff,y_diff,ptypeO,isP);
00210 }
00219 static int index1(int x_diff,int y_diff,PtypeO ptypeO,bool isP){
00220 assert(-9 <= y_diff && y_diff <= 9);
00221 assert(-9 <= x_diff && x_diff <= 9);
00222 assert(getPtype((PtypeO)ptypeO)!=PTYPE_EMPTY);
00223 int index=(ptypeO-PTYPEO_MIN)+32*((y_diff+9)+19*(x_diff+9+19*(isP ? 1 : 0)));
00224 assert(0<=index && index<32*19*19*2);
00225 return index;
00226 }
00234 static int index2(Square king,Square from,bool isP)
00235 {
00236 int y_diff=from.y()-king.y();
00237 int x_diff=from.x()-king.x();
00238 return index2(x_diff,y_diff,isP);
00239 }
00246 static int index2(int x_diff,int y_diff,bool isP){
00247 assert(-9 <= y_diff && y_diff <= 9);
00248 assert(-9 <= x_diff && x_diff <= 9);
00249 int index=(y_diff+9)+19*(x_diff+9+19*(isP ? 1 : 0));
00250 assert(0<=index && index<19*19*2);
00251 return index;
00252 }
00253 static CArray<MultiInt, 612> attack_table;
00254 static CArray<MultiInt, 612> defense_table;
00255 static CArray<MultiInt, 32> piece_table;
00256 static CArray<MultiInt, 23104> attack_u;
00257 static CArray<MultiInt, 23104> attack_d;
00258 static CArray<MultiInt, 23104> attack_l;
00259 static CArray<MultiInt, 23104> attack_r;
00260 static CArray<MultiInt, 23104> defense_u;
00261 static CArray<MultiInt, 23104> defense_d;
00262 static CArray<MultiInt, 23104> defense_l;
00263 static CArray<MultiInt, 23104> defense_r;
00264 static CArray<MultiInt, 722> attack_nospace;
00265 static CArray<MultiInt, 722> defense_nospace;
00266 };
00267 class RookEffect : public RookEffectBase
00268 {
00269 public:
00270 static void setUp(const Weights &weights,int stage);
00271 };
00272
00273 class RookEffectPiece
00274 {
00275 public:
00276 enum { DIM = 32 * EvalStages };
00277 static void setUp(const Weights &weights);
00278 };
00279 class RookEffectPieceKingRelative : RookEffectBase
00280 {
00281 public:
00282 enum { ONE_DIM = 19584, DIM = ONE_DIM * 2*EvalStages };
00283 static void setUp(const Weights & weights);
00284 };
00285
00286 class RookPromoteDefense : public RookEffectBase
00287 {
00288 friend class RookPromoteDefenseRookH;
00289 public:
00290 enum { ONE_DIM = 256, DIM = ONE_DIM * EvalStages };
00291 static void setUp(const Weights &weights);
00292 static MultiInt eval(const NumEffectState &state);
00293 private:
00294 static CArray<MultiInt, 256> promote_defense_table;
00295 static CArray<MultiInt, 144> promote_defense_rook_table;
00296 };
00297
00298 class RookPromoteDefenseRookH : public RookEffectBase
00299 {
00300 public:
00301 enum { ONE_DIM = 144, DIM = ONE_DIM * EvalStages };
00302 static void setUp(const Weights &weights);
00303 private:
00304 };
00305
00306 class BishopEffectBase
00307 {
00308 friend class BishopEffectPiece;
00309 public:
00310 enum { ONE_DIM = 612, DIM = ONE_DIM * 2 };
00311 static MultiInt eval(const NumEffectState &state);
00312 protected:
00313 template<Player P>
00314 static MultiInt evalOne(const NumEffectState& state,
00315 Square bishop,
00316 Square myKing,
00317 Square opKing,
00318 Square ulp,
00319 Square urp,
00320 Square dlp,
00321 Square drp,
00322 bool isP);
00323 static int index(int x_diff, int y_diff, bool ur, bool promoted)
00324 {
00325 if (x_diff<0)
00326 ur = !ur;
00327 return y_diff + 8 + std::abs(x_diff) * 17 + (ur ? 153 : 0) + (promoted ? 306 : 0);
00328 }
00329 static int index0(int x_diff, int y_diff,PtypeO ptypeO,bool ur, bool promoted)
00330 {
00331 if (x_diff>0)
00332 ur = !ur;
00333 return -y_diff + 8 + std::abs(x_diff) * 17 + (ptypeO - PTYPEO_MIN) * 17 * 9 +
00334 (ur ? 4896 : 0) + (promoted ? 9792 : 0);
00335 }
00345 static int index1(Square king,Square from,PtypeO ptypeO,bool isP)
00346 {
00347 int y_diff=from.y()-king.y();
00348 int x_diff=from.x()-king.x();
00349 return index1(x_diff,y_diff,ptypeO,isP);
00350 }
00359 static int index1(int x_diff,int y_diff,PtypeO ptypeO,bool isP){
00360 assert(-9 <= y_diff && y_diff <= 9);
00361 assert(-9 <= x_diff && x_diff <= 9);
00362 assert(getPtype((PtypeO)ptypeO)!=PTYPE_EMPTY);
00363 int index=(ptypeO-PTYPEO_MIN)+32*((y_diff+9)+19*(x_diff+9+19*(isP ? 1 : 0)));
00364 assert(0<=index && index<32*19*19*2);
00365 return index;
00366 }
00374 static int index2(Square king,Square from,bool isP)
00375 {
00376 int y_diff=from.y()-king.y();
00377 int x_diff=from.x()-king.x();
00378 return index2(x_diff,y_diff,isP);
00379 }
00386 static int index2(int x_diff,int y_diff,bool isP){
00387 assert(-9 <= y_diff && y_diff <= 9);
00388 assert(-9 <= x_diff && x_diff <= 9);
00389 int index=(y_diff+9)+19*(x_diff+9+19*(isP ? 1 : 0));
00390 assert(0<=index && index<19*19*2);
00391 return index;
00392 }
00393 static CArray<MultiInt, 612> attack_table;
00394 static CArray<MultiInt, 612> defense_table;
00395 static CArray<MultiInt, 32> piece_table;
00396 static CArray<MultiInt, 23104> attack_ur;
00397 static CArray<MultiInt, 23104> attack_ul;
00398 static CArray<MultiInt, 23104> attack_dr;
00399 static CArray<MultiInt, 23104> attack_dl;
00400 static CArray<MultiInt, 23104> defense_ur;
00401 static CArray<MultiInt, 23104> defense_ul;
00402 static CArray<MultiInt, 23104> defense_dr;
00403 static CArray<MultiInt, 23104> defense_dl;
00404 static CArray<MultiInt, 722> attack_nospace;
00405 static CArray<MultiInt, 722> defense_nospace;
00406 };
00407 class BishopEffect : public BishopEffectBase
00408 {
00409 public:
00410 static void setUp(const Weights &weights,int stage);
00411 };
00412 class BishopEffectPiece
00413 {
00414 public:
00415 enum { DIM = 32*EvalStages };
00416 static void setUp(const Weights &weights);
00417 };
00418
00419 class BishopEffectPieceKingRelative : BishopEffectBase
00420 {
00421 public:
00422 enum { ONE_DIM = 19584, DIM = ONE_DIM * 2*EvalStages };
00423 static void setUp(const Weights & weights);
00424 };
00425
00426 class BishopHead
00427 {
00428 friend class BishopHeadKingRelative;
00429 friend class BishopHeadX;
00430 public:
00431 enum { ONE_DIM = 32, DIM = ONE_DIM * EvalStages };
00432 static void setUp(const Weights &weights);
00433 static MultiInt eval(const NumEffectState &state);
00434 private:
00435 static int indexK(Player player, PtypeO ptypeO, int x_diff, int y_diff)
00436 {
00437 if (player == WHITE)
00438 {
00439 ptypeO=(PtypeO)(static_cast<int>(ptypeO)^(~15));
00440 }
00441 if (player == WHITE)
00442 {
00443 y_diff = -y_diff;
00444 }
00445 return (ptypeOIndex(ptypeO) * 9 + x_diff) * 17 + y_diff + 8;
00446 }
00447 template <Player P>
00448 static int indexX(PtypeO ptypeO, int x)
00449 {
00450 if (x > 5)
00451 {
00452 x = 10 - x;
00453 }
00454 if (P == WHITE)
00455 {
00456 ptypeO = altIfPiece(ptypeO);
00457 }
00458 return x - 1 + 5 * ptypeOIndex(ptypeO);
00459 }
00460 static CArray<MultiInt, 32> table;
00461 static CArray<MultiInt, 4896> king_table;
00462 static CArray<MultiInt, 160> x_table;
00463 };
00464
00465 class BishopHeadKingRelative
00466 {
00467 public:
00468 enum { ONE_DIM = 4896, DIM = ONE_DIM * EvalStages };
00469 static void setUp(const Weights &weights);
00470 };
00471 class BishopHeadX
00472 {
00473 public:
00474 enum { ONE_DIM = 160, DIM = ONE_DIM * EvalStages };
00475 static void setUp(const Weights &weights);
00476 };
00477 class KingRookBishop
00478 {
00479 public:
00480 enum { ONE_DIM = 374544, DIM = ONE_DIM * EvalStages };
00481 static void setUp(const Weights &weights);
00482 template<Player King>
00483 static MultiInt evalOne(const NumEffectState &state);
00484 static MultiInt eval(const NumEffectState &state);
00485 private:
00486 static CArray<MultiInt, 374544> table;
00487 template <Player King>
00488 static int index(const Square king, const Piece rook, const Piece bishop)
00489 {
00490 const int rook_x = std::abs(king.x() - rook.square().x());
00491 const int bishop_x = std::abs(king.x() - bishop.square().x());
00492 const int rook_y = (King == BLACK ? rook.square().y() - king.y() : king.y() - rook.square().y());
00493 const int bishop_y = (King == BLACK ? bishop.square().y() - king.y() : king.y() - bishop.square().y());
00494 return bishop_y + 8 + 17 * (bishop_x + 9 * (rook_y + 8 + 17 * (rook_x + 9 * ((bishop.owner() == King ? 1 : 0) + 2 * ((rook.owner() == King ? 1 : 0) + 2 * (2 * (bishop.isPromoted() ? 1 : 0) + (rook.isPromoted() ? 1 : 0)))))));
00495 }
00496 };
00497
00498 class NumPiecesBetweenBishopAndKing
00499 {
00500 friend class NumPiecesBetweenBishopAndKingSelf;
00501 friend class NumPiecesBetweenBishopAndKingOpp;
00502 friend class NumPiecesBetweenBishopAndKingAll;
00503 public:
00504 static MultiInt eval(const NumEffectState &state);
00505 private:
00506 static void countBetween(const NumEffectState &state,
00507 Square king, Piece bishop,
00508 int &self_count, int &opp_count,
00509 int &total_count);
00510 static CArray<MultiInt, 9> self_table;
00511 static CArray<MultiInt, 9> opp_table;
00512 static CArray<MultiInt, 9> all_table;
00513 };
00514 class NumPiecesBetweenBishopAndKingSelf
00515 {
00516 public:
00517 enum { ONE_DIM = 9, DIM = ONE_DIM * EvalStages };
00518 static void setUp(const Weights &weights);
00519 };
00520 class NumPiecesBetweenBishopAndKingOpp
00521 {
00522 public:
00523 enum { ONE_DIM = 9, DIM = ONE_DIM * EvalStages };
00524 static void setUp(const Weights &weights);
00525 };
00526 class NumPiecesBetweenBishopAndKingAll
00527 {
00528 public:
00529 enum { ONE_DIM = 9, DIM = ONE_DIM * EvalStages };
00530 static void setUp(const Weights &weights);
00531 };
00532 class BishopBishopPiece
00533 {
00534 public:
00535 enum { ONE_DIM = 64, DIM = ONE_DIM * EvalStages };
00536 static void setUp(const Weights &weights);
00537 static MultiInt eval(const NumEffectState &state);
00538 private:
00539 static int index(Ptype ptype, bool self_with_support,
00540 bool opp_with_support)
00541 {
00542 return ptype + PTYPE_SIZE * ((self_with_support ? 1 : 0) +
00543 2 * (opp_with_support ? 1 : 0));
00544 }
00545 static CArray<MultiInt, 64> table;
00546 };
00547
00548 class RookRook
00549 {
00550 public:
00551 enum { ONE_DIM = 800, DIM = ONE_DIM * EvalStages };
00552 static void setUp(const Weights &weights);
00553 static MultiInt eval(const NumEffectState &state);
00554 private:
00555 template <bool SamePlayer, Player P>
00556 static int index(Piece rook1, Piece rook2)
00557 {
00558 const int y1 = (rook1.isOnBoard() ? rook1.square().y() : 0);
00559 const int y2 = (rook2.isOnBoard() ? rook2.square().y() : 0);
00560 if (SamePlayer)
00561 {
00562 if (P == BLACK)
00563 {
00564 return y1 + 10 *
00565 (y2 + 10 * ((rook1.isPromoted() ? 1 : 0) + 2 *
00566 ((rook2.isPromoted() ? 1 : 0) + 2 *
00567 (SamePlayer ? 1 : 0))));
00568 }
00569 else
00570 {
00571 if (y1 == 0 || y2 == 0 || y1 == y2)
00572 {
00573 return (10 - y1) % 10 + 10 *
00574 ((10 - y2) % 10 + 10 * ((rook1.isPromoted() ? 1 : 0) + 2 *
00575 ((rook2.isPromoted() ? 1 : 0) + 2 *
00576 (SamePlayer ? 1 : 0))));
00577 }
00578 else
00579 {
00580 return (10 - y2) % 10 + 10 *
00581 ((10 - y1) % 10 + 10 * ((rook2.isPromoted() ? 1 : 0) + 2 *
00582 ((rook1.isPromoted() ? 1 : 0) + 2 *
00583 (SamePlayer ? 1 : 0))));
00584 }
00585 }
00586 }
00587 else
00588 {
00589 return y1 + 10 *
00590 (y2 + 10 * ((rook1.isPromoted() ? 1 : 0) + 2 *
00591 ((rook2.isPromoted() ? 1 : 0) + 2 *
00592 (SamePlayer ? 1 : 0))));
00593 }
00594 }
00595 static int index(bool same_player, bool promoted1,
00596 bool promoted2, int y1, int y2)
00597 {
00598 return y1 + 10 *
00599 (y2 + 10 * ((promoted1 ? 1 : 0) + 2 *
00600 ((promoted2 ? 1 : 0) + 2 *
00601 (same_player ? 1 : 0))));
00602 }
00603 static CArray<MultiInt, 800> table;
00604 };
00605
00606 class RookRookPiece
00607 {
00608 public:
00609 enum { ONE_DIM = 128, DIM = ONE_DIM * EvalStages };
00610 static void setUp(const Weights &weights);
00611 static MultiInt eval(const NumEffectState &state);
00612 private:
00613 static int index(Ptype ptype, bool self_with_support,
00614 bool opp_with_support, bool vertical)
00615 {
00616 return ptype + PTYPE_SIZE * ((self_with_support ? 1 : 0) +
00617 2 * (opp_with_support ? 1 : 0)) +
00618 (vertical ? PTYPE_SIZE * 2 * 2 : 0);
00619 }
00620 static CArray<MultiInt, 128> table;
00621 };
00622
00623 class BishopStandFile5
00624 {
00625 public:
00626 enum { ONE_DIM = 32, DIM = ONE_DIM * EvalStages };
00627 static void setUp(const Weights &weights);
00628 static MultiInt eval(const NumEffectState &state);
00629 private:
00630 static CArray<MultiInt, 32> table;
00631 };
00632
00633 class MajorCheckWithCapture
00634 {
00635 public:
00636 enum {
00637 ONE_DIM = PTYPE_SIZE * 2 * 2 ,
00638 DIM = ONE_DIM * EvalStages
00639 };
00640 static void setUp(const Weights &weights);
00641 static MultiInt eval(const NumEffectState &state);
00642 private:
00643 static CArray<MultiInt, ONE_DIM> table;
00644 template <Player Owner>
00645 static MultiInt addOne(const NumEffectState &state);
00646 static size_t index(Ptype ptype, bool is_rook, bool can_promote)
00647 {
00648 return ptype * 4 + is_rook * 2 + can_promote;
00649 }
00650 };
00651
00652 class RookSilverKnight
00653 {
00654 public:
00655 enum {
00656 ONE_DIM = 5 * 9 * 9 * 9 * 9 * 9,
00657 DIM = ONE_DIM * EvalStages
00658 };
00659 static void setUp(const Weights &weights);
00660 static MultiInt eval(const NumEffectState &state);
00661 private:
00662 static CArray<MultiInt, ONE_DIM> table;
00663 static size_t index(int rook_x, int rook_y, int silver_x, int silver_y,
00664 int knight_x, int knight_y)
00665 {
00666 return knight_y + 9 * (knight_x + 9 * (silver_y + 9 * (silver_x + 9 * (rook_y + 9 * rook_x))));
00667 }
00668 };
00669
00670 class BishopSilverKnight
00671 {
00672 public:
00673 enum {
00674 ONE_DIM = 5 * 9 * 9 * 9 * 9 * 9,
00675 DIM = ONE_DIM * EvalStages
00676 };
00677 static void setUp(const Weights &weights);
00678 static MultiInt eval(const NumEffectState &state);
00679 private:
00680 static CArray<MultiInt, ONE_DIM> table;
00681 static size_t index(int bishop_x, int bishop_y, int silver_x, int silver_y,
00682 int knight_x, int knight_y)
00683 {
00684 return knight_y + 9 * (knight_x + 9 * (silver_y + 9 * (silver_x + 9 * (bishop_y + 9 * bishop_x))));
00685 }
00686 };
00687
00688 class AttackMajorsInBase
00689 {
00690 public:
00691 enum {
00692 ONE_DIM = PTYPE_SIZE * PTYPE_SIZE * 2 * 2 * 2,
00693 DIM = ONE_DIM * EvalStages
00694 };
00695 static void setUp(const Weights &weights);
00696 static MultiInt eval(const NumEffectState &state);
00697 private:
00698 static CArray<MultiInt, ONE_DIM> table;
00699 size_t maxActive() const { return 4; }
00700 static int index(Ptype support, Ptype attack, bool has_gold,
00701 bool rook_support, bool bishop_support)
00702 {
00703 return (unpromoteSafe(support)*16 + unpromoteSafe(attack))*8+has_gold*4
00704 +rook_support*2+bishop_support;
00705 }
00706 template <Player Owner>
00707 static void addOne(const NumEffectState &state, Piece rook, MultiInt&);
00708 };
00709 }
00710 }
00711 }
00712
00713 #endif // EVAL_ML_MAJORPIECE_H
00714
00715
00716
00717