void testOsGame() { COsGame game; std::istringstream inStream("(;GM[Othello]PC[GGS/os]DT[2003.12.15_12:33:18.MST]PB[Saio1200]PW[Saio3000]RE[0]RB[2196.37]RW[2200.35]TI[5:00//2:00]TY[8]BO[8 --O--O--*-*OO---****OO-**O*O*OOO**O***O****O*O*---**O*----****-- O];)"); game.In(inStream); assertStringEquals("2003.12.15_12:33:18.MST", game.sDateTime); assertBoolEquals(false, game.GetPos().board.fBlackMove); }
void testOsGameResult() { COsGame game; std::istringstream inStream("(;GM[Othello]PC[Local]DT[2013-12-23 16:43:43 GMT]PB[s33]PW[s30]RE[2]TI[0//2:00]TY[0]BO[8 ---------------------------O*------*O--------------------------- *]B[F5/-1.04/0.01]W[D6//0.01]B[C3/-1.14/0.01]W[D3//0.01]B[C4/-1.14/0.01]W[F4//0.01]B[F6/-1.14/0.01]W[F3//0.01]B[E6/-1.14/0.01]W[E7//0.01]B[D7/-1.14/0.01]W[G6//0.02]B[G5/-1.14/0.01]W[C5/5.92/0.01]B[B6/-0.41/857.59]W[C6/5.92/0.01]B[B5/-1.99/15694.44]W[C7/5.92/0.01]B[F8//5207.92]W[E8/5.99/0.01]B[F7//0.03]W[H6/5.99/0.01]B[D2//5042.51]W[G4/7.99/0.01]B[C8/-1.00/1070.74]W[B3/7.99/0.01]B[B4/-1.00/30471.05]W[A5/102.00/0.01]B[D8/-1.00/0.30]W[E2/102.00/0.01]B[E3/-2.00/643.47]W[A4/102.00/0.01]B[F1/-2.00/0.03]W[F2/102.00/0.01]B[A6/-2.00/4.74]W[A7/102.00/0.01]B[H3/-2.00/1.07]W[H5/102.00/0.01]B[H4/-2.00/0.11]W[H2/102.00/0.01]B[G7/-2.00/0.09]W[B7/2.00/0.18]B[A8/-2.00/0.03]W[E1/2.00/0.02]B[G3/-2.00/0.03]W[G1/2.00/0.02]B[C1/-2.00/0.02]W[B8/2.00/0.02]B[C2/-2.00/0.02]W[H8/2.00/0.02]B[H7/-2.00/0.02]W[D1/2.00/0.01]B[A3/-2.00/0.01]W[B1/2.00/0.01]B[H1/-2.00/0.01]W[G8/2.00/0.01]B[A1//0.00]W[B2/2.00/0.01]B[A2//0.00]W[G2//0.00];)"); game.In(inStream); COsGame game2; game2.SetDefaultStartPos(8); for (auto mli: game.ml) { game2.Update(mli); } const COsBoard board = game2.GetPos().board; assertEquals(-2.0, game2.Result().dResult, 0.001); std::ostringstream out; out << game2; assertTrue(strstr(out.str().c_str(), "RE[-2]")!=NULL); }
CPlayer::TCheatcode CPlayerHuman::GetMove(COsGame& game, int flags, CSGMoveListItem& mli) { CMoves moves; string sInput; CSGSquare sq; while (flags&kMyMove) { // input and convert to lowercase cout << "Please enter next move: "; cin >> sInput; for(std::size_t i=0; i<sInput.length(); i++) { sInput[i]=tolower(sInput[i]); } // make a move? if (sInput.length()>=2 && isalpha(sInput[0]) && isdigit(sInput[1])) { if (game.pos.board.IsMoveLegal(sInput)) { mli.mv=CSGSquare(sInput); break; } else cout << "'" << sInput << "' is not a valid move.\n"; } // pass? else if(!strncmp(sInput.c_str(),"pa",2)) { if (!game.pos.board.HasLegalMove()) { mli.mv="PA"; break; } else cout << "You have a valid move, you can't pass.\n"; } // cheat code ? else { if (sInput=="save") { Save(game); } else if (flags&kAllowCheats) { if (sInput=="load") { Load(game); //return kCheatContinue; } else if (sInput=="undo") { return kCheatUndo; } else if (sInput=="ap") { return kCheatAutoplay; } else if (sInput=="switch") { return kCheatSwitch; } else if (sInput=="play") { string sLine; getline(cin, sLine); istrstream is(sLine.c_str()); CSGMoveListItem mli; while ((is >> mli)) { if (game.pos.board.IsMoveLegal(mli.mv)) game.Update(mli); else { cout << "Play sequence terminated at illegal move " << mli.mv << "\n"; break; } } return kCheatContinue; } else if (sInput=="?"|| sInput=="help") { cout << "Current cheat codes:\n"; cout << " save filename: save the current position as filename\n"; cout << " load filename: load the current position as filename\n"; cout << " ap: have opponent autoplay the remainder of the game\n"; cout << " switch: switch sides in game\n"; cout << " play <move>*: force a sequence of moves to be played\n"; cout << " undo: undo your last move\n"; cout << "\n"; } } else
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); }