- int compute_index(Square wksq, Square bksq, Square wpsq, Color stm) {
-
- int p = int(square_file(wpsq)) + (int(square_rank(wpsq)) - 1) * 4;
- int r = int(stm) + 2 * int(bksq) + 128 * int(wksq) + 8192 * p;
-
- assert(r >= 0 && r < IndexMax);
-
- return r;
- }
-
- void KPKPosition::from_index(int index) {
-
- int s = (index / 8192) % 24;
-
- sideToMove = Color(index % 2);
- blackKingSquare = Square((index / 2) % 64);
- whiteKingSquare = Square((index / 128) % 64);
- pawnSquare = make_square(File(s % 4), Rank(s / 4 + 1));
- }
-
- bool KPKPosition::is_legal() const {
-
- if ( whiteKingSquare == pawnSquare
- || whiteKingSquare == blackKingSquare
- || pawnSquare == blackKingSquare)
- return false;
-
- if (sideToMove == WHITE)
- {
- if ( bit_is_set(wk_attacks(), blackKingSquare)
- || bit_is_set(pawn_attacks(), blackKingSquare))
- return false;
- }
- else if (bit_is_set(bk_attacks(), whiteKingSquare))
- return false;
-
- return true;
- }
-
- bool KPKPosition::is_immediate_draw() const {
-
- if (sideToMove == BLACK)
- {
- Bitboard wka = wk_attacks();
- Bitboard bka = bk_attacks();
-
- // Case 1: Stalemate
- if ((bka & ~(wka | pawn_attacks())) == EmptyBoardBB)
- return true;
-
- // Case 2: King can capture pawn
- if (bit_is_set(bka, pawnSquare) && !bit_is_set(wka, pawnSquare))
- return true;
- }
+ KPKPosition::KPKPosition(unsigned idx) {
+
+ ksq[WHITE] = Square((idx >> 0) & 0x3F);
+ ksq[BLACK] = Square((idx >> 6) & 0x3F);
+ us = Color ((idx >> 12) & 0x01);
+ psq = make_square(File((idx >> 13) & 0x3), RANK_7 - Rank((idx >> 15) & 0x7));
+
+ // Check if two pieces are on the same square or if a king can be captured
+ if ( distance(ksq[WHITE], ksq[BLACK]) <= 1
+ || ksq[WHITE] == psq
+ || ksq[BLACK] == psq
+ || (us == WHITE && (StepAttacksBB[PAWN][psq] & ksq[BLACK])))
+ result = INVALID;
+
+ // Immediate win if a pawn can be promoted without getting captured
+ else if ( us == WHITE
+ && rank_of(psq) == RANK_7
+ && ksq[us] != psq + DELTA_N
+ && ( distance(ksq[~us], psq + DELTA_N) > 1
+ || (StepAttacksBB[KING][ksq[us]] & (psq + DELTA_N))))
+ result = WIN;
+
+ // Immediate draw if it is a stalemate or a king captures undefended pawn
+ else if ( us == BLACK
+ && ( !(StepAttacksBB[KING][ksq[us]] & ~(StepAttacksBB[KING][ksq[~us]] | StepAttacksBB[PAWN][psq]))
+ || (StepAttacksBB[KING][ksq[us]] & psq & ~StepAttacksBB[KING][ksq[~us]])))
+ result = DRAW;
+
+ // Position will be classified later