-namespace {
-
- void KPKPosition::from_index(int index) {
- int s;
- sideToMove = Color(index % 2);
- blackKingSquare = Square((index / 2) % 64);
- whiteKingSquare = Square((index / 128) % 64);
- s = (index / 8192) % 24;
- pawnSquare = make_square(File(s % 4), Rank(s / 4 + 1));
- }
-
-
- int KPKPosition::to_index() const {
- return compute_index(whiteKingSquare, blackKingSquare, pawnSquare,
- sideToMove);
- }
-
-
- bool KPKPosition::is_legal() const {
- if(whiteKingSquare == pawnSquare || whiteKingSquare == blackKingSquare ||
- pawnSquare == blackKingSquare)
- return false;
- if(sideToMove == WHITE) {
- if(bit_is_set(this->wk_attacks(), blackKingSquare))
- return false;
- if(bit_is_set(this->pawn_attacks(), blackKingSquare))
- return false;
- }
- else {
- if(bit_is_set(this->bk_attacks(), whiteKingSquare))
- return false;
- }
- return true;
- }
-
-
- bool KPKPosition::is_immediate_draw() const {
- if(sideToMove == BLACK) {
- Bitboard wka = this->wk_attacks();
- Bitboard bka = this->bk_attacks();
-
- // Case 1: Stalemate
- if((bka & ~(wka | this->pawn_attacks())) == EmptyBoardBB)
- return true;
-
- // Case 2: King can capture pawn
- if(bit_is_set(bka, pawnSquare) && !bit_is_set(wka, pawnSquare))
- return true;
- }
- else {
- // Case 1: Stalemate
- if(whiteKingSquare == SQ_A8 && pawnSquare == SQ_A7 &&
- (blackKingSquare == SQ_C7 || blackKingSquare == SQ_C8))
- return true;
- }
-
- return false;
- }
-
-
- bool KPKPosition::is_immediate_win() const {
- // The position is an immediate win if it is white to move and the white
- // pawn can be promoted without getting captured:
- return
- sideToMove == WHITE &&
- square_rank(pawnSquare) == RANK_7 &&
- (square_distance(blackKingSquare, pawnSquare+DELTA_N) > 1 ||
- bit_is_set(this->wk_attacks(), pawnSquare+DELTA_N));
- }
-
-
- Bitboard KPKPosition::wk_attacks() const {
- return StepAttackBB[WK][whiteKingSquare];
- }
-
-
- Bitboard KPKPosition::bk_attacks() const {
- return StepAttackBB[BK][blackKingSquare];
- }
-
-
- Bitboard KPKPosition::pawn_attacks() const {
- return StepAttackBB[WP][pawnSquare];
- }
-
-
- void initialize() {
- KPKPosition p;
- for(int i = 0; i < IndexMax; i++) {
- p.from_index(i);
- if(!p.is_legal())
- Bitbase[i] = RESULT_INVALID;
- else if(p.is_immediate_draw())
- Bitbase[i] = RESULT_DRAW;
- else if(p.is_immediate_win())
- Bitbase[i] = RESULT_WIN;
- else {
- Bitbase[i] = RESULT_UNKNOWN;
- UnknownCount++;
- }
- }
- }
-
-
- bool next_iteration() {
- KPKPosition p;
- int previousUnknownCount = UnknownCount;
-
- for(int i = 0; i < IndexMax; i++)
- if(Bitbase[i] == RESULT_UNKNOWN) {
- p.from_index(i);
-
- Bitbase[i] = (p.sideToMove == WHITE)? classify_wtm(p) : classify_btm(p);
-
- if(Bitbase[i] == RESULT_WIN || Bitbase[i] == RESULT_LOSS ||
- Bitbase[i] == RESULT_DRAW)
- UnknownCount--;
- }
-
- return UnknownCount != previousUnknownCount;
- }
-