// preconditions: computer has no book void CalcMPCStats(CPlayerComputer* computer, int height) { FILE* cpFile; CBitBoard bb; int nbbs[60], i, iPos; const int iPosMin=159; // start at this line, useful if stopping and restarting CQPosition pos; CCalcParams *cpOld=computer->pcp; CHeightInfo hi(height, 0, false); CCalcParamsFixedHeight cp(hi); computer->pcp=&cp; computer->cd.fsPrint=0; // header info std::cout << 3 << " " << height << " " << kStoneValue << "\n"; // clear computer's and params //computer->cd.iPruneMidgame=computer->cd.iPruneEndgame=0; // clear position counts and init for (i=0; i<60; i++) nbbs[i]=0; iPos=0; // read positions from file; analyze if we should std::string fn(fnBaseDir); fn+="captured.pos"; if ((cpFile=fopen(fn.c_str(),"rb"))) { while (bb.Read(cpFile)) { pos.Initialize(bb, true); if (nbbs[bb.NEmpty()]++ < kMaxPositions) if (iPos++>=iPosMin) AnalyzePosition(computer, pos); } fclose(cpFile); } // restore computer's book and params computer->pcp=cpOld; }
/// /// prints a labeled bitboard diagram as a comment /// void CFiestyGen::printBitBoardDiagram( std::string& rLabel, CBitBoard bb ) { std::cout << "\n/* " << rLabel << "\n" << bb.asDiagram() << "*/"; }
// save values of positions in a file // format: // bitboard (white just moved), value (to black), pass flag (0,1,2), best move (for mover) // precondition: no book (unless you want to add these positions to a book) void CalcPosValues(CPlayerComputer* computer, bool fAppend) { FILE* fpCapture, *fpPV; CQPosition pos; CMVK mvk; CMoves moves; int i, quantities[60], pass, nCalced, iAppend; CBitBoard bb; time_t tStart; if (fAppend) { // figure out what number to start on std::string fn(fnBaseDir); fn+=sPVFile; fpPV=fopen(fn.c_str(), "rb"); int result = fseek(fpPV, 0, SEEK_END); int nFileSize=ftell(fpPV); int nRecordSize=sizeof(bb.mover)+sizeof(bb.empty)+ sizeof(mvk.value)+sizeof(pass)+sizeof(mvk.move); if (nFileSize%nRecordSize) { iAppend=0; std::cerr << "Previous .pv file is corrupt, starting again: file size = " << nFileSize << ", record size = " << nRecordSize << ", file size % record size = " << nFileSize%nRecordSize << "\n"; } else { iAppend=nFileSize/nRecordSize; std::cerr << "Appending to previous file with " << iAppend << " elements\n"; } fclose(fpPV); fpPV=NULL; } else iAppend=0; // clear count for (i=0;i<60; i++) quantities[i]=0; std::string fn(fnBaseDir); fn+=fnCapture; fpCapture=fopen(fn.c_str(), "rb"); if (fpCapture) { std::string fn(fnBaseDir); fn+=sPVFile; fpPV=fopen(fn.c_str(), iAppend?"a+bc":"wbc"); if (fpPV) { for (nCalced=0; bb.Read(fpCapture); ) { if (bb.NEmpty()>60) continue; quantities[bb.NEmpty()]++; // print progress if (nCalced%200 == 0) { fflush(fpPV); if (nCalced%10000 == 0) fprintf(stderr, "\nPosition %dk ",nCalced/1000); else fprintf(stderr, "."); } //printf("%d", bb.NEmpty()); if (nCalced>=iAppend) { pos.Initialize(bb,true); pass=pos.CalcMovesAndPass(moves); // if terminal position, calc value if (pass==2) { mvk.value=-pos.TerminalValue(); mvk.move.Set(-1); } // nonterminal position, get value from computer else { tStart=time(0); CSearchInfo si = computer->DefaultSearchInfo(pos.BlackMove(), CSearchInfo::kNeedMove + CSearchInfo::kNeedValue, INFINITE_TIME, 0); computer->GetChosen(si, pos, mvk, true); if (pass==1) mvk.value=-mvk.value; //printf("NEmpty = %2d; value = %4d; move = ",pos.NEmpty(),mvk.value); //mvk.move.Print(); //printf("; pass = %d; time = %2d\n",pass, time(0)-tStart); } // write to file if (!bb.Write(fpPV) || !fwrite(&mvk.value, sizeof(mvk.value), 1, fpPV) || !fwrite(&pass, sizeof(pass), 1, fpPV) || !fwrite(&mvk.move, sizeof(mvk.move), 1, fpPV)) { std::string fn(fnBaseDir); fn+=sPVFile; std::cerr << "can't write to file " << fn << "\n"; assert(0); _exit(1); } } nCalced++; } fclose(fpPV); } fclose(fpCapture); } // print count int sum=0; for (i=0;i<60; i++) { sum+=quantities[i]; printf("%d:%d\n",i,quantities[i]); } printf("%d total positions\n",sum); }
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); }