説明を見る。00001
00002
00003 #include "osl/move_probability/moveInfo.h"
00004 #include "osl/move_probability/stateInfo.h"
00005 #include "osl/move_classifier/moveAdaptor.h"
00006 #include "osl/move_classifier/check_.h"
00007 #include "osl/eval/see.h"
00008 #include "osl/eval/minorPiece.h"
00009 using namespace osl::move_classifier;
00010
00011 osl::move_probability::
00012 MoveInfo::MoveInfo(const StateInfo& info, Move m)
00013 : move(m),
00014 see(See::see(*info.state, move, info.pin[info.state->turn()],
00015 info.pin[alt(info.state->turn())])),
00016 plain_see(see),
00017 check(PlayerMoveAdaptor<Check>::isMember(*info.state, move)),
00018 open_check(ConditionAdaptor<OpenCheck>::isMember(*info.state, move)),
00019 player(m.player()), stand_index_cache(-1)
00020 {
00021
00022 if (adhocAdjustBishopFork(info))
00023 see = 0;
00024 else if (adhocAdjustSlider(info))
00025 see = plain_see / 8;
00026 else if (adhocAdjustBreakThreatmate(info))
00027 see = 0;
00028 else if (adhocAdjustAttackCheckmateDefender(info))
00029 see = 0;
00030 else if (adhocAdjustKeepCheckmateDefender(info))
00031 see = 0;
00032 }
00033
00034 bool osl::move_probability::
00035 MoveInfo::adhocAdjustSlider(const StateInfo& info) const
00036 {
00037 if (plain_see >= 0)
00038 return false;
00039 const Piece attack = info.state->findCheapAttack(alt(player), move.to());
00040 return info.pinByOpposingSliders(attack)
00041 && (move.isDrop()
00042 || ! info.state->hasEffectByPiece(info.state->pieceAt(move.from()),
00043 attack.square()));
00044 }
00045
00046 bool osl::move_probability::
00047 MoveInfo::adhocAdjustBishopFork(const StateInfo& info) const
00048 {
00049 if (plain_see >= 0
00050 || !info.state->hasPieceOnStand<BISHOP>(info.state->turn()))
00051 return false;
00052
00053 const Piece attack
00054 = info.state->findCheapAttack(alt(player), move.to());
00055 if (unpromote(attack.ptype()) == ROOK) {
00056 const Player defense = alt(info.state->turn());
00057 const Square king = info.state->kingSquare(defense);
00058 const Square center
00059 = eval::ml::BishopRookFork::isBishopForkSquare(*info.state, defense, king, move.to(), true);
00060 return ! center.isPieceStand();
00061 }
00062 return false;
00063 }
00064
00065 bool osl::move_probability::
00066 MoveInfo::adhocAdjustBreakThreatmate(const StateInfo& info) const
00067 {
00068 if (! info.threatmate_move.isNormal())
00069 return false;
00070
00071 const Piece attack
00072 = info.state->findCheapAttack(alt(player), move.to());
00073 if (attack.isPiece()
00074 && info.state->hasEffectByPiece(attack, info.threatmate_move.to()))
00075 return ! info.state->hasEffectIf(attack.ptypeO(), move.to(),
00076 info.threatmate_move.to());
00077 return false;
00078 }
00079
00080 bool osl::move_probability::
00081 MoveInfo::adhocAdjustAttackCheckmateDefender(const StateInfo& info) const
00082 {
00083 if (plain_see >= 0)
00084 return false;
00085 const Piece defender = info.checkmate_defender[alt(player)].first;
00086 if (defender.isPiece()
00087 && info.state->countEffect(alt(player), move.to()) == 1
00088 && info.state->hasEffectByPiece(defender, move.to()))
00089 return true;
00090 return false;
00091 }
00092
00093 bool osl::move_probability::
00094 MoveInfo::adhocAdjustKeepCheckmateDefender(const StateInfo& info) const
00095 {
00096 if (plain_see <= 0)
00097 return false;
00098 const Piece defender = info.checkmate_defender[player].first;
00099 const Square threat_at = info.checkmate_defender[player].second;
00100 if (defender.isPiece() && move.from() == defender.square()
00101 && ! info.state->hasEffectIf(move.ptypeO(), move.to(), threat_at))
00102 return true;
00103 return false;
00104 }
00105
00106
00107
00108
00109