See More

#include "../tests/tests.h" using namespace TestCommon; void Tests::runBoardIOTests() { cout << "Running board IO tests" << endl; ostringstream out; //============================================================================ { const char* name = "Parse test"; Board board = Board::parseBoard(6,5,R"%%( ABCDEF 5...... 4...... 3...... 2...... 1...... )%%"); Board board2 = Board::parseBoard(6,5,R"%%( A B C D E F 10 . . . . . . 9 . . . . . . 8 . . . . . . 7 . X . . . . 6 . . . . . . )%%"); board.playMove(Location::ofString("B2",board),P_BLACK,true); board2.playMove(Location::ofString("F1",board),P_WHITE,true); out << board << endl; out << board2 << endl; string expected = R"%%( HASH: B9AF12139C31CE252E00CFACD7466195 A B C D E F 5 . . . . . . 4 . . . . . . 3 . . . . . . 2 . X . . . . 1 . . . . . . HASH: FEAC8B83FDFD55B47128913D3E68E748 A B C D E F 5 . . . . . . 4 . . . . . . 3 . . . . . . 2 . X . . . . 1 . . . . . O )%%"; expect(name,out.str(),expected); out.str(""); out.clear(); } } void Tests::runBoardBasicTests() { cout << "Running board basic tests" << endl; ostringstream out; //============================================================================ { const char* name = "Liberties"; Board board = Board::parseBoard(9,9,R"%%( ......... .....x... ..oo..x.. ..x...... ......xx. ..x..ox.. .oxoo.oxx xxoo.o.ox .x.....oo )%%"); out << endl; for(int y = 0; y buf; Board board = Board::parseBoard(9,9,R"%%( xo.x..oxo xoxo..o.. xxo...... ..o.x.... xo..xox.. o..ooxo.. .....xo.. xoox..xo. .xxoo.xxo )%%"); out << endl; for(int y = 0; y buf; vector buf2; Board board = Board::parseBoard(9,9,R"%%( xo.x..oxo xo.o..o.. xxo...... ..o.x.... xo..xo... ...ooxo.. .....xo.. xoox..xo. .xx.o.xxo )%%"); out << endl; for(int y = 0; y buf; vector buf2; Board board = Board::parseBoard(18,9,R"%%( .................. .................. ....ox.......ox... ..xooox....xooox.. ..xoxox....xoxox.. ..xx.x......x.x... ...ox.......ox.... ....o............. .................. )%%"); out << endl; for(int y = 0; y buf; vector buf2; Board board = Board::parseBoard(18,9,R"%%( .............xo.oo ....x........xxooo ...x.xx.......xxo. ..xoxoxo.......xxo ..xoooxo........xx ...xo......o...... .................. .................. .....x.oo......... )%%"); Board board2 = Board::parseBoard(18,9,R"%%( .................. ....x............. ...x.xx........... ..xoxoxo.......... ..xoooxo.......... ...xo......o...... .................x .................. .....x.oo......... )%%"); Board board3 = Board::parseBoard(18,9,R"%%( ....xo.......xo... ....xox......xox.. ...xo.ox....xo.ox. ...xxoox....xxoox. ..xooox....xooox.. .xo.ox....xo.ox... ..xox......xox.... ..xox......xox.... ............o..... )%%"); out << endl; for(int y = 0; y buf; vector buf2; Board board = Board::parseBoard(19,19,R"%%( A B C D E F G H J K L M N O P Q R S T 19 . . . . . . . . . . . . . . . . . . . 18 . . . . . . . . . . . . . . . . . . . 17 . . . . . . . . . . . . . . . . . . . 16 . . . X . . . . . . . . . . . X . . . 15 . . . . . . . . . . . . . . . . . . . 14 . . . . . . . . . . . . . . . . . . . 13 . . . . . . . . . . . . . . . . . . . 12 . . . . . . . . . . . . . . . . . . . 11 . . . . . . . . . . . . . . . . . . . 10 . . . . . . . . . . . . . . . . . . . 9 . . . . . . . . . . . . . . . . . . . 8 . . . . . . . . . . . . . . . . . . . 7 . . . . . . . . . . . . . . . . . . . 6 . . . . . . . . . . . . . . . . . . . 5 . . . . . . . . . . . . . . . . . . . 4 . . . . . . . . . . . . . . X O O . . 3 . . . O . . . . . . . . . . O X X . . 2 . . . . . . . . . . . . . . . . . . . 1 . . . . . . . . . . . . . . . . . . . )%%"); out << endl; for(int y = 0; y buf; vector buf2; Board board = Board::parseBoard(19,19,R"%%( A B C D E F G H J K L M N O P Q R S T 19 . . . . O . . . . . . . . . . . . . . 18 O . . . . . . . . . . . . . . . . . O 17 . . . . . . . . . . . . . . . . . . O 16 . . . O O X O . . . . . . . . . . . . 15 O . . . O X O O O O . O . . . . . O . 14 O X X X X X X X X X O . . . . . . . . 13 X O O O . X . . . . X . . . . . . . O 12 X . O O O X . . . . X O . . . . . . . 11 X O O O O X . . . . X . . . . . . . . 10 O X X X X X X X X X O . . . . . . . O 9 O O . . . X O . . O . . . . . . . . . 8 . O . O . X . O . . . . . . . . . . . 7 . . . . . . O . . . . . . . . . . . . 6 . . . . O . . . . X . . . . . . . . . 5 O . . . . X . . . X . . . X O . . . . 4 . . . . . X . . . X . . . X . . . . . 3 . . . . . X . . . X . . . X . . . . . 2 . . . . O . X X X X X X X O . . . O . 1 . O . . . . O O O O O O O . O . . . . )%%"); out << endl; for(int y = 0; y buf; vector buf2; Board board = Board::parseBoard(19,19,R"%%( A B C D E F G H J K L M N O P Q R S T 19 . . . O O O O O O O O . . . . . O . O 18 X X X . X X X X X . . . O O O O O . O 17 O . . . . . O O . . . . . . . X X X . 16 . . . . . . . O O O . . . . . . O . . 15 O . O . . . . . . . . . . . . . . . . 14 . . O . . . . . . O . . . . . . O . O 13 . . O . . . . . . . X . . . . . O . . 12 . . . . . . . . . O X . . . . . . . . 11 . . . . . . . X . X . O . O . . . . . 10 O X X . . . . . X . O . . . . . . . . 9 O X . . . . . . X O . . . . . . . . . 8 . . X O . . . . . X . . . . . . . . . 7 O . . . X . . . . . . . . . . . . . . 6 . . . . . . . . . . . . . . . . . . . 5 . . . . . . . . . . . . . . . . . . . 4 O . . . . . . . . . . . . . . . O . . 3 . . . . . . . . . X O . . . . . O . . 2 . . . O O . . . . X O X . X . . . X . 1 . . . . . . X . O O O X . X . . O O O )%%"); out << endl; for(int y = 0; y= 0; n--) { board.undo(records[n]); assert(boardsSeemEqual(boards[n],board)); board.checkConsistency(); } delete[] boards; }; run(Board(19,19),true); run(Board(4,4),true); run(Board(4,4),false); ostringstream out; out << endl; out << "regularMoveCount " << regularMoveCount << endl; out << "passCount " << passCount << endl; out << "koCaptureCount " << koCaptureCount << endl; out << "suicideCount " << suicideCount << endl; string expected = R"%%( regularMoveCount 2431 passCount 482 koCaptureCount 25 suicideCount 87 )%%"; expect("Board undo test move counts",out.str(),expected); } void Tests::runBoardStressTest() { cout << "Running board stress test" << endl; Rand rand("runBoardStressTests"); int numBoards = 4; Board boards[numBoards]; boards[0] = Board(); boards[1] = Board(9,16); boards[2] = Board(13,7); boards[3] = Board(4,4); bool multiStoneSuicideLegal[4] = {false,false,true,false}; Board copies[numBoards]; Player pla = C_BLACK; int suicideCount = 0; int koBanCount = 0; int koCaptureCount = 0; int passCount = 0; int regularMoveCount = 0; for(int n = 0; n < 20000; n++) { Loc locs[numBoards]; //Sometimes generate garbage input if(n % 2 == 0) { locs[0] = (Loc)rand.nextInt(-10,500); locs[1] = (Loc)rand.nextInt(-10,250); locs[2] = (Loc)rand.nextInt(-10,200); locs[3] = (Loc)rand.nextInt(-10,50); } //Sometimes select only from empty points, to greatly increase the chance of real moves else { for(int i = 0; i 0); locs[i] = boards[i].empty_list[rand.nextUInt(size)]; } } for(int i = 0; i= Board::MAX_ARR_SIZE || board.colors[loc] != C_EMPTY || board.isIllegalSuicide(loc,pla,multiStoneSuicideLegal[i]) || board.isKoBanned(loc)); if(board.isKoBanned(loc)) { testAssert(board.colors[loc] == C_EMPTY && (board.wouldBeKoCapture(loc,C_BLACK) || board.wouldBeKoCapture(loc,C_WHITE))); koBanCount++; } } } else { if(loc == Board::PASS_LOC) { testAssert(boardsSeemEqual(copy,board)); testAssert(board.ko_loc == Board::NULL_LOC); passCount++; } else if(copy.isSuicide(loc,pla)) { testAssert(board.colors[loc] == C_EMPTY); testAssert(board.isLegal(loc,pla,multiStoneSuicideLegal[i])); testAssert(multiStoneSuicideLegal[i]); suicideCount++; } else { testAssert(board.colors[loc] == pla); testAssert(board.getNumLiberties(loc) == copy.getNumLibertiesAfterPlay(loc,pla,1000)); testAssert(std::min(2,board.getNumLiberties(loc)) == copy.getNumLibertiesAfterPlay(loc,pla,2)); testAssert(std::min(4,board.getNumLiberties(loc)) == copy.getNumLibertiesAfterPlay(loc,pla,4)); if(board.ko_loc != Board::NULL_LOC) { koCaptureCount++; testAssert(copy.wouldBeKoCapture(loc,pla)); } else testAssert(!copy.wouldBeKoCapture(loc,pla)); regularMoveCount++; } } } pla = rand.nextUInt(2) == 0 ? getOpp(pla) : pla; } ostringstream out; out << endl; out << "regularMoveCount " << regularMoveCount << endl; out << "passCount " << passCount << endl; out << "koCaptureCount " << koCaptureCount << endl; out << "koBanCount " << koBanCount << endl; out << "suicideCount " << suicideCount << endl; for(int i = 0; i<4; i++) out << "Caps " << boards[i].numBlackCaptures << " " << boards[i].numWhiteCaptures << endl; string expected = R"%%( regularMoveCount 37692 passCount 280 koCaptureCount 164 koBanCount 25 suicideCount 445 Caps 4862 4732 Caps 4590 4745 Caps 4890 5071 Caps 4364 4393 )%%"; expect("Board stress test move counts",out.str(),expected); }