// File: /workspace/github_cpp_makefile_star2_O1/ATOMIC-LICHESS[P]ATOMKRAFT/endgame.cpp
// Function: Endgame<ScaleFactor, (EndgameType)12>::apply(Position const&) const
ScaleFactor Endgame<ScaleFactor, KRPKR>::apply(const Position& pos) const {

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

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

  // Orient the board in such a way that the stronger side is white, and the
  // pawn is on the left half of the board.
  if (strongerSide == BLACK)
  {
      wksq = flip_square(wksq);
      wrsq = flip_square(wrsq);
      wpsq = flip_square(wpsq);
      bksq = flip_square(bksq);
      brsq = flip_square(brsq);
  }
  if (square_file(wpsq) > FILE_D)
  {
      wksq = flop_square(wksq);
      wrsq = flop_square(wrsq);
      wpsq = flop_square(wpsq);
      bksq = flop_square(bksq);
      brsq = flop_square(brsq);
  }

  File f = square_file(wpsq);
  Rank r = square_rank(wpsq);
  Square queeningSq = make_square(f, RANK_8);
  int tempo = (pos.side_to_move() == strongerSide);

  // If the pawn is not too far advanced and the defending king defends the
  // queening square, use the third-rank defence.
  if (   r <= RANK_5
      && square_distance(bksq, queeningSq) <= 1
      && wksq <= SQ_H5
      && (square_rank(brsq) == RANK_6 || (r <= RANK_3 && square_rank(wrsq) != RANK_6)))
      return SCALE_FACTOR_ZERO;

  // The defending side saves a draw by checking from behind in case the pawn
  // has advanced to the 6th rank with the king behind.
  if (   r == RANK_6
      && square_distance(bksq, queeningSq) <= 1
      && square_rank(wksq) + tempo <= RANK_6
      && (square_rank(brsq) == RANK_1 || (!tempo && abs(square_file(brsq) - f) >= 3)))
      return SCALE_FACTOR_ZERO;

  if (   r >= RANK_6
      && bksq == queeningSq
      && square_rank(brsq) == RANK_1
      && (!tempo || square_distance(wksq, wpsq) >= 2))
      return SCALE_FACTOR_ZERO;

  // White pawn on a7 and rook on a8 is a draw if black's king is on g7 or h7
  // and the black rook is behind the pawn.
  if (   wpsq == SQ_A7
      && wrsq == SQ_A8
      && (bksq == SQ_H7 || bksq == SQ_G7)
      && square_file(brsq) == FILE_A
      && (square_rank(brsq) <= RANK_3 || square_file(wksq) >= FILE_D || square_rank(wksq) <= RANK_5))
      return SCALE_FACTOR_ZERO;

  // If the defending king blocks the pawn and the attacking king is too far
  // away, it's a draw.
  if (   r <= RANK_5
      && bksq == wpsq + DELTA_N
      && square_distance(wksq, wpsq) - tempo >= 2
      && square_distance(wksq, brsq) - tempo >= 2)
      return SCALE_FACTOR_ZERO;

  // Pawn on the 7th rank supported by the rook from behind usually wins if the
  // attacking king is closer to the queening square than the defending king,
  // and the defending king cannot gain tempi by threatening the attacking rook.
  if (   r == RANK_7
      && f != FILE_A
      && square_file(wrsq) == f
      && wrsq != queeningSq
      && (square_distance(wksq, queeningSq) < square_distance(bksq, queeningSq) - 2 + tempo)
      && (square_distance(wksq, queeningSq) < square_distance(bksq, wrsq) + tempo))
      return ScaleFactor(SCALE_FACTOR_MAX - 2 * square_distance(wksq, queeningSq));

  // Similar to the above, but with the pawn further back
  if (   f != FILE_A
      && square_file(wrsq) == f
      && wrsq < wpsq
      && (square_distance(wksq, queeningSq) < square_distance(bksq, queeningSq) - 2 + tempo)
      && (square_distance(wksq, wpsq + DELTA_N) < square_distance(bksq, wpsq + DELTA_N) - 2 + tempo)
      && (  square_distance(bksq, wrsq) + tempo >= 3
          || (    square_distance(wksq, queeningSq) < square_distance(bksq, wrsq) + tempo
              && (square_distance(wksq, wpsq + DELTA_N) < square_distance(bksq, wrsq) + tempo))))
      return ScaleFactor(  SCALE_FACTOR_MAX
                         - 8 * square_distance(wpsq, queeningSq)
                         - 2 * square_distance(wksq, queeningSq));

  // If the pawn is not far advanced, and the defending king is somewhere in
  // the pawn's path, it's probably a draw.
  if (r <= RANK_4 && bksq > wpsq)
  {
      if (square_file(bksq) == square_file(wpsq))
          return ScaleFactor(10);
      if (   abs(square_file(bksq) - square_file(wpsq)) == 1
          && square_distance(wksq, bksq) > 2)
          return ScaleFactor(24 - 2 * square_distance(wksq, bksq));
  }
  return SCALE_FACTOR_NONE;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
movl 0x8(%rdi), %ebx
movl 0xc(%rdi), %eax
movq %rbx, %rdx
shlq $0x9, %rdx
shlq $0x9, %rax
movl 0x310(%rsi,%rdx), %r8d
movl 0x1d0(%rsi,%rdx), %edi
movl 0x290(%rsi,%rdx), %r13d
movl 0x290(%rsi,%rax), %r11d
movl 0x310(%rsi,%rax), %edx
cmpq $0x1, %rbx
jne 0xc417
xorl $0x38, %r8d
xorl $0x38, %r13d
xorl $0x38, %edi
xorl $0x38, %edx
xorl $0x38, %r11d
testb $0x4, %dil
je 0xc42f
xorl $0x7, %r8d
xorl $0x7, %r13d
xorl $0x7, %edi
xorl $0x7, %edx
xorl $0x7, %r11d
movl %edi, %r9d
andl $0x7, %r9d
movl %edi, %r10d
sarl $0x3, %r10d
movl 0x1090(%rsi), %r14d
xorl %esi, %esi
cmpl %ebx, %r14d
sete %bpl
cmpl $0x4, %r10d
jg 0xc4b5
movl %edx, %eax
andl $0x7, %eax
subl %r9d, %eax
movl %eax, %r15d
negl %r15d
cmovsl %eax, %r15d
movl %edx, %r12d
sarl $0x3, %r12d
addl $-0x7, %r12d
movl %r12d, %eax
negl %eax
cmovsl %r12d, %eax
cmpl %eax, %r15d
cmoval %r15d, %eax
cmpl $0x27, %r8d
jg 0xc4b5
cmpl $0x1, %eax
ja 0xc4b5
movl %r11d, %r15d
andl $-0x8, %r15d
xorl %eax, %eax
cmpl $0x28, %r15d
je 0xc8ca
cmpl $0x2, %r10d
jg 0xc4b5
movl %r13d, %r15d
andl $-0x8, %r15d
cmpl $0x28, %r15d
jne 0xc8ca
movb %bpl, %sil
cmpl $0x5, %r10d
jne 0xc527
movl %edx, %eax
andl $0x7, %eax
subl %r9d, %eax
movl %eax, %ebp
negl %ebp
cmovsl %eax, %ebp
movl %edx, %eax
sarl $0x3, %eax
addl $-0x7, %eax
movl %eax, %r15d
negl %r15d
cmovsl %eax, %r15d
cmpl %r15d, %ebp
cmoval %ebp, %r15d
cmpl $0x1, %r15d
ja 0xc527
movl %r8d, %eax
sarl $0x3, %eax
addl %esi, %eax
cmpl $0x5, %eax
jg 0xc527
xorl %eax, %eax
cmpl $0x8, %r11d
jb 0xc8ca
cmpl %ebx, %r14d
je 0xc527
movl %r11d, %ebp
andl $0x7, %ebp
subl %r9d, %ebp
movl %ebp, %r15d
negl %r15d
cmovsl %ebp, %r15d
cmpl $0x2, %r15d
ja 0xc8ca
leal 0x38(%r9), %ebp
cmpl $0x5, %r10d
jl 0xc57d
cmpl %ebp, %edx
jne 0xc57d
cmpl $0x7, %r11d
ja 0xc57d
xorl %eax, %eax
cmpl %ebx, %r14d
jne 0xc8ca
movl %r8d, %ebx
andl $0x7, %ebx
subl %r9d, %ebx
movl %ebx, %r14d
negl %r14d
cmovsl %ebx, %r14d
movl %r8d, %ebx
sarl $0x3, %ebx
subl %r10d, %ebx
movl %ebx, %r15d
negl %r15d
cmovsl %ebx, %r15d
cmpl %r15d, %r14d
cmoval %r14d, %r15d
cmpl $0x1, %r15d
ja 0xc8ca
movl %edx, %eax
andl $-0x2, %eax
movl %r11d, %r14d
andl $0x7, %r14d
cmpl $0x36, %eax
jne 0xc5c3
cmpl $0x30, %edi
jne 0xc5c3
cmpl $0x38, %r13d
jne 0xc5c3
testl %r14d, %r14d
jne 0xc5c3
xorl %eax, %eax
cmpl $0x11, %r11d
jl 0xc8ca
cmpl $0x28, %r8d
jl 0xc8ca
movl %r8d, %ebx
andl $0x7, %ebx
cmpl $0x2, %ebx
ja 0xc8ca
leal 0x8(%rdi), %ebx
cmpl $0x4, %r10d
jg 0xc652
cmpl %ebx, %edx
jne 0xc652
movl %r8d, %eax
andl $0x7, %eax
movl %eax, %r15d
subl %r9d, %r15d
movl %r15d, %r12d
negl %r12d
cmovsl %r15d, %r12d
movl %r8d, %ecx
sarl $0x3, %ecx
movl %ecx, %r15d
subl %r10d, %r15d
movl %ebx, -0x10(%rsp)
movl %r13d, %ebx
movl %r15d, %r13d
negl %r13d
cmovsl %r15d, %r13d
cmpl %r13d, %r12d
cmoval %r12d, %r13d
subl %esi, %r13d
cmpl $0x2, %r13d
movl %ebx, %r13d
movl -0x10(%rsp), %ebx
jl 0xc652
subl %r14d, %eax
movl %eax, %r14d
negl %r14d
cmovsl %eax, %r14d
sarl $0x3, %r11d
subl %r11d, %ecx
movl %ecx, %r11d
negl %r11d
cmovsl %ecx, %r11d
cmpl %r11d, %r14d
cmoval %r14d, %r11d
subl %esi, %r11d
xorl %eax, %eax
cmpl $0x1, %r11d
jg 0xc8ca
cmpl $0x6, %r10d
setne %al
testl %r9d, %r9d
sete %cl
orb %al, %cl
jne 0xc71c
movl %r13d, %eax
andl $0x7, %eax
cmpl %r9d, %eax
jne 0xc71c
cmpl %ebp, %r13d
je 0xc71c
movl %r8d, %ecx
andl $0x7, %ecx
subl %r9d, %ecx
movl %ecx, %ebp
negl %ebp
cmovsl %ecx, %ebp
movl %r8d, %ecx
sarl $0x3, %ecx
addl $-0x7, %ecx
movl %ecx, %r11d
negl %r11d
cmovsl %ecx, %r11d
cmpl %r11d, %ebp
cmoval %ebp, %r11d
movl %edx, %ebp
andl $0x7, %ebp
movl %ebp, %ecx
subl %r9d, %ecx
movl %ecx, %r15d
negl %r15d
cmovsl %ecx, %r15d
movl %edx, %r14d
sarl $0x3, %r14d
leal -0x7(%r14), %ecx
movl %ecx, %r12d
negl %r12d
cmovsl %ecx, %r12d
cmpl %r12d, %r15d
cmoval %r15d, %r12d
leal (%r12,%rsi), %ecx
addl $-0x2, %ecx
cmpl %ecx, %r11d
jge 0xc71c
subl %eax, %ebp
movl %ebp, %eax
negl %eax
cmovsl %ebp, %eax
movl %r13d, %ecx
sarl $0x3, %ecx
subl %ecx, %r14d
movl %r14d, %ecx
negl %ecx
cmovsl %r14d, %ecx
cmpl %ecx, %eax
cmoval %eax, %ecx
addl %esi, %ecx
cmpl %ecx, %r11d
jae 0xc71c
addl %r11d, %r11d
movl $0x80, %eax
subl %r11d, %eax
jmp 0xc8ca
movl %r13d, -0x10(%rsp)
testl %r9d, %r9d
je 0xc864
cmpl %edi, -0x10(%rsp)
jge 0xc864
movl -0x10(%rsp), %r11d
andl $0x7, %r11d
cmpl %r9d, %r11d
jne 0xc864
movl %r8d, %r15d
andl $0x7, %r15d
subl %r9d, %r15d
movl %r15d, %ecx
negl %ecx
cmovsl %r15d, %ecx
movl %r8d, %r12d
sarl $0x3, %r12d
leal -0x7(%r12), %ebp
movl %ebp, %eax
negl %eax
cmovsl %ebp, %eax
cmpl %eax, %ecx
cmoval %ecx, %eax
movl %edx, %r13d
andl $0x7, %r13d
movl %r13d, -0xc(%rsp)
subl %r9d, %r13d
movl %r13d, %ecx
negl %ecx
cmovsl %r13d, %ecx
movl %edx, %r14d
sarl $0x3, %r14d
movq %rsi, -0x8(%rsp)
movl %ebx, %esi
leal -0x7(%r14), %ebx
movl %ebx, %ebp
negl %ebp
cmovsl %ebx, %ebp
cmpl %ebp, %ecx
cmoval %ecx, %ebp
movq -0x8(%rsp), %rcx
addl %ebp, %ecx
addl $-0x2, %ecx
cmpl %ecx, %eax
jge 0xc864
movl %esi, %ebx
movl %r15d, %ecx
negl %ecx
cmovsl %r15d, %ecx
sarl $0x3, %ebx
subl %ebx, %r12d
movl %r12d, %r15d
negl %r15d
cmovsl %r12d, %r15d
cmpl %r15d, %ecx
cmoval %ecx, %r15d
movl %r13d, %ecx
negl %ecx
cmovsl %r13d, %ecx
movl %ebx, %esi
movl %r14d, %ebx
subl %esi, %ebx
movq -0x8(%rsp), %rsi
movl %ebx, %r12d
negl %r12d
cmovsl %ebx, %r12d
cmpl %r12d, %ecx
cmoval %ecx, %r12d
leal (%r12,%rsi), %ecx
addl $-0x2, %ecx
cmpl %ecx, %r15d
jge 0xc864
movl -0xc(%rsp), %ecx
subl %r11d, %ecx
movl %ecx, %r11d
negl %r11d
cmovsl %ecx, %r11d
movl -0x10(%rsp), %ecx
sarl $0x3, %ecx
subl %ecx, %r14d
movl %r14d, %ecx
negl %ecx
cmovsl %r14d, %ecx
cmpl %ecx, %r11d
cmoval %r11d, %ecx
addl %esi, %ecx
cmpl $0x2, %ecx
ja 0xc848
cmpl %ecx, %eax
jae 0xc864
cmpl %ecx, %r15d
jae 0xc864
addl $-0x7, %r10d
movl %r10d, %ecx
negl %ecx
cmovsl %r10d, %ecx
shll $0x3, %ecx
leal (%rcx,%rax,2), %ecx
movl $0x80, %eax
subl %ecx, %eax
jmp 0xc8ca
cmpl %edi, %edx
jle 0xc8c5
cmpl $0x3, %r10d
jg 0xc8c5
movl %edx, %esi
andl $0x7, %esi
movl $0xa, %eax
movl %esi, %edi
subl %r9d, %edi
je 0xc8ca
incl %edi
testl $0xfffffffd, %edi       # imm = 0xFFFFFFFD
jne 0xc8c5
movl %r8d, %eax
andl $0x7, %eax
subl %esi, %eax
movl %eax, %ecx
negl %ecx
cmovsl %eax, %ecx
sarl $0x3, %r8d
sarl $0x3, %edx
subl %edx, %r8d
movl %r8d, %edx
negl %edx
cmovsl %r8d, %edx
cmpl %edx, %ecx
cmoval %ecx, %edx
movl $0xff, %eax
cmpl $0x3, %edx
jb 0xc8ca
addl %edx, %edx
movl $0x18, %eax
subl %edx, %eax
jmp 0xc8ca
movl $0xff, %eax
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
nop