00001
00002
00003 #include "osl/effect_util/effectUtil.h"
00004 #include "osl/effect_util/effectUtil.tcc"
00005 #include "osl/eval/pieceEval.h"
00006 #include "osl/state/numEffectState.h"
00007
00008 namespace osl
00009 {
00010 template Piece
00011 EffectUtil::cheapestPiece(Player, const NumEffectState&, Position);
00012 template Piece
00013 EffectUtil::promotablePiece(Player, const NumEffectState&, Position);
00014 template void
00015 EffectUtil::showEffect(const NumEffectState&, Position, std::ostream&);
00016 template Piece
00017 EffectUtil::safeCaptureNotByKing(Player, const NumEffectState&, Position);
00018 template void
00019 EffectUtil::findEffect(Player, const NumEffectState&, Position, PieceVector&);
00020 template bool
00021 EffectUtil::isOpenAttackMove<BLACK>(const SimpleState&, Position, Position, Position);
00022 template bool
00023 EffectUtil::isOpenAttackMove<WHITE>(const SimpleState&, Position, Position, Position);
00024 template bool
00025 EffectUtil::isAddEffectMove<BLACK>(const SimpleState&, Position, Move);
00026 template bool
00027 EffectUtil::isAddEffectMove<WHITE>(const SimpleState&, Position, Move);
00028 #ifdef NEED_EXTRA_TEMPLATE_INSTANTIATION
00029 template Piece
00030 EffectUtil::safeCaptureNotByKing<BLACK, NumEffectState>(NumEffectState const&, Position, Piece);
00031 template Piece
00032 EffectUtil::safeCaptureNotByKing<WHITE, NumEffectState>(NumEffectState const&, Position, Piece);
00033 #endif
00034 }
00035
00036 struct osl::effect_util::EffectUtil::SelectMostValuable
00037 {
00038 const SimpleState& state;
00039 Player target;
00040 Position move_from;
00041 Piece result;
00042 int result_value;
00043 SelectMostValuable(const SimpleState& s, Player t, Position f)
00044 : state(s), target(t), move_from(f),
00045 result(Piece::EMPTY()), result_value(0)
00046 {
00047 }
00048 void operator()(Position pos)
00049 {
00050 if (pos == move_from)
00051 return;
00052 const Piece cur = state.getPieceOnBoard(pos);
00053 assert(cur.isPiece());
00054 if (cur.owner() == target)
00055 {
00056 const Ptype ptype = cur.ptype();
00057 const int curValue
00058 = eval::Ptype_Eval_Table.captureValue(newPtypeO(WHITE,ptype));
00059 assert(curValue > 0);
00060 if ((ptype != KING) && (curValue > result_value))
00061 {
00062 result = cur;
00063 result_value = curValue;
00064 }
00065 }
00066 }
00067 };
00068
00069 osl::Piece osl::EffectUtil::
00070 mostValuableEffectOfMoveNotKing(Player target, const SimpleState& state, Move m)
00071 {
00072 SelectMostValuable selector(state, target, m.from());
00073 forEachEffectPieceOfMove(state, m, selector);
00074 return selector.result;
00075 }
00076
00077 template <int N>
00078 struct osl::effect_util::EffectUtil::SelectMostValuableN
00079 {
00080 const SimpleState& state;
00081 Player target;
00082 Position move_from;
00083 CArray<Piece,N>& result;
00084 CArray<int,N> result_value;
00085 SelectMostValuableN(const SimpleState& s, Player t, Position f,
00086 CArray<Piece,N>& out)
00087 : state(s), target(t), move_from(f), result(out)
00088 {
00089 result.fill(Piece::EMPTY());
00090 result_value.fill(0);
00091 }
00092 void operator()(Position pos)
00093 {
00094 if (pos == move_from)
00095 return;
00096 const Piece cur = state.getPieceOnBoard(pos);
00097 assert(cur.isPiece());
00098 if (cur.owner() == target)
00099 {
00100 const Ptype ptype = cur.ptype();
00101 const int curValue
00102 = eval::Ptype_Eval_Table.captureValue(newPtypeO(WHITE,ptype));
00103 assert(curValue > 0);
00104 if (ptype == KING)
00105 return;
00106 for (int i=0; i<N; ++i)
00107 {
00108 if (curValue > result_value[i])
00109 {
00110 for (int j=i; j+1<N; ++j)
00111 {
00112 result[j+1] = result[j];
00113 result_value[j+1] = result_value[j];
00114 }
00115 result[i] = cur;
00116 result_value[i] = curValue;
00117 return;
00118 }
00119 }
00120 }
00121 }
00122 };
00123
00124 void osl::EffectUtil::
00125 mostValuableEffectOfMoveNotKing(Player target, const SimpleState& state,
00126 Move m, CArray<Piece,2>& out)
00127 {
00128 SelectMostValuableN<2> selector(state, target, m.from(), out);
00129 forEachEffectPieceOfMove(state, m, selector);
00130 }
00131
00132 struct osl::effect_util::EffectUtil::FindThreat
00133 {
00134 const NumEffectState& state;
00135 Player target;
00136 int attacker_value;
00137 PieceVector& supported, & unsupported;
00138 FindThreat(const NumEffectState& st, Player t, int a,
00139 PieceVector& s, PieceVector& u)
00140 : state(st), target(t), attacker_value(a), supported(s), unsupported(u)
00141 {
00142 }
00143 void operator()(Position pos)
00144 {
00145 const Piece cur = state.getPieceOnBoard(pos);
00146 assert(cur.isPiece());
00147 if (cur.owner() != target)
00148 return;
00149 if (state.hasEffectBy(target, pos))
00150 {
00151 if (abs(eval::PieceEval::captureValue(cur.ptypeO()))
00152 > attacker_value)
00153 supported.push_back(cur);
00154 }
00155 else
00156 {
00157 unsupported.push_back(cur);
00158 }
00159 }
00160 };
00161
00162 void osl::EffectUtil::
00163 findThreat(const NumEffectState& state, Position position,
00164 PtypeO ptypeo, PieceVector& out)
00165 {
00166 PieceVector supported, unsupported;
00167 const int attacker_value = abs(eval::PieceEval::captureValue(ptypeo));
00168 FindThreat f(state, alt(getOwner(ptypeo)), attacker_value,
00169 supported, unsupported);
00170 forEachEffectOfPtypeO<NumEffectState, FindThreat, false>
00171 (state, position, ptypeo, f);
00172
00173 unsupported.sortByPtype();
00174 supported.sortByPtype();
00175 PieceVector::iterator u=unsupported.begin(), s=supported.begin();
00176
00177 if (u!=unsupported.end())
00178 {
00179 while ((s!=supported.end())
00180 && ((abs(eval::PieceEval::captureValue(s->ptypeO()))
00181 - attacker_value)
00182 > abs(eval::PieceEval::captureValue(u->ptypeO()))))
00183 {
00184 out.push_back(*s);
00185 ++s;
00186 }
00187 }
00188 out.push_back(u, unsupported.end());
00189 out.push_back(s, supported.end());
00190 }
00191
00192 osl::Ptype osl::EffectUtil::
00193 cheapestPtype(Player P, const NumEffectState& state, Position effect_target)
00194 {
00195 PieceMask pieces = state.getEffect(effect_target);
00196 pieces &= state.getOnBoardMask(P);
00197 Ptype result = PTYPE_EMPTY;
00198
00199 if (pieces.none())
00200 return result;
00201 if ((pieces.getMask(PtypeFuns<PAWN>::indexNum) & mask_t::makeDirect(PtypeFuns<PAWN>::indexMask)).any()) {
00202 Position d = Board_Table.nextPosition(P, effect_target, D);
00203 if (state.getPieceAt(d).ptype() == PAWN)
00204 return PAWN;
00205 return PPAWN;
00206 }
00207 #ifndef CHEAPEST_PTYPE_STRICT
00208 mask_t m = pieces.getMask(PtypeFuns<LANCE>::indexNum) & mask_t::makeDirect(PtypeFuns<LANCE>::indexMask);
00209 if (m.any()) {
00210 int num=m.takeOneBit()+(PtypeFuns<LANCE>::indexNum<<5);
00211 return state.getPieceOf(num).ptype();
00212 }
00213 m = pieces.getMask(0);
00214 # if OSL_WORDSIZE == 64
00215 return state.getPieceOf(m.takeOneBit()).ptype();
00216 # else
00217 if (m.any())
00218 return state.getPieceOf(m.takeOneBit()).ptype();
00219 m = pieces.getMask(1);
00220 return state.getPieceOf(m.takeOneBit()+32).ptype();
00221 # endif
00222 #else
00223 mask_t m = pieces.getMask(PtypeFuns<LANCE>::indexNum) & mask_t::makeDirect(PtypeFuns<LANCE>::indexMask);
00224 while (m.any()) {
00225 int num=m.takeOneBit()+(PtypeFuns<LANCE>::indexNum<<5);
00226 if (state.getPieceOf(num).ptype() == LANCE)
00227 return LANCE;
00228 result = PLANCE;
00229 }
00230 m = pieces.getMask(PtypeFuns<KNIGHT>::indexNum) & mask_t::makeDirect(PtypeFuns<KNIGHT>::indexMask);
00231 while (m.any()) {
00232 int num=m.takeOneBit()+(PtypeFuns<KNIGHT>::indexNum<<5);
00233 if (state.getPieceOf(num).ptype() == KNIGHT)
00234 return KNIGHT;
00235 if (result == PTYPE_EMPTY)
00236 result = PKNIGHT;
00237 }
00238 m = pieces.getMask(PtypeFuns<SILVER>::indexNum) & mask_t::makeDirect(PtypeFuns<SILVER>::indexMask);
00239 while (m.any()) {
00240 int num=m.takeOneBit()+(PtypeFuns<SILVER>::indexNum<<5);
00241 if (state.getPieceOf(num).ptype() == SILVER)
00242 return SILVER;
00243 if (result == PTYPE_EMPTY)
00244 result = PSILVER;
00245 }
00246 if (result != PTYPE_EMPTY)
00247 return result;
00248 if ((pieces.getMask(PtypeFuns<GOLD>::indexNum) & mask_t::makeDirect(PtypeFuns<GOLD>::indexMask)).any())
00249 return GOLD;
00250
00251 m = pieces.getMask(PtypeFuns<BISHOP>::indexNum) & mask_t::makeDirect(PtypeFuns<BISHOP>::indexMask);
00252 while (m.any()) {
00253 int num=m.takeOneBit()+(PtypeFuns<BISHOP>::indexNum<<5);
00254 if (state.getPieceOf(num).ptype() == BISHOP)
00255 return BISHOP;
00256 result = PBISHOP;
00257 }
00258 m = pieces.getMask(PtypeFuns<ROOK>::indexNum) & mask_t::makeDirect(PtypeFuns<ROOK>::indexMask);
00259 while (m.any()) {
00260 int num=m.takeOneBit()+(PtypeFuns<ROOK>::indexNum<<5);
00261 if (state.getPieceOf(num).ptype() == ROOK)
00262 return ROOK;
00263 if (result == PTYPE_EMPTY)
00264 result = PROOK;
00265 }
00266 return result;
00267 #endif
00268 }
00269
00270
00271
00272
00273