00001
00002
00003 #include "osl/category/capture.h"
00004 #include "osl/category/probTableDefine.h"
00005 #include "osl/move_generator/capture_.h"
00006 #include "osl/move_generator/additionalLance.h"
00007 #include "osl/move_action/store.h"
00008 #include "osl/state/simpleState.tcc"
00009 #include <string>
00010
00011 namespace osl
00012 {
00013 namespace category
00014 {
00015 DEF_CATEGORY_TABLE_IP(PieceValueTable, ContinueCapture);
00016 template <osl::Ptype PTYPE>
00017 DEF_CATEGORY_TABLE_IP(PieceValueTable, Capture<PTYPE>);
00018 DEF_CATEGORY_TABLE(FixedValueTable, TrapRook);
00019 }
00020 }
00021
00022
00023 template <osl::Ptype PTYPE>
00024 void osl::category::Capture<PTYPE>::
00025 generate(const CategoryEnv& env, MoveVector& out)
00026 {
00027 const Player turn = env.state->getTurn();
00028 move_action::Store a(out);
00029 for (int i=PtypeTraits<PTYPE>::indexMin;
00030 i < PtypeTraits<PTYPE>::indexLimit; i++)
00031 {
00032 const Piece target = env.state->getPieceOf(i);
00033 if (target.owner() == alt(env.state->getTurn()))
00034 {
00035 move_generator::GenerateCapture::generate
00036 (turn, *env.state, target.position(), a);
00037 }
00038 }
00039
00040 if (env.state->hasPieceOnStand(turn,LANCE))
00041 {
00042
00043
00044
00045
00046 MoveVector::const_iterator original_end = out.end();
00047 for (MoveVector::const_iterator p=out.begin(); p!=original_end; ++p)
00048 {
00049 const Position from = p->from();
00050 if ((p->oldPtype() == PAWN)
00051 && (env.state->hasEffectBy(alt(turn), p->to())))
00052 {
00053 if (turn == BLACK)
00054 move_generator::AdditionalLance<BLACK>::generate(*env.state, from, out);
00055 else
00056 move_generator::AdditionalLance<WHITE>::generate(*env.state, from, out);
00057 }
00058 }
00059 }
00060 }
00061
00062 template <osl::Ptype PTYPE>
00063 const char * osl::category::Capture<PTYPE>::getName()
00064 {
00065 static std::string name = std::string("Capture-")
00066 + PtypeTraits<PTYPE>::name();
00067 return name.c_str();
00068 }
00069
00070 template struct osl::category::Capture<osl::ROOK>;
00071 template struct osl::category::Capture<osl::BISHOP>;
00072 template struct osl::category::Capture<osl::GOLD>;
00073 template struct osl::category::Capture<osl::SILVER>;
00074 template struct osl::category::Capture<osl::KNIGHT>;
00075 template struct osl::category::Capture<osl::LANCE>;
00076 template struct osl::category::Capture<osl::PAWN>;
00077
00078
00079 struct osl::category::ContinueCapture::PositionAction
00080 {
00081 const CategoryEnv::effect_state_t *state;
00082 Position attackFrom;
00083 Ptype attackerPtype;
00084 MoveVector *out;
00085 PositionAction(const CategoryEnv::effect_state_t *s,
00086 Position from, Ptype ptype,
00087 MoveVector *o)
00088 : state(s), attackFrom(from), attackerPtype(ptype), out(o)
00089 {
00090 }
00091 template<Player P>
00092 void
00093 #ifdef __GNUC__
00094 __attribute__ ((noinline))
00095 #endif
00096 doAction(Piece, Position pos)
00097 {
00098 const Piece target = state->getPieceAt(pos);
00099 if (target.isPiece() && (target.owner() == alt(state->getTurn())))
00100 {
00101 assert(target.position()==pos);
00102 if (isBasic(attackerPtype) && canPromote(attackerPtype)
00103 && (pos.canPromote(state->getTurn())
00104 || attackFrom.canPromote(state->getTurn())))
00105 {
00106
00107 const Move m1(attackFrom, pos, promote(attackerPtype),
00108 target.ptype(), true, state->getTurn());
00109 out->push_back(m1);
00110 }
00111 if ((! isBasic(attackerPtype))
00112 || Ptype_Table.canDropTo(state->getTurn(), attackerPtype, pos))
00113 {
00114
00115 const Move m2(attackFrom, pos, attackerPtype,
00116 target.ptype(), false, state->getTurn());
00117 out->push_back(m2);
00118 }
00119 }
00120 }
00121 };
00122 void osl::category::
00123 ContinueCapture::generate(const CategoryEnv& env, MoveVector& out)
00124 {
00125 if (! isEffective(env))
00126 return;
00127 const Move lastLastMove=env.history->lastMove(2);
00128 const Position attackFrom = lastLastMove.to();
00129 const Piece attacker = env.state->getPieceOnBoard(attackFrom);
00130 assert(attacker.isPiece());
00131 if (attacker.owner() != env.state->getTurn())
00132 return;
00133
00134 PositionAction a(env.state, attackFrom, attacker.ptype(), &out);
00135 env.state->forEachEffectOfPiece(attacker,a);
00136 }
00137
00138
00139
00140
00141
00142