00001
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)));
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);
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 ,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 ,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 ,Move){
00104 assert(0);
00105 }
00106
00107 };
00108
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 }
00127 }
00128
00129
00130 #endif
00131
00132
00133
00134
00135