void TestIterativeValue(int depth) { // setup book and cache CCache acache(2); cache = &acache; const int nEmpty = 22; CBook* oldBook = book; book = NULL; InitializeCache(); SetBookHeights(nEmpty); mpcs = CMPCStats::GetMPCStats('J','A',5); // testing const COsGame osGame = LoadTestGames().at(0); const CQPosition testPosition = PositionFromEmpties(osGame, nEmpty); std::vector<CMoveValue> mvs = createMoves(testPosition); Pos2 pos2; pos2.Initialize(testPosition.BitBoard(), testPosition.BlackMove()); u4 nValued=0; std::vector<CMoveValue> mvsEvaluated; ValueMulti(pos2, depth, -kInfinity, kInfinity, 4, 1, mvs, false, false, mvsEvaluated, nValued); // cout << " nValued = " << nValued << "\n"; // cout << " mvsEvaluated = \n"; // for (int i=0; i<mvsEvaluated.size(); i++) { // CMoveValue mv = mvsEvaluated.at(i); // cout << "new CMoveValue(" << mv.move << "," << mv.value << "),\n"; // } // cout << "\n"; // tear down book and cache book = oldBook; cache = NULL; }
//! Helper routine to make sure that the given position is stored as an unsolved leaf node in the book static void TestULeafPos(const CBook& book, const CQPosition& pos, CValue value, const CHeightInfoX& hix) { const CBookData* bd=book.FindData(pos.BitBoard()); TEST(bd!=NULL); TEST(bd->IsLeaf()); TEST(!bd->IsProven()); TEST(bd->IsUleaf()); TEST(bd->Hi()==hix); TEST(bd->Values().vMover==value); TEST(bd->Values().vOpponent==value); TEST(bd->Values().vHeuristic==value); }
//! Test that WriteCompressed() followed by ReadCompressed() returns the same book void CBook::TestIO() { { // test book with no position CBook book(NULL, s_out); book.TestMyIO(); } { // test book with a pass position and a subposition from that CBook book(NULL, s_out); CQPosition pos; pos.Initialize("---------------------------**------**------------------O------O*", true); book.StoreRoot(pos.BitBoard(), CHeightInfoX(10, 4, false, pos.NEmpty()), 32, -300); pos.MakeMove(CMove(057)); pos.Pass(); book.StoreLeaf(pos.BitBoard(), CHeightInfoX(10, 4, false, pos.NEmpty()), 32); book.TestMyIO(); } { // test book with only one entry CBook book(NULL, s_out); CQPosition pos; pos.Initialize(); book.StoreLeaf(pos.BitBoard(), CHeightInfoX(10, 4, false, 60), 32); book.TestMyIO(); } { // test book with two entries in a tree CBook book(NULL, s_out); CQPosition pos; pos.Initialize(); book.StoreRoot(pos.BitBoard(), CHeightInfoX(10, 4, false, 60), 32, 16400); pos.MakeMove(CMove(045)); book.StoreLeaf(pos.BitBoard(), CHeightInfoX(10, 4, false, 59), -32); book.TestMyIO(); } }
void TestFindQuestionableNode() { COsGame game; game.Initialize("8"); CQPosition initialPos(game, 0); CQPosition questionablePosition; CBook book; bool drawToMover; // The position is not in book. FindQuestionableNode should return NULL. bool isQuestionable = book.FindQuestionableNode(questionablePosition, drawToMover, initialPos, drawCutoff, deviationCutoff); TEST(!isQuestionable); // add the initial position to the book. FindQuestionableNode should return the initial position. const CBitBoard initialBitBoard(initialPos.BitBoard()); CMinimalReflection mr(initialBitBoard); CHeightInfoX heightInfoX(2, 4, false, initialBitBoard.NEmpty()); book.StoreLeaf(CMinimalReflection(initialBitBoard), heightInfoX, 0); isQuestionable = book.FindQuestionableNode(questionablePosition, drawToMover, initialPos, drawCutoff, deviationCutoff); TEST(isQuestionable); TEST(questionablePosition==initialPos); // add the initial position to the book with a deviation of the deviation cutoff // Since this is bigger than the threshold for deviations, we won't count it. book.StoreLeaf(CMinimalReflection(initialBitBoard), heightInfoX, deviationCutoff); isQuestionable = book.FindQuestionableNode(questionablePosition, drawToMover, initialPos, drawCutoff, deviationCutoff); TEST(!isQuestionable); // but if it's one less than the deviation cutoff, it's questionable book.StoreLeaf(CMinimalReflection(initialBitBoard), heightInfoX, deviationCutoff-1); isQuestionable = book.FindQuestionableNode(questionablePosition, drawToMover, initialPos, drawCutoff, deviationCutoff); TEST(isQuestionable); TEST(questionablePosition==initialPos); // Also if it's negative... at the deviation cutoff is ok, one more is questionable book.StoreLeaf(CMinimalReflection(initialBitBoard), heightInfoX, -deviationCutoff); isQuestionable = book.FindQuestionableNode(questionablePosition, drawToMover, initialPos, drawCutoff, deviationCutoff); TEST(!isQuestionable); book.StoreLeaf(CMinimalReflection(initialBitBoard), heightInfoX, 1-deviationCutoff); isQuestionable = book.FindQuestionableNode(questionablePosition, drawToMover, initialPos, drawCutoff, deviationCutoff); TEST(isQuestionable); TEST(questionablePosition==initialPos); // This node is a draw, at +3/-3.. so it's ok const CBookData* bookData = book.FindData(initialBitBoard); // casting to remove const is a really bad idea... but no other easy way to test CBookValue& bookValue = (CBookValue&)(bookData->Values()); bookValue.vHeuristic = 0; bookValue.vMover = drawCutoff; bookValue.vOpponent = - drawCutoff; isQuestionable = book.FindQuestionableNode(questionablePosition, drawToMover, initialPos, drawCutoff, deviationCutoff); TEST(!isQuestionable); TEST(questionablePosition==initialPos); CQPosition nextPos(initialPos); nextPos.MakeMove(CMove("F5")); const CBitBoard f5 = nextPos.BitBoard(); nextPos.MakeMove(CMove("D6")); const CBitBoard f5d6 = nextPos.BitBoard(); nextPos = initialPos; nextPos.MakeMove(CMove("F5")); nextPos.MakeMove(CMove("F6")); const CBitBoard f5f6 = nextPos.BitBoard(); // Now we have a questionable position, but it's not at the initial node // tree is: // f5 d6 : proven draw // f5 f6 : deviation with value drawValue book.StoreRoot(initialBitBoard, heightInfoX, 0, -16400); book.StoreRoot(f5, heightInfoX, 0, -16400); CHeightInfoX hixSolved = CHeightInfoX(f5f6.NEmpty(), 0, false, f5f6.NEmpty()); book.StoreLeaf(f5f6, hixSolved, 0); book.StoreLeaf(f5d6, heightInfoX, drawCutoff); book.NegamaxAll(); isQuestionable = book.FindQuestionableNode(questionablePosition, drawToMover, initialPos, drawCutoff, deviationCutoff); TEST(isQuestionable); TEST(CMinimalReflection(questionablePosition.BitBoard())==CMinimalReflection(f5d6)); // This position has a questionable node, but it's not on the draw tree so it's not returned CBook book2; book2.StoreRoot(initialBitBoard, heightInfoX, -deviationCutoff, -16400); book2.StoreRoot(f5, heightInfoX, deviationCutoff, -16400); book2.StoreLeaf(f5f6, heightInfoX, -deviationCutoff); book2.StoreLeaf(f5d6, heightInfoX, 0); book2.NegamaxAll(); isQuestionable = book2.FindQuestionableNode(questionablePosition, drawToMover, initialPos, drawCutoff, deviationCutoff); TEST(!isQuestionable); }
//! Test CBook::StoreSubposition(). //! While we're at it, test negamaxing as well, so store the parent position //! as a branch node and see if it's assigned the right value. static void TestStoreSubposition() { { // test StoreSubposition() when there is no pass after the move. CBook book; CQPosition pos; pos.Initialize(); const CMoveValue mv(F5, 41); CHeightInfoX hix(2, 4, false, pos.NEmpty()); // store subpos in book book.StoreSubposition(pos, mv, hix); TEST(book.Size()==1); // test that subpos went in correctly CQPosition posSub(pos); posSub.MakeMove(mv.move); CHeightInfoX hixSub(1, 4, false, posSub.NEmpty()-1); TestULeafPos(book, posSub, -mv.value, hixSub); // test that pos is valued correctly when we negamax book.StoreRoot(pos.BitBoard(), hix, mv.value, -100); book.NegamaxAll(); const CBookData* pbd=book.FindData(pos.BitBoard()); TEST(pbd!=NULL); TEST(pbd->Values().vHeuristic==mv.value); } { // test StoreSubposition() when there is a pass after the move. CBook book; CQPosition pos("OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO*******-----------------", false); CMoveValue mv(A7, 64*kStoneValue); CHeightInfoX hix(2, 4, false, pos.NEmpty()); // store subpos in book book.StoreSubposition(pos, mv, hix); TEST(book.Size()==1); // test that subpos went in correctly CQPosition posSub(pos); posSub.MakeMoveAndPass(mv.move); CHeightInfoX hixSub(1, 4, false, posSub.NEmpty()-1); TestULeafPos(book, posSub, mv.value, hixSub); // test that pos is valued correctly when we negamax book.StoreRoot(pos.BitBoard(), hix, mv.value, -100); book.NegamaxAll(); const CBookData* pbd=book.FindData(pos.BitBoard()); TEST(pbd!=NULL); TEST(pbd->Values().vHeuristic==mv.value); } { // test StoreSubposition() when there are two passes after the move. // no subposition should be added to the book (we don't store terminal nodes in book.) CBook book; CQPosition pos("OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO******-----------------", false); CMoveValue mv; mv.move=H6; mv.value=64*kStoneValue; CHeightInfoX hix(2, 4, false, pos.NEmpty()); // store subpos in book book.StoreSubposition(pos, mv, hix); TEST(book.Size()==0); // test that pos is valued correctly when we negamax book.StoreRoot(pos.BitBoard(), hix, mv.value, -100); book.NegamaxAll(); const CBookData* pbd=book.FindData(pos.BitBoard()); TEST(pbd!=NULL); TEST(pbd->Values().vHeuristic==mv.value); } }