// File: /workspace/github_cpp_makefile_star2_O2/ATOMIC-LICHESS[P]ATOMKRAFT/endgame.cpp
// Function: Endgame<Value, (EndgameType)3>::apply(Position const&) const
Value Endgame<Value, KRKP>::apply(const Position& pos) const {

  assert(pos.non_pawn_material(strongerSide) == RookValueMidgame);
  assert(pos.piece_count(strongerSide, PAWN) == 0);
  assert(pos.non_pawn_material(weakerSide) == 0);
  assert(pos.piece_count(weakerSide, PAWN) == 1);

  Square wksq, wrsq, bksq, bpsq;
  int tempo = (pos.side_to_move() == strongerSide);

  wksq = pos.king_square(strongerSide);
  wrsq = pos.piece_list(strongerSide, ROOK, 0);
  bksq = pos.king_square(weakerSide);
  bpsq = pos.piece_list(weakerSide, PAWN, 0);

  if (strongerSide == BLACK)
  {
      wksq = flip_square(wksq);
      wrsq = flip_square(wrsq);
      bksq = flip_square(bksq);
      bpsq = flip_square(bpsq);
  }

  Square queeningSq = make_square(square_file(bpsq), RANK_1);
  Value result;

  // If the stronger side's king is in front of the pawn, it's a win
  if (wksq < bpsq && square_file(wksq) == square_file(bpsq))
      result = RookValueEndgame - Value(square_distance(wksq, bpsq));

  // If the weaker side's king is too far from the pawn and the rook,
  // it's a win
  else if (   square_distance(bksq, bpsq) - (tempo ^ 1) >= 3
           && square_distance(bksq, wrsq) >= 3)
      result = RookValueEndgame - Value(square_distance(wksq, bpsq));

  // If the pawn is far advanced and supported by the defending king,
  // the position is drawish
  else if (   square_rank(bksq) <= RANK_3
           && square_distance(bksq, bpsq) == 1
           && square_rank(wksq) >= RANK_4
           && square_distance(wksq, bpsq) - tempo > 2)
      result = Value(80 - square_distance(wksq, bpsq) * 8);

  else
      result =  Value(200)
              - Value(square_distance(wksq, bpsq + DELTA_S) * 8)
              + Value(square_distance(bksq, bpsq + DELTA_S) * 8)
              + Value(square_distance(bpsq, queeningSq) * 8);

  return strongerSide == pos.side_to_move() ? result : -result;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x18, %rsp
movq %rsi, %rbx
movl 0x8(%rdi), %ecx
movq %rdi, 0x10(%rsp)
movl 0xc(%rdi), %edx
xorl %r14d, %r14d
cmpl %ecx, 0x1090(%rsi)
sete %al
movq %rcx, %rsi
shlq $0x9, %rsi
movl 0x290(%rbx,%rsi), %edi
movl 0x310(%rbx,%rsi), %ebp
shlq $0x9, %rdx
movl 0x1d0(%rbx,%rdx), %r15d
movl 0x310(%rbx,%rdx), %r12d
cmpl $0x1, %ecx
jne 0xb460
xorl $0x38, %ebp
xorl $0x38, %edi
xorl $0x38, %r12d
xorl $0x38, %r15d
movl %r15d, %r13d
andl $0x7, %r13d
cmpl %r15d, %ebp
jge 0xb492
movl %ebp, %ecx
andl $0x7, %ecx
cmpl %r13d, %ecx
jne 0xb492
leaq 0x29fe7(%rip), %rax     # 0x35464
movl (%rax), %r14d
movl %ebp, %edi
movl %r15d, %esi
callq 0x75ec
subl %eax, %r14d
jmp 0xb53e
movl %edi, 0xc(%rsp)
movb %al, %r14b
movl %r12d, %edi
movl %r15d, %esi
callq 0x75ec
movl %r14d, 0x8(%rsp)
xorl $0x1, %r14d
subl %r14d, %eax
cmpl $0x3, %eax
jl 0xb4c6
movl %r12d, %edi
movl 0xc(%rsp), %esi
callq 0x75ec
cmpl $0x3, %eax
jge 0xb476
cmpl $0x17, %r12d
jg 0xb507
movl %r12d, %edi
movl %r15d, %esi
callq 0x75ec
cmpl $0x18, %ebp
jl 0xb507
cmpl $0x1, %eax
jne 0xb507
movl %ebp, %edi
movl %r15d, %esi
callq 0x75ec
subl 0x8(%rsp), %eax
cmpl $0x3, %eax
jl 0xb507
movl %ebp, %edi
movl %r15d, %esi
callq 0x75ec
shll $0x3, %eax
pushq $0x50
popq %r14
jmp 0xb48a
leal -0x8(%r15), %r14d
movl %ebp, %edi
movl %r14d, %esi
callq 0x75ec
movl %eax, %ebp
movl %r12d, %edi
movl %r14d, %esi
callq 0x75ec
movl %eax, %r14d
subl %ebp, %r14d
movl %r15d, %edi
movl %r13d, %esi
callq 0x75ec
addl %r14d, %eax
leal 0xc8(,%rax,8), %r14d
movq 0x10(%rsp), %rax
movl 0x8(%rax), %ecx
movl %r14d, %eax
negl %eax
cmpl 0x1090(%rbx), %ecx
cmovel %r14d, %eax
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq