proofDisproof.h
Go to the documentation of this file.
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     public:
00020       enum {
00021         PROOF_SHIFT = 32,
00022         DISPROOF_MASK = 0xffffffffu,
00023         PROOF_MAX = (0xffffffffu / 16),
00024         DISPROOF_MAX = (0xffffffffu / 16),
00026         NO_ESCAPE_DISPROOF  = (DISPROOF_MAX - 1),
00027         CHECK_MATE_DISPROOF = (DISPROOF_MAX - 2),
00029         NO_CHECK_MATE_PROOF   = (PROOF_MAX - 1),
00030         PAWN_CHECK_MATE_PROOF = (PROOF_MAX - 2),
00031         LOOP_DETECTION_PROOF  = (PROOF_MAX - 3),
00032         ATTACK_BACK_PROOF  = (PROOF_MAX - 4),
00033       };
00034     private:
00035       static void testConsistency();
00036     public:
00037       enum {
00039         DISPROOF_LIMIT = (DISPROOF_MAX - 3),
00041         PROOF_LIMIT           = (PROOF_MAX - 5),
00042       };
00043     private:
00044       static unsigned long long
00045       compose(unsigned long long proof, unsigned long long disproof) 
00046       {
00047         return (proof << PROOF_SHIFT) + disproof;
00048       }
00050       ProofDisproof(unsigned long long value) : pdp(value)
00051       {
00052       }
00053       static const ProofDisproof
00054       make(unsigned int proof, unsigned int disproof)
00055       {
00056         return ProofDisproof(compose(proof, disproof));
00057       }
00058     public:
00059       ProofDisproof() : pdp(compose(1, 1))
00060       {
00061       }
00062       ProofDisproof(unsigned int proof, unsigned int disproof)
00063         : pdp(compose(proof,disproof))
00064       {
00065         assert(proof < PROOF_MAX);
00066         assert(disproof < DISPROOF_MAX);
00067         assert(proof || disproof);
00068         assert((proof == 0) ^ (disproof < DISPROOF_LIMIT));
00069         assert((disproof == 0) ^ (proof < PROOF_LIMIT));
00070       }
00071       static const ProofDisproof makeDirect(unsigned long long value) { return ProofDisproof(value); }
00072 
00073       // constants
00074       static const ProofDisproof NoEscape()  { return ProofDisproof(0, NO_ESCAPE_DISPROOF); }
00075       static const ProofDisproof Checkmate() { return ProofDisproof(0, CHECK_MATE_DISPROOF); }
00076       static const ProofDisproof NoCheckmate() { return ProofDisproof(NO_CHECK_MATE_PROOF,   0); }
00077       static const ProofDisproof PawnCheckmate() { return ProofDisproof(PAWN_CHECK_MATE_PROOF, 0); }
00078       static const ProofDisproof LoopDetection() { return ProofDisproof(LOOP_DETECTION_PROOF,  0); }
00079       static const ProofDisproof AttackBack() { return ProofDisproof(ATTACK_BACK_PROOF,  0); }
00080       static const ProofDisproof Unknown () { return ProofDisproof(1, 1); }
00082       static const ProofDisproof Bottom    () { return make(PROOF_MAX, DISPROOF_MAX); }
00083 
00084       unsigned int proof()    const { return pdp >> PROOF_SHIFT; }
00085       unsigned int disproof() const { return pdp & DISPROOF_MASK; }
00086       bool isCheckmateSuccess() const { return proof()==0; }
00087       bool isCheckmateFail() const { return disproof()==0; }
00088       bool isFinal() const { return isCheckmateSuccess() || isCheckmateFail(); }
00089       bool isUnknown() const { return !isFinal(); }
00090 
00092       bool isPawnDropFoul(Move move) const
00093       {
00094         return (pdp == NoEscape().pdp) && move.isNormal() && move.isDrop() 
00095           && (move.ptype()==PAWN);
00096       }
00097       bool isLoopDetection() const { return pdp == LoopDetection().pdp; }
00098       
00099       unsigned long long ulonglongValue() const { return pdp; }
00100 
00101       static const unsigned int BigProofNumber=PROOF_MAX;
00102 
00106       bool isBetterForAttack(const ProofDisproof& r) const
00107       {
00108         const unsigned int lp = proof();
00109         const unsigned int rp = r.proof();
00110         if (lp != rp)
00111           return lp < rp;
00112         return disproof() > r.disproof();
00113       }
00117       bool isBetterForDefense(const ProofDisproof& r) const
00118       {
00119         const unsigned int ld = disproof();
00120         const unsigned int rd = r.disproof();
00121         if (ld != rd)
00122           return ld < rd;
00123         return proof() > r.proof();
00124       }
00128       const ProofDisproof& betterForAttack(const ProofDisproof& r) const
00129       {
00130         return (isBetterForAttack(r) ? *this : r);
00131       }
00135       const ProofDisproof& betterForDefense(const ProofDisproof& r) const
00136       {
00137         return (isBetterForDefense(r) ? *this : r);
00138       }
00139     };
00140     inline bool operator==(const ProofDisproof& l, const ProofDisproof& r)
00141     {
00142       return l.ulonglongValue() == r.ulonglongValue();
00143     }
00144     inline bool operator!=(const ProofDisproof& l, const ProofDisproof& r)
00145     {
00146       return ! (l == r);
00147     }
00148     inline bool operator<(const ProofDisproof& l, const ProofDisproof& r)
00149     {
00150       return l.ulonglongValue() < r.ulonglongValue();
00151     }
00152   
00153     std::ostream& operator<<(std::ostream& os,
00154                              const ProofDisproof& proofDisproof);
00155   } // namespace checkmate
00156 
00157   using checkmate::ProofDisproof;
00158 } // namespace osl
00159 #endif // _PROOF_DISPROOF_H
00160 // ;;; Local Variables:
00161 // ;;; mode:c++
00162 // ;;; c-basic-offset:2
00163 // ;;; End:
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines