#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);
}