00001 #ifndef _PROOF_DISPROOF_H
00002 #define _PROOF_DISPROOF_H
00003
00004 #include "osl/move.h"
00005 #include <cassert>
00006 #include <iosfwd>
00007 namespace osl
00008 {
00009 namespace checkmate
00010 {
00016 class ProofDisproof
00017 {
00018 unsigned long long pdp;
00019 enum {
00020 PROOF_SHIFT = 32,
00021 DISPROOF_MASK = 0xffffffffu,
00022 PROOF_MAX = (0xffffffffu / 16),
00023 DISPROOF_MAX = (0xffffffffu / 16),
00025 NO_ESCAPE_DISPROOF = (DISPROOF_MAX - 1),
00026 CHECK_MATE_DISPROOF = (DISPROOF_MAX - 2),
00028 NO_CHECK_MATE_PROOF = (PROOF_MAX - 1),
00029 PAWN_CHECK_MATE_PROOF = (PROOF_MAX - 2),
00030 LOOP_DETECTION_PROOF = (PROOF_MAX - 3),
00031 ATTACK_BACK_PROOF = (PROOF_MAX - 4),
00032 };
00033 static void testConsistency();
00034 public:
00035 enum {
00037 DISPROOF_LIMIT = (DISPROOF_MAX - 3),
00039 PROOF_LIMIT = (PROOF_MAX - 5),
00040 };
00041 private:
00042 static unsigned long long
00043 compose(unsigned long long proof, unsigned long long disproof)
00044 {
00045 return (proof << PROOF_SHIFT) + disproof;
00046 }
00048 ProofDisproof(unsigned long long value) : pdp(value)
00049 {
00050 }
00051 static const ProofDisproof
00052 make(unsigned int proof, unsigned int disproof)
00053 {
00054 return ProofDisproof(compose(proof, disproof));
00055 }
00056 public:
00057 ProofDisproof() : pdp(compose(1, 1))
00058 {
00059 }
00060 ProofDisproof(unsigned int proof, unsigned int disproof)
00061 : pdp(compose(proof,disproof))
00062 {
00063 assert(proof < PROOF_MAX);
00064 assert(disproof < DISPROOF_MAX);
00065 assert(proof || disproof);
00066 assert((proof == 0) ^ (disproof < DISPROOF_LIMIT));
00067 assert((disproof == 0) ^ (proof < PROOF_LIMIT));
00068 }
00069 static const ProofDisproof makeDirect(unsigned long long value) { return ProofDisproof(value); }
00070
00071
00072 static const ProofDisproof NoEscape() { return ProofDisproof(0, NO_ESCAPE_DISPROOF); }
00073 static const ProofDisproof Checkmate() { return ProofDisproof(0, CHECK_MATE_DISPROOF); }
00074 static const ProofDisproof NoCheckmate() { return ProofDisproof(NO_CHECK_MATE_PROOF, 0); }
00075 static const ProofDisproof PawnCheckmate() { return ProofDisproof(PAWN_CHECK_MATE_PROOF, 0); }
00076 static const ProofDisproof LoopDetection() { return ProofDisproof(LOOP_DETECTION_PROOF, 0); }
00077 static const ProofDisproof AttackBack() { return ProofDisproof(ATTACK_BACK_PROOF, 0); }
00078 static const ProofDisproof Unknown () { return ProofDisproof(1, 1); }
00080 static const ProofDisproof Bottom () { return make(PROOF_MAX, DISPROOF_MAX); }
00081
00082 unsigned int proof() const { return pdp >> PROOF_SHIFT; }
00083 unsigned int disproof() const { return pdp & DISPROOF_MASK; }
00084 bool isCheckmateSuccess() const { return proof()==0; }
00085 bool isCheckmateFail() const { return disproof()==0; }
00086 bool isFinal() const { return isCheckmateSuccess() || isCheckmateFail(); }
00087 bool isUnknown() const { return !isFinal(); }
00088
00090 bool isPawnDropFoul(Move move) const
00091 {
00092 return (pdp == NoEscape().pdp) && move.isNormal() && move.isDrop()
00093 && (move.ptype()==PAWN);
00094 }
00095 bool isLoopDetection() const { return pdp == LoopDetection().pdp; }
00096
00097 unsigned long long ulonglongValue() const { return pdp; }
00098
00099 static const unsigned int BigProofNumber=PROOF_MAX;
00100
00104 bool isBetterForAttack(const ProofDisproof& r) const
00105 {
00106 const unsigned int lp = proof();
00107 const unsigned int rp = r.proof();
00108 if (lp != rp)
00109 return lp < rp;
00110 return disproof() > r.disproof();
00111 }
00115 bool isBetterForDefense(const ProofDisproof& r) const
00116 {
00117 const unsigned int ld = disproof();
00118 const unsigned int rd = r.disproof();
00119 if (ld != rd)
00120 return ld < rd;
00121 return proof() > r.proof();
00122 }
00126 const ProofDisproof& betterForAttack(const ProofDisproof& r) const
00127 {
00128 return (isBetterForAttack(r) ? *this : r);
00129 }
00133 const ProofDisproof& betterForDefense(const ProofDisproof& r) const
00134 {
00135 return (isBetterForDefense(r) ? *this : r);
00136 }
00137 };
00138 inline bool operator==(const ProofDisproof& l, const ProofDisproof& r)
00139 {
00140 return l.ulonglongValue() == r.ulonglongValue();
00141 }
00142 inline bool operator!=(const ProofDisproof& l, const ProofDisproof& r)
00143 {
00144 return ! (l == r);
00145 }
00146 inline bool operator<(const ProofDisproof& l, const ProofDisproof& r)
00147 {
00148 return l.ulonglongValue() < r.ulonglongValue();
00149 }
00150
00151 std::ostream& operator<<(std::ostream& os,
00152 const ProofDisproof& proofDisproof);
00153 }
00154
00155 using checkmate::ProofDisproof;
00156 }
00157 #endif // _PROOF_DISPROOF_H
00158
00159
00160
00161