00001
00002
00003 #include "osl/category/breakThreatmate.h"
00004 #include "osl/container/moveLogProbVector.h"
00005 #include "osl/move_generator/addEffect_.h"
00006 #include "osl/move_generator/capture_.h"
00007 #include "osl/move_generator/pieceOnBoard.h"
00008 #include "osl/move_action/store.h"
00009 #include "osl/boardTable.h"
00010 #include "osl/ptypeTable.h"
00011
00012 void osl::category::
00013 BreakThreatmate::generateBreakDrop(int limit,
00014 const NumEffectState& state, Position to,
00015 int default_prob,
00016 MoveLogProbVector& out)
00017 {
00018 const Player Turn = state.getTurn();
00019 default_prob = std::max(default_prob, 150);
00020 if (state.hasPieceOnStand(Turn, PAWN))
00021 {
00022 if (! state.isPawnMaskSet(Turn, to.x())
00023 && Ptype_Table.canDropTo(Turn, PAWN, to)
00024 && limit >= default_prob-100)
00025 out.push_back(MoveLogProb(Move(to, PAWN, Turn), default_prob-100));
00026 }
00027 if (state.hasPieceOnStand(Turn, LANCE)
00028 && Ptype_Table.canDropTo(Turn, LANCE, to)
00029 && limit >= default_prob-50)
00030 out.push_back(MoveLogProb(Move(to, LANCE, Turn), default_prob-50));
00031 if (default_prob > limit)
00032 return;
00033
00034 if (state.hasPieceOnStand(Turn, KNIGHT)
00035 && Ptype_Table.canDropTo(Turn, KNIGHT, to))
00036 out.push_back(MoveLogProb(Move(to, KNIGHT, Turn), default_prob));
00037 if (state.hasPieceOnStand(Turn, SILVER))
00038 out.push_back(MoveLogProb(Move(to, SILVER, Turn), default_prob));
00039 if (state.hasPieceOnStand(Turn, GOLD))
00040 out.push_back(MoveLogProb(Move(to, GOLD, Turn), default_prob));
00041 if (state.hasPieceOnStand(Turn, BISHOP))
00042 out.push_back(MoveLogProb(Move(to, BISHOP, Turn), default_prob));
00043 if (state.hasPieceOnStand(Turn, ROOK))
00044 out.push_back(MoveLogProb(Move(to, ROOK, Turn), default_prob));
00045 }
00046
00047
00048 void osl::category::BreakThreatmate::
00049 generateBreak(int limit, const NumEffectState& state, Move threatmate_move,
00050 MoveLogProbVector& out)
00051 {
00052 assert(threatmate_move.isNormal());
00053 const Player Turn = state.getTurn();
00054
00055 MoveVector all_moves;
00056 move_action::Store store(all_moves);
00057 assert(threatmate_move.isNormal());
00058 const Position target = threatmate_move.to();
00059
00060 move_generator::GenerateAddEffect<false>::generate<NumEffectState>
00061 (Turn, state, target, store);
00062 for (MoveVector::const_iterator p=all_moves.begin(); p!=all_moves.end(); ++p)
00063 {
00064 const Ptype ptype = p->ptype();
00065 if (ptype == KING)
00066 continue;
00067 if (! p->isDrop())
00068 {
00069 if (isMajor(ptype)
00070 && state.hasEffectByPiece(state.getPieceOnBoard(p->from()), target))
00071 continue;
00072 }
00073 const Position to = p->to();
00074 const int me = state.countEffect(Turn, to) + (p->isDrop() ? 1 : 0);
00075 const int op = state.countEffect(alt(Turn), to);
00076 int prob = (p->isDrop() ? 100 : 100);
00077 if (p->capturePtype() != PTYPE_EMPTY)
00078 {
00079 prob -= 50;
00080 }
00081 else
00082 {
00083 if (isMajor(ptype)
00084 || ((ptype == GOLD || ptype == SILVER)
00085 && (to.x() == 1 || to.x() == 9)))
00086 {
00087 prob += 50;
00088 }
00089 if (! ((me >= 2) || (op == 0)))
00090 {
00091 prob += 300;
00092 }
00093 }
00094 if (prob <= limit)
00095 out.push_back(MoveLogProb(*p, prob));
00096 }
00097 if (threatmate_move.isDrop())
00098 {
00099 const int drop_prob = (state.hasEffectBy(alt(Turn), target) ? 400 : 100);
00100 generateBreakDrop(limit, state, target, drop_prob, out);
00101 }
00102 else
00103 {
00104
00105 const Position from = threatmate_move.from();
00106 const Offset offset
00107 = Board_Table.getShortOffsetNotKnight(Offset32(target, from));
00108 if (! offset.zero())
00109 {
00110 for (Position to = from + offset; to != target; to += offset)
00111 {
00112 assert(to.isOnBoard());
00113 assert(state.getPieceOnBoard(to) == Piece::EMPTY());
00114 const int drop_prob = (state.hasEffectBy(Turn, to) ? 100 : 400);
00115 generateBreakDrop(limit, state, to, drop_prob, out);
00116
00117 const int move_prob = (state.hasMultipleEffectBy(Turn, to) ? 100 : 400);
00118 if (move_prob > limit)
00119 continue;
00120 all_moves.clear();
00121 move_generator::GenerateCapture::generate
00122 (Turn, state, to, store);
00123 for (MoveVector::const_iterator p=all_moves.begin(); p!=all_moves.end();
00124 ++p)
00125 {
00126 out.push_back(MoveLogProb(*p, move_prob));
00127 }
00128 }
00129 }
00130 }
00131
00132
00133 const Piece my_king = state.getKingPiece(Turn);
00134 const int king_prob = 100;
00135 if (king_prob <= limit)
00136 {
00137 all_moves.clear();
00138 GeneratePieceOnBoard::generate(Turn, state, my_king, all_moves);
00139 for (MoveVector::const_iterator p=all_moves.begin(); p!=all_moves.end(); ++p)
00140 {
00141 if (state.hasEffectBy(alt(Turn), p->to()))
00142 continue;
00143 out.push_back(MoveLogProb(*p, king_prob));
00144 }
00145 }
00146
00147
00148 const Position center = my_king.position();
00149 generateOpenRoad(limit, state, center + DirectionTraits<U>::blackOffset(), out);
00150 generateOpenRoad(limit, state, center + DirectionTraits<UL>::blackOffset(), out);
00151 generateOpenRoad(limit, state, center + DirectionTraits<UR>::blackOffset(), out);
00152 generateOpenRoad(limit, state, center + DirectionTraits<L>::blackOffset(), out);
00153 generateOpenRoad(limit, state, center + DirectionTraits<R>::blackOffset(), out);
00154 generateOpenRoad(limit, state, center + DirectionTraits<D>::blackOffset(), out);
00155 generateOpenRoad(limit, state, center + DirectionTraits<DL>::blackOffset(), out);
00156 generateOpenRoad(limit, state, center + DirectionTraits<DR>::blackOffset(), out);
00157 }
00158
00159 void osl::category::BreakThreatmate::
00160 generateOpenRoad(int limit, const NumEffectState& state,
00161 Position from, MoveLogProbVector& out)
00162 {
00163 const Piece target = state.getPieceAt(from);
00164 if (! target.isPiece())
00165 return;
00166 const Player Turn = state.getTurn();
00167 if (target.owner() != Turn)
00168 return;
00169
00170 const int capture_prob = 50;
00171 const int default_prob = 100;
00172 const int sacrifice_prob = 400;
00173 if (limit < capture_prob)
00174 return;
00175
00176 MoveVector moves;
00177 GeneratePieceOnBoard::generate(Turn, state, target, moves);
00178
00179 for (MoveVector::const_iterator p=moves.begin(); p!=moves.end(); ++p)
00180 {
00181 const bool capture = (p->capturePtype() != PTYPE_EMPTY);
00182 const bool sacrifice = state.hasEffectBy(alt(Turn), p->to());
00183 const int prob = capture ? capture_prob
00184 : (sacrifice ? sacrifice_prob : default_prob);
00185 if (prob <= limit)
00186 out.push_back(MoveLogProb(*p, prob));
00187 }
00188 }
00189
00190
00191
00192
00193
00194