// File: ATOMIC-LICHESS[P]ATOMKRAFT/book.cpp
// Function: Book::get_move(Position const&, bool)
Move Book::get_move(const Position& pos, bool findBestMove) {

  if (!bookFile.is_open() || bookSize == 0)
      return MOVE_NONE;
  

  BookEntry entry;
  int bookMove = MOVE_NONE;
  unsigned score, scoresSum = 0, bestScore = 0;
  uint64_t key = book_key(pos);
  
  // Choose a book move among the possible moves for the given position
  for (int idx = find_entry(key); idx < bookSize; idx++)
  {
      entry = read_entry(idx);
      

      if (entry.key != key)
          break;

      score = entry.count;
      
      NEW // skip moves with non positive score
      NEW if (score <= 0) continue;
      
      
      if (!findBestMove)
      {
          // Choose book move according to its score. If a move has a very
          // high score it has more probability to be choosen then a one with
          // lower score. Note that first entry is always chosen.
          scoresSum += score;
          if (RKiss.rand<unsigned>() % scoresSum < score)
              bookMove = entry.move;
      }
      else if (score > bestScore)
      {
          bestScore = score;
          bookMove = entry.move;
      }
  }

  // A PolyGlot book move is encoded as follows:
  //
  // bit  0- 5: destination square (from 0 to 63)
  // bit  6-11: origin square (from 0 to 63)
  // bit 12-13-14: promotion piece (from KNIGHT == 1 to QUEEN == 4)
  //
  // Castling moves follow "king captures rook" representation. So in case
  // book move is a promotion we have to convert to our representation, in
  // all other cases we can directly compare with a Move after having
  // masked out special Move's flags that are not supported by PolyGlot.
  int p = (bookMove >> 12) & 7;

  if (p)
      bookMove = int(make_promotion_move(move_from(Move(bookMove)),
                 move_to(Move(bookMove)), PieceType(p + 1)));

  // Verify the book move (if any) is legal
  MoveStack mlist[MAX_MOVES];
  MoveStack* last = generate<MV_LEGAL>(pos, mlist);
  for (MoveStack* cur = mlist; cur != last; cur++)
      if ((int(cur->move) & ~(3 << 14)) == bookMove) // Mask out special flags
          return cur->move;

  return MOVE_NONE;
}

// Assembly:
subq $0x888, %rsp            # imm = 0x888
movb %dl, %al
movq %rdi, 0x878(%rsp)
movq %rsi, 0x870(%rsp)
andb $0x1, %al
movb %al, 0x86f(%rsp)
movq 0x878(%rsp), %rdi
movq %rdi, 0x8(%rsp)
callq 0x6930
testb $0x1, %al
jne 0xee1a
jmp 0xee28
movq 0x8(%rsp), %rax
cmpl $0x0, 0x230(%rax)
jne 0xee38
movl $0x0, 0x884(%rsp)
jmp 0xf074
movl $0x0, 0x854(%rsp)
movl $0x0, 0x84c(%rsp)
movl $0x0, 0x848(%rsp)
movq 0x870(%rsp), %rdi
callq 0xe9e0
movq 0x8(%rsp), %rdi
movq %rax, 0x840(%rsp)
movq 0x840(%rsp), %rsi
callq 0xf090
movl %eax, 0x83c(%rsp)
movq 0x8(%rsp), %rcx
movl 0x83c(%rsp), %eax
cmpl 0x230(%rcx), %eax
jge 0xefaf
movq 0x8(%rsp), %rdi
movl 0x83c(%rsp), %esi
callq 0xf170
movq %rax, 0x828(%rsp)
movq %rdx, 0x830(%rsp)
movq 0x828(%rsp), %rax
movq %rax, 0x858(%rsp)
movq 0x830(%rsp), %rax
movq %rax, 0x860(%rsp)
movq 0x858(%rsp), %rax
cmpq 0x840(%rsp), %rax
je 0xeef7
jmp 0xefaf
movzwl 0x862(%rsp), %eax
movl %eax, 0x850(%rsp)
cmpl $0x0, 0x850(%rsp)
ja 0xef15
jmp 0xef99
testb $0x1, 0x86f(%rsp)
jne 0xef68
movq 0x8(%rsp), %rdi
movl 0x850(%rsp), %eax
addl 0x84c(%rsp), %eax
movl %eax, 0x84c(%rsp)
addq $0x238, %rdi            # imm = 0x238
callq 0xf600
xorl %edx, %edx
divl 0x84c(%rsp)
cmpl 0x850(%rsp), %edx
jae 0xef66
movzwl 0x860(%rsp), %eax
movl %eax, 0x854(%rsp)
jmp 0xef97
movl 0x850(%rsp), %eax
cmpl 0x848(%rsp), %eax
jbe 0xef95
movl 0x850(%rsp), %eax
movl %eax, 0x848(%rsp)
movzwl 0x860(%rsp), %eax
movl %eax, 0x854(%rsp)
jmp 0xef97
jmp 0xef99
movl 0x83c(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x83c(%rsp)
jmp 0xee87
movl 0x854(%rsp), %eax
sarl $0xc, %eax
andl $0x7, %eax
movl %eax, 0x824(%rsp)
cmpl $0x0, 0x824(%rsp)
je 0xf005
movl 0x854(%rsp), %edi
callq 0xf680
movl %eax, 0x4(%rsp)
movl 0x854(%rsp), %edi
callq 0xf690
movl 0x4(%rsp), %edi
movl %eax, %esi
movl 0x824(%rsp), %edx
addl $0x1, %edx
callq 0xf650
movl %eax, 0x854(%rsp)
movq 0x870(%rsp), %rdi
leaq 0x20(%rsp), %rsi
callq 0x30420
movq %rax, 0x18(%rsp)
leaq 0x20(%rsp), %rax
movq %rax, 0x10(%rsp)
movq 0x10(%rsp), %rax
cmpq 0x18(%rsp), %rax
je 0xf069
movq 0x10(%rsp), %rax
movl (%rax), %eax
andl $0xffff3fff, %eax       # imm = 0xFFFF3FFF
cmpl 0x854(%rsp), %eax
jne 0xf057
movq 0x10(%rsp), %rax
movl (%rax), %eax
movl %eax, 0x884(%rsp)
jmp 0xf074
jmp 0xf059
movq 0x10(%rsp), %rax
addq $0x8, %rax
movq %rax, 0x10(%rsp)
jmp 0xf026
movl $0x0, 0x884(%rsp)
movl 0x884(%rsp), %eax
addq $0x888, %rsp            # imm = 0x888
retq
nopw %cs:(%rax,%rax)