00001
00002
00003 #ifndef _DEFENSE_SIMULATION_TCC
00004 #define _DEFENSE_SIMULATION_TCC
00005
00006 #include "osl/checkmate/defenseSimulation.h"
00007 #include "osl/checkmate/checkHashRecord.h"
00008 #include "osl/checkmate/oracleDisprover.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 Disprover, Player P>
00020 struct CallDisprover
00021 {
00022 typedef typename Disprover::state_t state_t;
00023 bool *result;
00024 Disprover *prover;
00025 state_t *state;
00026 const HashKey& new_key;
00027 const PathEncoding& new_path;
00028 DisproofOracleDefense<P> oracle;
00029 Move last_move;
00030 CallDisprover(bool *r, Disprover *p, state_t *s,
00031 const HashKey& k, const PathEncoding& pa,
00032 DisproofOracleDefense<P> o, Move last)
00033 : result(r), prover(p), state(s), new_key(k), new_path(pa),
00034 oracle(o), last_move(last)
00035 {
00036 }
00037 void operator()(Position)
00038 {
00039 Move escape_move;
00040 *result = (*prover).template proofEscape<P>
00041 (*state, new_key, new_path, oracle, escape_move, last_move);
00042 }
00043 };
00044 }
00045 }
00046
00047 template <osl::Player P>
00048 template <class Table>
00049 inline
00050 bool osl::checkmate::DefenseSimulation<P>::
00051 disproof(NumEffectState& state,
00052 const HashKey& new_key, const PathEncoding& new_path, Table& table,
00053 const CheckMove& target, CheckHashRecord *guide, size_t& node_count)
00054 {
00055 check_assert(target.record);
00056 check_assert(state.getTurn() == P);
00057 DisproofOracleDefense<P> oracle(guide);
00058 check_assert(oracle.isValid());
00059 typedef OracleDisprover<Table> disprover_t;
00060 disprover_t disprover(table);
00061 bool result;
00062 CallDisprover<disprover_t,P>
00063 helper(&result, &disprover, &state, new_key, new_path, oracle, target.move);
00064 ApplyMove<P>::doUndoMove(state, target.move, helper);
00065 node_count += disprover.nodeCount();
00066 return result;
00067 }
00068
00069 template <osl::Player P>
00070 template <class Table>
00071 bool osl::checkmate::DefenseSimulation<P>::
00072 disproofNoPromote(NumEffectState& state,
00073 const HashKey& new_key,
00074 const PathEncoding& new_path,
00075 CheckHashRecord *record, Table& table,
00076 CheckMove& target, const CheckMove& guide,
00077 size_t& node_count)
00078 {
00079 #ifdef CHECKMATE_DEBUG
00080 static stat::Ratio disproven("defense disproof:nopromote");
00081 #endif
00082 check_assert(guide.move.noPromote() == target.move);
00083 const bool result = disproof(state, new_key, new_path, table, target,
00084 guide.record, node_count);
00085 if (result)
00086 {
00087 if (target.record->proofDisproof().isCheckmateFail())
00088 record->addToSolvedInAttack(target, target.record->proofDisproof());
00089 else
00090 check_assert(target.record->findLoop(new_path, table.getTwinTable()));
00091 }
00092 #ifdef CHECKMATE_DEBUG
00093 disproven.add(result);
00094 #endif
00095 return result;
00096 }
00097
00098 template <osl::Player P>
00099 template <class Table>
00100 void osl::checkmate::DefenseSimulation<P>::
00101 disproofDropSibling(NumEffectState& state,
00102 const HashKey& key, const PathEncoding& path,
00103 CheckHashRecord *record,
00104 Table& table, const CheckMove& guide, size_t& node_count)
00105 {
00106 #ifdef CHECKMATE_DEBUG
00107 static stat::Ratio disproven("defense disproof:drop sibling");
00108 #endif
00109 check_assert(guide.move.isDrop());
00110 const Ptype ptype = guide.move.ptype();
00111 for (CheckMoveList::iterator p=record->moves.begin();
00112 p!=record->moves.end(); ++p)
00113 {
00114 if (! record->filter.isTarget(p->flags))
00115 continue;
00116 if (! p->move.isDrop())
00117 continue;
00118
00119 const HashKey new_key = key.newHashWithMove(p->move);
00120 const PathEncoding new_path(path, p->move);
00121 if (p->move.ptype() == ptype)
00122 {
00123 if (! p->record)
00124 {
00125 CheckTableUtil::allocate
00126 (p->move, p->record, table, new_key, new_path, record);
00127 }
00128 const bool result =
00129 disproof(state, new_key, new_path, table, *p, guide.record, node_count);
00130 if (result)
00131 {
00132 if (p->record->proofDisproof().isCheckmateFail())
00133 record->addToSolvedInAttack(*p, p->record->proofDisproof());
00134 else
00135 check_assert(p->findLoop(path, table.getTwinTable()));
00136 }
00137 #ifdef CHECKMATE_DEBUG
00138 disproven.add(result);
00139 #endif
00140 }
00141 }
00142 }
00143
00144
00145 #endif
00146
00147
00148
00149