00001
00002
00003 #include "osl/brinkmate/brinkmateState.h"
00004
00005 osl::brinkmate::
00006 BrinkmateState::BrinkmateState()
00007 : m_state(SimpleState(HIRATE)), checkmator(0)
00008 {
00009 defense_check.push(0);
00010 }
00011
00012 osl::brinkmate::
00013 BrinkmateState::~BrinkmateState()
00014 {
00015 }
00016
00017 void osl::brinkmate::
00018 BrinkmateState::init(const HashEffectState& s)
00019 {
00020 m_state = s;
00021 path = PathEncoding(s.getTurn());
00022 }
00023
00024 void osl::brinkmate::
00025 BrinkmateState::init(checkmate_t& c)
00026 {
00027 checkmator = &c;
00028 }
00029
00030 void osl::brinkmate::
00031 BrinkmateState::push(Move todo, bool is_defense_check)
00032 {
00033 move_stack.push(m_state, todo);
00034 moves.push(todo);
00035 path.pushMove(todo);
00036 defense_check.push(defense_check.top()+is_defense_check);
00037 }
00038
00039 void osl::brinkmate::
00040 BrinkmateState::pop()
00041 {
00042 const Move last_move = moves.lastMove();
00043 move_stack.pop();
00044 moves.pop();
00045 path.popMove(last_move);
00046 defense_check.pop();
00047 }
00048
00049 bool osl::brinkmate::
00050 BrinkmateState::isEffectiveDefense(Move move)
00051 {
00052 using namespace checkmate;
00053 const Player attacker = alt(move.player());
00054 const checkmate_t::table_t& table = checkmator->getTable(attacker);
00055 const CheckHashRecord *record
00056 = table.find(m_state.getHash().newHashWithMove(Move::PASS(alt(attacker))));
00057
00058 push(move, false);
00059 bool checkmate = false;
00060
00061 checkmate = isWinningState(0);
00062
00063
00064 if ((! checkmate) && (move.ptype() != KING)
00065 && record && record->proofDisproof().isCheckmateSuccess())
00066 {
00067 if (attacker == BLACK)
00068 {
00069 Move best_move;
00070 checkmate::ProofOracleAttack<BLACK> oracle(record);
00071 OracleProverLight<BLACK> prover;
00072 checkmate = prover.proofWin(m_state, oracle, best_move);
00073 }
00074 else
00075 {
00076 Move best_move;
00077 ProofOracleAttack<WHITE> oracle(record);
00078 OracleProverLight<WHITE> prover;
00079 checkmate = prover.proofWin(m_state, oracle, best_move);
00080 }
00081 }
00082
00083
00084 if (! checkmate)
00085 {
00086 checkmate = isWinningState(1);
00087 }
00088 pop();
00089
00090 return ! checkmate;
00091 }
00092
00093 const osl::checkmate::ProofDisproof osl::brinkmate::
00094 BrinkmateState::testThreatmateState(int node)
00095 {
00096 if ((depth() / 2) == 0)
00097 node *= 20;
00098 else if ((depth() / 2) == 1)
00099 node *= 2;
00100
00101 m_state.changeTurn();
00102
00103 const HashKey& threatmate_hash = m_state.getHash();
00104 const PathEncoding threatmate_path(m_state.getTurn());
00105
00106 AttackOracleAges age;
00107 Move threatmate_move;
00108 const bool threatmate0
00109 = checkmator->isWinningState(0, m_state, threatmate_hash,
00110 threatmate_path, threatmate_move, age);
00111 const bool threatmate
00112 = (threatmate0
00113 || (checkmator->isWinningState(node, m_state, threatmate_hash,
00114 threatmate_path, threatmate_move, age)));
00115 const checkmate_t::table_t& table = checkmator->getTable(m_state.getTurn());
00116 const CheckHashRecord *record = table.find(m_state.getHash());
00117 assert(threatmate || record);
00118
00119 m_state.changeTurn();
00120
00121 if (threatmate)
00122 return ProofDisproof::Checkmate();
00123 return record->proofDisproof();
00124 }
00125
00126 const osl::checkmate::ProofDisproof osl::brinkmate::
00127 BrinkmateState::testWinningState(int node)
00128 {
00129 if ((depth() / 2) == 0)
00130 node *= 8;
00131 else if ((depth() / 2) == 1)
00132 node *= 2;
00133
00134 const HashKey& hash = m_state.getHash();
00135
00136 AttackOracleAges age;
00137 Move checkmate_move;
00138 const bool checkmate0
00139 = checkmator->isWinningState(0, m_state, hash, path, checkmate_move, age);
00140 const bool checkmate
00141 = (checkmate0
00142 || (checkmator->isWinningState(node, m_state, hash,
00143 path, checkmate_move, age)));
00144
00145 const checkmate_t::table_t& table = checkmator->getTable(m_state.getTurn());
00146 const CheckHashRecord *record = table.find(m_state.getHash());
00147 assert(checkmate || (node == 0) || record);
00148 if (checkmate)
00149 return ProofDisproof::Checkmate();
00150 if (node == 0)
00151 return ProofDisproof::Unknown();
00152 return record->proofDisproof();
00153 }
00154
00155 bool osl::brinkmate::
00156 BrinkmateState::isThreatmateState(int node)
00157 {
00158 return testThreatmateState(node).isCheckmateSuccess();
00159 }
00160
00161 bool osl::brinkmate::
00162 BrinkmateState::isWinningState(int node)
00163 {
00164 return testWinningState(node).isCheckmateSuccess();
00165 }
00166
00167
00168
00169
00170
00171