00001
00002
00003 #ifndef _BLOCKING_SIMULATION_TCC
00004 #define _BLOCKING_SIMULATION_TCC
00005
00006 #include "osl/checkmate/blockingSimulation.h"
00007 #include "osl/checkmate/checkHashRecord.h"
00008 #include "osl/checkmate/oracleProver.h"
00009 #include "osl/checkmate/checkTableUtil.h"
00010 #include "osl/apply_move/applyMoveWithPath.h"
00011 #ifdef CHECKMATE_DEBUG
00012 # include "osl/stat/ratio.h"
00013 #endif
00014
00015 namespace osl
00016 {
00017 namespace checkmate
00018 {
00019 template <class Prover, Player P>
00020 struct CallProver
00021 {
00022 typedef typename Prover::state_t state_t;
00023 bool *result;
00024 Prover *prover;
00025 state_t *state;
00026 const HashKey& key;
00027 const PathEncoding& path;
00028 ProofOracleAttack<P> oracle;
00029 CallProver(bool *r, Prover *p, state_t *s, const HashKey& k,
00030 const PathEncoding& pa, ProofOracleAttack<P> o)
00031 : result(r), prover(p), state(s), key(k), path(pa), oracle(o)
00032 {
00033 }
00034 void operator()(Position)
00035 {
00036 Move check_move;
00037 *result = (*prover).template proofWin<P>
00038 (*state, key, path, oracle, check_move);
00039 }
00040 };
00041 }
00042 }
00043
00044 template <osl::Player P>
00045 template <class Table>
00046 inline
00047 bool osl::checkmate::BlockingSimulation<P>::
00048 proof(NumEffectState& state, const HashKey& new_key,
00049 const PathEncoding& new_path, Table& table,
00050 const CheckMove& target, const CheckHashRecord *guide,
00051 size_t& node_count)
00052 {
00053 assert(state.getTurn() == alt(P));
00054 ProofOracleAttack<P> oracle(guide);
00055 assert(oracle.isValid());
00056 typedef OracleProver<Table> prover_t;
00057 prover_t prover(table);
00058 bool result;
00059 CallProver<prover_t,P> helper(&result, &prover, &state, new_key, new_path, oracle);
00060 ApplyMove<PlayerTraits<P>::opponent>::doUndoMove(state, target.move, helper);
00061 node_count += prover.nodeCount();
00062 return result;
00063 }
00064
00065 template <osl::Player P>
00066 template <class Table>
00067 bool osl::checkmate::BlockingSimulation<P>::
00068 proof(NumEffectState& state, const HashKey& new_key, const PathEncoding& new_path,
00069 const CheckHashRecord *record, Table& table, const CheckMove& move,
00070 size_t& node_count)
00071 {
00072 #ifdef CHECKMATE_DEBUG
00073 static stat::Ratio oracle_found("blocking proof:oracle found"),
00074 proven("blocking proof:sim success");
00075 #endif
00076 CheckMoveList::const_iterator p=record->moves.begin();
00077 for (; p!=record->moves.end(); ++p)
00078 {
00079 if (p->flags.isSet(MoveFlags::Solved)
00080 && (p->move.to() == move.move.to()))
00081 break;
00082 }
00083 #ifdef CHECKMATE_DEBUG
00084 oracle_found.add(p != record->moves.end());
00085 #endif
00086 if (p == record->moves.end())
00087 return false;
00088
00089 const bool result = proof(state, new_key, new_path,
00090 table, move, p->record, node_count);
00091 #ifdef CHECKMATE_DEBUG
00092 proven.add(result);
00093 #endif
00094 return result;
00095 }
00096
00097 template <osl::Player P>
00098 template <class Table>
00099 void osl::checkmate::BlockingSimulation<P>::
00100 proofSibling(NumEffectState& state,
00101 const HashKey& key, const PathEncoding& path,
00102 CheckHashRecord *record,
00103 Table& table, const CheckMove& guide, size_t& node_count)
00104 {
00105 #ifdef CHECKMATE_DEBUG
00106 static stat::Ratio proven("blocking proof:sibling");
00107 #endif
00108 const Position to = guide.move.to();
00109 for (CheckMoveList::iterator p=record->moves.begin();
00110 p!=record->moves.end(); ++p)
00111 {
00112 if (! record->filter.isTarget(p->flags))
00113 continue;
00114 if (p->move.to() == to)
00115 {
00116 const HashKey new_key = key.newHashWithMove(p->move);
00117 const PathEncoding new_path(path, p->move);
00118 if (! p->record)
00119 {
00120 CheckTableUtil::allocate
00121 (p->move, p->record, table, new_key, new_path, record);
00122 }
00123 const bool result =
00124 proof(state, new_key, new_path, table, *p, guide.record, node_count);
00125 if (result)
00126 record->addToSolvedInDefense(*p, p->record->proofDisproof());
00127 #ifdef CHECKMATE_DEBUG
00128 proven.add(result);
00129 #endif
00130 }
00131 }
00132 }
00133
00134
00135 #endif
00136
00137
00138
00139