00001
00002
00003 #ifndef _CHECKMOVE_H
00004 #define _CHECKMOVE_H
00005
00006 #include "osl/checkmate/proofDisproof.h"
00007 #include "osl/move.h"
00008 #include "osl/pathEncoding.h"
00009 #include <iosfwd>
00010 namespace osl
00011 {
00012 namespace checkmate
00013 {
00014 class CheckHashRecord;
00015 class TwinEntry;
00016 class TwinTable;
00017 class MoveFlags
00018 {
00019 unsigned char flags;
00020 public:
00021 enum Constant {
00023 Solved=1,
00025 BlockingBySacrifice=2,
00027 NoPromote=4,
00029 SacrificeAttack=8,
00032 Upward=16,
00034 ImmediateCheckmate=32,
00035 };
00036 MoveFlags() : flags(0) {}
00037 MoveFlags& operator=(Constant flag)
00038 {
00039 flags = static_cast<unsigned char>(flag);
00040 return *this;
00041 }
00042 void set(Constant flag)
00043 {
00044 assert((flags & flag) == 0);
00045 flags |= flag;
00046 }
00047 void unset(Constant flag)
00048 {
00049 assert(flags & flag);
00050 flags ^= flag;
00051 }
00052 int isSet(Constant flag) const
00053 {
00054 return flags & flag;
00055 }
00056 int getFlags() const { return flags; }
00057 };
00058 class MoveFilter
00059 {
00060 unsigned char mask;
00061 public:
00062 MoveFilter() : mask(31)
00063 {
00064 }
00065 bool isTarget(MoveFlags flags) const
00066 {
00067 return (mask & flags.getFlags()) == 0;
00068 }
00069 void addTarget(MoveFlags::Constant flag)
00070 {
00071 assert(! isTarget(flag));
00072 mask ^= flag;
00073 }
00074 bool isTarget(MoveFlags::Constant flag) const
00075 {
00076 return (mask & flag) == 0;
00077 }
00078 int getMask() const { return mask; }
00079 };
00080 std::ostream& operator<<(std::ostream& os, MoveFlags);
00081 std::ostream& operator<<(std::ostream& os, MoveFilter);
00085 struct CheckMoveCore
00086 {
00088 CheckHashRecord *record;
00089 Move move;
00090 explicit CheckMoveCore(Move m=Move::INVALID(), CheckHashRecord *r=0)
00091 : record(r), move(m)
00092 {
00093 }
00094 };
00098 struct CheckMove : public CheckMoveCore
00099 {
00100 MoveFlags flags;
00102 signed char cost_proof, cost_disproof;
00104 unsigned short h_proof, h_disproof;
00105 explicit CheckMove(Move m=Move::INVALID(), CheckHashRecord *r=0)
00106 : CheckMoveCore(m, r),
00107 cost_proof(0), cost_disproof(0), h_proof(1), h_disproof(1)
00108 {
00109 }
00110 void addCost(unsigned& proof, unsigned int& disproof) const
00111 {
00112 assert(proof && disproof);
00113 assert(cost_proof >= 0);
00114 assert(cost_disproof >= 0);
00115 proof += cost_proof;
00116 disproof += cost_disproof;
00117 assert(proof < ProofDisproof::PROOF_LIMIT);
00118 assert(disproof < ProofDisproof::DISPROOF_LIMIT);
00119 }
00125 inline const TwinEntry* findLoop(const PathEncoding& path,
00126 const TwinTable& table) const;
00127 inline const TwinEntry* findLoopInList(const PathEncoding& path) const;
00128 };
00129 inline bool operator==(const CheckMove& l, const CheckMove& r)
00130 {
00131 if (l.move == r.move)
00132 {
00133 assert(l.record == r.record);
00134 return true;
00135 }
00136 assert(l.record != r.record || (l.record == 0 && r.record == 0));
00137 return false;
00138 }
00139 }
00140 }
00141
00142
00143 #endif
00144
00145
00146
00147