00001
00002
00003
00004
00005
00006 #ifndef PROOFUTIL_HPP
00007 #define PROOFUTIL_HPP
00008
00009 #include "Hex.hpp"
00010 #include "BenzeneSolver.hpp"
00011 #include "StoneBoard.hpp"
00012 #include "ICEngine.hpp"
00013 #include "SolverDB.hpp"
00014 #include "SortedSequence.hpp"
00015
00016 _BEGIN_BENZENE_NAMESPACE_
00017
00018
00019
00020
00021 namespace ProofUtil
00022 {
00023
00024 bitset_t MaximumProofSet(const HexBoard& brd, HexColor toPlay);
00025
00026
00027
00028
00029
00030
00031 bitset_t InitialProofForOpponent(const HexBoard& brd, HexColor toPlay);
00032
00033
00034
00035
00036 bool ShrinkProof(bitset_t& proof, const StoneBoard& board,
00037 HexColor loser, const ICEngine& ice);
00038
00039
00040
00041
00042 template<class HASH, class DB, class DATA>
00043 int StoreTranspositions(SolverDB<HASH,DB,DATA>& db, const DATA& data,
00044 const HexState& state, const bitset_t& proof,
00045 HexColor winner);
00046
00047
00048
00049
00050 template<class HASH, class DB, class DATA>
00051 int StoreFlippedStates(SolverDB<HASH,DB,DATA>& db, const DATA& data,
00052 const HexState& state, const bitset_t& proof,
00053 HexColor winner);
00054 }
00055
00056
00057
00058 template<class HASH, class DB, class DATA>
00059 int ProofUtil::StoreTranspositions(SolverDB<HASH,DB,DATA>& db,
00060 const DATA& data, const HexState& state,
00061 const bitset_t& proof, HexColor winner)
00062 {
00063 boost::function_requires< HasFlagsConcept<DATA> >();
00064 const StoneBoard& brd = state.Position();
00065
00066
00067 int numBlack = (brd.GetPlayed(BLACK) & brd.Const().GetCells()).count();
00068 int numWhite = (brd.GetPlayed(WHITE) & brd.Const().GetCells()).count();
00069 HexAssert(numBlack + numWhite == brd.NumStones());
00070
00071
00072 HexColor loser = !winner;
00073 bitset_t outside = (~proof & brd.GetEmpty())
00074 | (brd.GetColor(loser) & brd.Const().GetCells());
00075
00076
00077 bitset_t winners = brd.GetColor(winner) & brd.Const().GetCells();
00078
00079
00080 std::vector<HexPoint> black, white;
00081 std::vector<HexPoint>& lose_list = (loser == BLACK) ? black : white;
00082 std::vector<HexPoint>& winn_list = (loser == BLACK) ? white : black;
00083 BitsetUtil::BitsetToVector(outside, lose_list);
00084 BitsetUtil::BitsetToVector(winners, winn_list);
00085
00086 HexAssert(black.size() >= (unsigned)numBlack);
00087 HexAssert(white.size() >= (unsigned)numWhite);
00088
00089
00090 int count = 0;
00091 HexState myState(state);
00092 StoneBoard& board = myState.Position();
00093 SortedSequence bseq(black.size(), numBlack);
00094 while (!bseq.finished())
00095 {
00096 SortedSequence wseq(white.size(), numWhite);
00097 while (!wseq.finished())
00098 {
00099
00100 board.StartNewGame();
00101 for (int i = 0; i < numBlack; ++i)
00102 board.PlayMove(BLACK, black[bseq[i]]);
00103 for (int i = 0; i < numWhite; ++i)
00104 board.PlayMove(WHITE, white[wseq[i]]);
00105
00106
00107
00108 DATA ss(data);
00109 if (board.Hash() != brd.Hash())
00110 ss.m_flags |= SolverDataFlags::TRANSPOSITION;
00111 db.Put(myState, ss);
00112 ++count;
00113
00114 ++wseq;
00115 }
00116 ++bseq;
00117 }
00118 return count;
00119 }
00120
00121 template<class HASH, class DB, class DATA>
00122 int ProofUtil::StoreFlippedStates(SolverDB<HASH,DB,DATA>& db, const DATA& data,
00123 const HexState& state, const bitset_t& proof,
00124 HexColor winner)
00125 {
00126 boost::function_requires< HasFlagsConcept<DATA> >();
00127 boost::function_requires< HasMirrorConcept<DATA> >();
00128 const StoneBoard& brd = state.Position();
00129
00130
00131
00132 bitset_t flippedBlack = BoardUtils::Mirror(brd.Const(),
00133 brd.GetPlayed(WHITE) & brd.Const().GetCells());
00134 bitset_t flippedWhite = BoardUtils::Mirror(brd.Const(),
00135 brd.GetPlayed(BLACK) & brd.Const().GetCells());
00136 StoneBoard flippedBrd(brd.Width(), brd.Height());
00137 flippedBrd.AddColor(BLACK, flippedBlack);
00138 flippedBrd.AddColor(WHITE, flippedWhite);
00139 flippedBrd.SetPlayed(flippedBlack | flippedWhite);
00140
00141
00142 HexColor flippedWinner = !winner;
00143 bitset_t flippedProof = BoardUtils::Mirror(brd.Const(), proof);
00144 bitset_t flippedOutside = (~flippedProof & flippedBrd.GetEmpty());
00145
00146
00147 bool canAddFlippedBlack = false;
00148 bitset_t flippedBlackToAdd;
00149 bool canRemoveFlippedWhite = false;
00150 bitset_t flippedWhiteToRemove;
00151
00152
00153
00154
00155
00156 if (flippedWinner == BLACK)
00157 {
00158 canAddFlippedBlack = true;
00159 flippedBlackToAdd = flippedBrd.GetEmpty();
00160 canRemoveFlippedWhite = true;
00161 flippedWhiteToRemove = flippedWhite;
00162 }
00163 else
00164 {
00165 HexAssert(flippedWinner == WHITE);
00166 canAddFlippedBlack = flippedOutside.any();
00167 flippedBlackToAdd = flippedOutside;
00168 }
00169 HexAssert(canAddFlippedBlack != flippedBlackToAdd.none());
00170 HexAssert(BitsetUtil::IsSubsetOf(flippedBlackToAdd,flippedBrd.GetEmpty()));
00171 HexAssert(canRemoveFlippedWhite != flippedWhiteToRemove.none());
00172 HexAssert(BitsetUtil::IsSubsetOf(flippedWhiteToRemove,flippedWhite));
00173
00174
00175 DATA ss(data);
00176 ss.Mirror(brd.Const());
00177 ss.m_flags |= SolverDataFlags::TRANSPOSITION;
00178 ss.m_flags |= SolverDataFlags::MIRROR_TRANSPOSITION;
00179
00180 int count = 0;
00181 if (canAddFlippedBlack)
00182 {
00183 for (BitsetIterator i(flippedBlackToAdd); i; ++i)
00184 {
00185 flippedBrd.PlayMove(BLACK, *i);
00186 HexAssert(!state.ToPlay() == flippedBrd.WhoseTurn());
00187 db.Put(HexState(flippedBrd, WHITE), ss);
00188 flippedBrd.UndoMove(*i);
00189 ++count;
00190 }
00191 }
00192 if (canRemoveFlippedWhite)
00193 {
00194 for (BitsetIterator i(flippedWhiteToRemove); i; ++i)
00195 {
00196 flippedBrd.UndoMove(*i);
00197 HexAssert(!state.ToPlay() == flippedBrd.WhoseTurn());
00198 db.Put(HexState(flippedBrd, WHITE), ss);
00199 flippedBrd.PlayMove(WHITE, *i);
00200 ++count;
00201 }
00202 }
00203 return count;
00204 }
00205
00206
00207
00208 _END_BENZENE_NAMESPACE_
00209
00210 #endif // PROOFUTIL_HPP