minorPieceBonus.h
Go to the documentation of this file.
00001 /* minorPieceBonus.h
00002  */
00003 #ifndef EVAL_MINORPIECEBONUS_H
00004 #define EVAL_MINORPIECEBONUS_H
00005 
00006 #include "osl/eval/pieceEval.h"
00007 #include "osl/progress/progress16.h"
00008 #include "osl/state/simpleState.h"
00009 #include <boost/static_assert.hpp>
00010 
00011 namespace osl
00012 {
00013   namespace eval
00014   {
00015     struct MinorPieceDebugInfo
00016     {
00017       int pawn_bonus, lance_bonus, knight_bonus, gold_bonus;
00018     };
00022     class MinorPieceBonus
00023     {
00024       CArray<int,2> pawn_on_stand;
00025       CArray<int,2> lance_on_stand;
00026       CArray<int,2> knight_on_stand;
00027       CArray<int,2> pawns;
00028       CArray<int,2> golds;
00029     private:
00030       int pawnBonus(Progress16 progress16) const
00031       {
00032         const int black_pawn = pawn_on_stand[BLACK];
00033         const int white_pawn = pawn_on_stand[WHITE];
00034         const int black_pawn_total = pawns[BLACK];
00035         const int white_pawn_total =  pawns[WHITE];
00036         int result = 0;
00037         if (black_pawn > 1)
00038         {
00039           result -= (black_pawn - 1) * progress16.value() *
00040             PtypeEvalTraits<PAWN>::val / 32;
00041         }
00042         else if (black_pawn == 0 && black_pawn_total < white_pawn_total)
00043         {
00044           result -= PtypeEvalTraits<PAWN>::val / 2;
00045         }
00046         if (black_pawn >= 9)
00047         {
00048           result -= (black_pawn - 8) * progress16.value() *
00049             PtypeEvalTraits<PAWN>::val / 8;
00050         }
00051         if (white_pawn > 1)
00052         {
00053           result += (white_pawn - 1) * progress16.value() * 
00054             PtypeEvalTraits<PAWN>::val / 32;
00055         }
00056         else if (white_pawn == 0 && white_pawn_total < black_pawn_total)
00057         {
00058           result += PtypeEvalTraits<PAWN>::val / 2;
00059         }
00060         if (white_pawn >= 9)
00061         {
00062           result += (white_pawn - 8) * progress16.value() *
00063             PtypeEvalTraits<PAWN>::val / 8;
00064         }
00065         return result;
00066       }
00067       int lanceBonus(Progress16 progress16) const
00068       {
00069         const int black_lance = lance_on_stand[BLACK];
00070         const int white_lance = lance_on_stand[WHITE];
00071         int result = 0;
00072         if (black_lance > 1)
00073         {
00074           result -= (black_lance - 1) * progress16.value() * PtypeEvalTraits<LANCE>::val / 32;
00075         }
00076         if (black_lance > 2)
00077         {
00078           result -= (black_lance - 2) * progress16.value() * PtypeEvalTraits<PAWN>::val / 24;
00079         }
00080         if (white_lance > 1)
00081         {
00082           result += (white_lance - 1) * progress16.value() * PtypeEvalTraits<LANCE>::val / 32;
00083         }
00084         if (white_lance > 2)
00085         {
00086           result += (white_lance - 2) * progress16.value() * PtypeEvalTraits<PAWN>::val / 24;
00087         }
00088         return result;
00089       }
00090       int knightBonus(Progress16 progress16) const
00091       {
00092         const int black_knight = knight_on_stand[BLACK];
00093         const int white_knight = knight_on_stand[WHITE];
00094         int result = 0;
00095         if (black_knight > 1)
00096         {
00097           result -= (black_knight - 1) * progress16.value() * PtypeEvalTraits<KNIGHT>::val / 32;
00098         }
00099         if (black_knight > 2)
00100         {
00101           result -= (black_knight - 2) * progress16.value() * PtypeEvalTraits<PAWN>::val / 8;
00102         }
00103         if (white_knight > 1)
00104         {
00105           result += (white_knight - 1) * progress16.value() * PtypeEvalTraits<KNIGHT>::val / 32;
00106         }
00107         if (white_knight > 2)
00108         {
00109           result += (white_knight - 2) * progress16.value() * PtypeEvalTraits<PAWN>::val / 8;
00110         }
00111         return result;
00112       }
00113       int goldBonus(Progress16 black, Progress16 white) const
00114       {
00115         const int black_gold = golds[BLACK];
00116         const int white_gold = golds[WHITE];
00117         if (black_gold >= 3)
00118         {
00119           return white.value() * PtypeEvalTraits<GOLD>::val
00120             * (black_gold - 2);
00121         }
00122         else if (white_gold >= 3)
00123         {
00124           return -black.value() * PtypeEvalTraits<GOLD>::val
00125             * (white_gold - 2);
00126         }
00127         
00128         return 0;
00129       }
00130 
00131     public:
00132       MinorPieceBonus(const SimpleState& state) 
00133       {
00134         pawn_on_stand[BLACK] = state.countPiecesOnStand(BLACK, PAWN);
00135         pawn_on_stand[WHITE] = state.countPiecesOnStand(WHITE, PAWN);
00136         lance_on_stand[BLACK] = state.countPiecesOnStand(BLACK, LANCE);
00137         lance_on_stand[WHITE] = state.countPiecesOnStand(WHITE, LANCE);
00138         knight_on_stand[BLACK] = state.countPiecesOnStand(BLACK, KNIGHT);
00139         knight_on_stand[WHITE] = state.countPiecesOnStand(WHITE, KNIGHT);
00140         pawns[BLACK] = 0;
00141         pawns[WHITE] = 0;
00142         golds[BLACK] = 0;
00143         golds[WHITE] = 0;
00144         for (int i = PtypeTraits<PAWN>::indexMin;
00145              i < PtypeTraits<PAWN>::indexLimit; i++)
00146         {
00147           const Piece pawn = state.pieceOf(i);
00148           if (pawn.owner() == BLACK)
00149             pawns[BLACK]++;
00150           else
00151             pawns[WHITE]++;
00152         }
00153 
00154         for (int i = PtypeTraits<GOLD>::indexMin;
00155              i < PtypeTraits<GOLD>::indexLimit; i++)
00156         {
00157           const Piece gold = state.pieceOf(i);
00158           golds[gold.owner()]++;
00159         }
00160       }
00161 
00162       int value(Progress16 progress16,
00163                 Progress16 black,
00164                 Progress16 white) const
00165       {
00166         return pawnBonus(progress16) + lanceBonus(progress16) +
00167           knightBonus(progress16) + goldBonus(black, white);
00168       }
00169 
00170       void update(const SimpleState& /*new_state*/, Move last_move)
00171       {
00172         const Player player = last_move.player();
00173         const Ptype ptype = last_move.ptype();
00174         if (last_move.isDrop()) {
00175           if (ptype == PAWN) {
00176             pawn_on_stand[player]--;
00177             assert(pawn_on_stand[BLACK] >= 0);
00178             assert(pawn_on_stand[WHITE] >= 0);
00179           }
00180           if (ptype == LANCE) {
00181             lance_on_stand[player]--;
00182           }
00183           if (ptype == KNIGHT) {
00184             knight_on_stand[player]--;
00185           }
00186           return;
00187         }
00188         const Ptype captured = last_move.capturePtype();
00189         if (captured != PTYPE_EMPTY) {
00190           switch (unpromote(captured)) {
00191           case PAWN:
00192             pawn_on_stand[player]++;
00193             pawns[player]++;
00194             pawns[alt(player)]--;
00195             assert(pawns[BLACK] + pawns[WHITE] == 18);
00196             assert(pawn_on_stand[BLACK] >= 0);
00197             assert(pawn_on_stand[WHITE] >= 0);
00198             break;
00199           case LANCE:
00200             lance_on_stand[player]++;
00201             break;
00202           case KNIGHT:
00203             knight_on_stand[player]++;
00204             break;
00205           case GOLD:
00206             golds[player]++;
00207             golds[alt(player)]--;
00208             assert(golds[BLACK] + golds[WHITE] == 4);
00209             break;
00210           default:
00211             ;
00212           }
00213         }
00214       }
00215 
00216       int expect(const SimpleState& state, Move move, Progress16 progress16,
00217                  Progress16 black,
00218                  Progress16 white) const
00219       {
00220         MinorPieceBonus new_eval = *this;
00221         if (move.isDrop()){
00222           const Ptype ptype = move.ptype();
00223           if (ptype == PAWN) {
00224             new_eval.pawn_on_stand[state.turn()]--;
00225             assert(new_eval.pawn_on_stand[BLACK] >= 0);
00226             assert(new_eval.pawn_on_stand[WHITE] >= 0);
00227           }
00228           else if (ptype == LANCE) {
00229             new_eval.lance_on_stand[state.turn()]--;
00230           }
00231           else if (ptype == KNIGHT) {
00232             new_eval.knight_on_stand[state.turn()]--;
00233           }
00234           return new_eval.value(progress16, black, white);
00235         }
00236         Ptype ptype = move.capturePtype();
00237         if (ptype != PTYPE_EMPTY) {
00238           if (unpromote(ptype) == PAWN) {
00239             new_eval.pawn_on_stand[state.turn()]++;
00240             new_eval.pawns[state.turn()]++;
00241             new_eval.pawns[alt(state.turn())]--;
00242             assert(new_eval.pawns[BLACK] + new_eval.pawns[WHITE] == 18);
00243             assert(new_eval.pawn_on_stand[BLACK] >= 0);
00244             assert(new_eval.pawn_on_stand[WHITE] >= 0);
00245           }
00246           else if (unpromote(ptype) == LANCE) {
00247             new_eval.lance_on_stand[state.turn()]++;
00248           }
00249           else if (unpromote(ptype) == KNIGHT) {
00250             new_eval.knight_on_stand[state.turn()]++;
00251           }
00252           else if (unpromote(ptype) == GOLD) {
00253             new_eval.golds[state.turn()]++;
00254             new_eval.golds[alt(state.turn())]--;
00255             assert(new_eval.golds[BLACK] + new_eval.golds[WHITE] == 4);
00256           }
00257         }
00258         return new_eval.value(progress16, black, white);
00259       }
00260 
00261       MinorPieceDebugInfo debugInfo(Progress16 progress16,
00262                                     Progress16 black, Progress16 white) const
00263       {
00264         MinorPieceDebugInfo debug_info;
00265         debug_info.pawn_bonus = pawnBonus(progress16);
00266         debug_info.lance_bonus = lanceBonus(progress16);
00267         debug_info.knight_bonus = knightBonus(progress16);
00268         debug_info.gold_bonus = goldBonus(black, white);
00269 
00270         return debug_info;
00271       }
00272     };
00273   } // namespace eval
00274 } // namespace osl
00275 
00276 #endif /* EVAL_MINORPIECEBONUS_H */
00277 // ;;; Local Variables:
00278 // ;;; mode:c++
00279 // ;;; c-basic-offset:2
00280 // ;;; coding:utf-8
00281 // ;;; End:
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines