| 331 | namespace Database { |
| 332 | |
| 333 | DBKey constructDBKey(const Board &board, Rule rule, TransformType *transType) |
| 334 | { |
| 335 | DBKey key[TRANS_NB]; |
| 336 | StonePos whiteStones[TRANS_NB][MAX_MOVES]; |
| 337 | for (int trans = IDENTITY; trans < TRANS_NB; trans++) { |
| 338 | key[trans].rule = rule; |
| 339 | key[trans].boardWidth = board.size(); |
| 340 | key[trans].boardHeight = board.size(); |
| 341 | key[trans].sideToMove = board.sideToMove(); |
| 342 | key[trans].numBlackStones = 0; |
| 343 | key[trans].numWhiteStones = 0; |
| 344 | } |
| 345 | |
| 346 | for (int ply = 0; ply < board.ply(); ply++) { |
| 347 | Pos move = board.getHistoryMove(ply); |
| 348 | if (move == Pos::PASS) |
| 349 | continue; |
| 350 | |
| 351 | Color c = board.cell(move).piece; |
| 352 | if (c == BLACK) { |
| 353 | for (int trans = IDENTITY; trans < TRANS_NB; trans++) { |
| 354 | Pos transformedPos = applyTransform(move, board.size(), (TransformType)trans); |
| 355 | key[trans].stones[key[trans].numBlackStones++] = {transformedPos.x(), |
| 356 | transformedPos.y()}; |
| 357 | } |
| 358 | } |
| 359 | else if (c == WHITE) { |
| 360 | for (int trans = IDENTITY; trans < TRANS_NB; trans++) { |
| 361 | Pos transformedPos = applyTransform(move, board.size(), (TransformType)trans); |
| 362 | whiteStones[trans][key[trans].numWhiteStones++] = {transformedPos.x(), |
| 363 | transformedPos.y()}; |
| 364 | } |
| 365 | } |
| 366 | } |
| 367 | |
| 368 | // Construct 8 symmetry database keys, and find the smallest one |
| 369 | int smallestIndex = 0; |
| 370 | |
| 371 | for (int trans = IDENTITY; trans < TRANS_NB; trans++) { |
| 372 | std::sort(key[trans].stones, |
| 373 | key[trans].stones + key[trans].numBlackStones, |
| 374 | std::less<StonePos>()); |
| 375 | std::copy(whiteStones[trans], |
| 376 | whiteStones[trans] + key[trans].numWhiteStones, |
| 377 | key[trans].stones + key[trans].numBlackStones); |
| 378 | std::sort(key[trans].stones + key[trans].numBlackStones, |
| 379 | key[trans].stones + key[trans].numBlackStones + key[trans].numWhiteStones, |
| 380 | std::less<StonePos>()); |
| 381 | |
| 382 | if (trans != smallestIndex && key[trans] < key[smallestIndex]) |
| 383 | smallestIndex = trans; |
| 384 | } |
| 385 | |
| 386 | if (transType) |
| 387 | *transType = static_cast<TransformType>(smallestIndex); |
| 388 | |
| 389 | return key[smallestIndex]; |
| 390 | } |
no test coverage detected