escapeFilter.h
Go to the documentation of this file.
00001 /* escapeFilter.h
00002  */
00003 #ifndef OSL_ESCAPE_FILTER_H
00004 #define OSL_ESCAPE_FILTER_H
00005 
00006 #include "osl/player.h"
00007 #include "osl/move_action/concept.h"
00008 #include "osl/eval/pieceEval.h"
00009 
00010 namespace osl
00011 {
00012   namespace move_action
00013   {
00017     template<Player P,class OrigAction>
00018     class EscapeFilter
00019     {
00020       BOOST_CLASS_REQUIRE(OrigAction,osl::move_action,Concept);
00021       const NumEffectState& state;
00022       OrigAction & action;
00023       PieceMask attack_pin, defense_pin;
00024       Piece removed;
00025       Ptype attacking;
00026       int value, my_value;
00027       bool has_long, has_long_support;
00028 
00029       Piece findThreat(Square to) const
00030       {
00031         Piece attack = state.findCheapAttackNotBy(alt(P), to, state.pinOrOpen(alt(P))); // == pin
00032         if (! attack.isEmpty())
00033           return attack;
00034         if (! has_long)
00035           return Piece::EMPTY();
00036         const Direction d = Board_Table.getLongDirection<BLACK>(Offset32(to, removed.square()));
00037         if (!isLong(d))
00038           return Piece::EMPTY();
00039         const int num=state.longEffectNumTable()[removed.number()][longToShort(d)];
00040         if (Piece::isEmptyNum(num))
00041           return Piece::EMPTY();
00042         attack = state.pieceOf(num);
00043         if (attack.owner()==alt(P))
00044           return attack;
00045         return Piece::EMPTY();
00046       }
00047       template <bool IsSimple>
00048       bool suitable(Square to) const
00049       {
00050         const Piece attack = findThreat(to);
00051         if (attack.isEmpty())
00052           return true;
00053         if (! IsSimple)
00054         {
00055           const Ptype capture = state.pieceAt(to).ptype();
00056           if (capture != PTYPE_EMPTY)
00057             if (eval::Ptype_Eval_Table.captureValue(newPtypeO(WHITE, capture)) >= my_value)
00058               return true;
00059         }
00060         if (eval::Ptype_Eval_Table.captureValue(newPtypeO(WHITE, attack.ptype())) <= value)
00061           return false;
00062         const int attack_count = state.countEffect(alt(P), to, attack_pin); // rough estimation
00063         const int defense_count = state.countEffect(P, to, defense_pin);
00064         if (defense_count > attack_count)
00065           return true;
00066         if (defense_count < attack_count)
00067           return false;
00068         if (! has_long_support)
00069           return false;
00070         const Direction d = Board_Table.getLongDirection<BLACK>(Offset32(to, removed.square()));
00071         if (!isLong(d))
00072           return false;
00073         const int num=state.longEffectNumTable()[removed.number()][longToShort(d)];
00074         return ! Piece::isEmptyNum(num)
00075           && state.pieceOf(num).owner() == P;
00076       }
00077     public:
00078       EscapeFilter(const NumEffectState& s, OrigAction & action,Square pos, Ptype ptype)
00079         : state(s), action(action),
00080           attack_pin(state.pin(alt(P))), defense_pin(state.pin(P)),
00081           removed(state.pieceAt(pos)), 
00082           has_long(state.longEffectAt(pos, alt(P)).any()),
00083           has_long_support(state.longEffectAt(pos, P).any())
00084       {
00085         assert(removed.isPiece());
00086         assert(removed.owner() == P);
00087 
00088         if (ptype == PTYPE_EMPTY)
00089           ptype = state.findCheapAttackNotBy(alt(P), pos, state.pinOrOpen(alt(P))).ptype();
00090         attacking = ptype;
00091         value = eval::Ptype_Eval_Table.captureValue(newPtypeO(WHITE, ptype));
00092         my_value = eval::Ptype_Eval_Table.captureValue(newPtypeO(WHITE, removed.ptype()))
00093           - eval::Ptype_Eval_Table.value(PAWN);
00094       }
00095       void simpleMove(Square from,Square to,Ptype ptype, bool isPromote,Player /* p */,Move m){
00096         if (suitable<true>(to))
00097           action.simpleMove(from,to,ptype,isPromote,P,m);
00098       }
00099       void unknownMove(Square from,Square to,Piece p1,Ptype ptype,bool isPromote,Player /* p */,Move m){
00100         if (suitable<false>(to))
00101           action.unknownMove(from,to,p1,ptype,isPromote,P,m);
00102       }
00103       void dropMove(Square to,Ptype ptype,Player /* p */,Move){
00104         assert(0);
00105       }
00106     
00107     };
00108       // old interfaces
00109       void simpleMove(Square from,Square to,Ptype ptype, 
00110                       bool isPromote,Player p)
00111       {
00112         simpleMove(from,to,ptype,isPromote,p,
00113                    Move(from,to,ptype,PTYPE_EMPTY,isPromote,p));
00114       }
00115       void unknownMove(Square from,Square to,Piece captured,
00116                        Ptype ptype,bool isPromote,Player p)
00117       {
00118         unknownMove(from,to,captured,ptype,isPromote,p,
00119                     Move(from,to,ptype,captured.ptype(),isPromote,p));
00120       }
00121       void dropMove(Square to,Ptype ptype,Player p)
00122       {
00123         dropMove(to,ptype,p,
00124                  Move(to,ptype,p));
00125       }
00126   } // namespace move_action
00127 } // namespace osl
00128 
00129 
00130 #endif /* _NO_EFFECT_FILTER_H */
00131 // ;;; Local Variables:
00132 // ;;; mode:c++
00133 // ;;; c-basic-offset:2
00134 // ;;; coding:utf-8
00135 // ;;; End:
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines