// File: /workspace/github_cpp_makefile_star2_O3/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 %r12
pushq %rbx
movl 0x8(%rdi), %ebx
movl 0xc(%rdi), %eax
movq %rbx, %rdx
shlq $0x9, %rdx
shlq $0x9, %rax
movl 0x310(%rsi,%rdx), %ecx
movl 0x1d0(%rsi,%rdx), %edi
movl 0x290(%rsi,%rdx), %r8d
movl 0x290(%rsi,%rax), %r11d
movl 0x310(%rsi,%rax), %edx
cmpq $0x1, %rbx
jne 0xc935
xorl $0x38, %ecx
xorl $0x38, %r8d
xorl $0x38, %edi
xorl $0x38, %edx
xorl $0x38, %r11d
testb $0x4, %dil
je 0xc94c
xorl $0x7, %ecx
xorl $0x7, %r8d
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 %sil
cmpl $0x4, %r10d
jg 0xca48
movl %edx, %eax
andl $0x7, %eax
subl %r9d, %eax
movl %eax, %ebx
negl %ebx
cmovsl %eax, %ebx
movl %edx, %ebp
sarl $0x3, %ebp
addl $-0x7, %ebp
movl %ebp, %eax
negl %eax
cmovsl %ebp, %eax
cmpl %eax, %ebx
cmoval %ebx, %eax
cmpl $0x27, %ecx
jg 0xc9c7
cmpl $0x1, %eax
ja 0xc9c7
movl %r11d, %ebx
andl $-0x8, %ebx
xorl %eax, %eax
cmpl $0x28, %ebx
je 0xcd6f
cmpl $0x2, %r10d
jg 0xc9c7
movl %r8d, %ebx
andl $-0x8, %ebx
cmpl $0x28, %ebx
jne 0xcd6f
leal 0x8(%rdi), %eax
cmpl %eax, %edx
jne 0xca3a
movl %ecx, %eax
andl $0x7, %eax
movl %eax, %ebx
subl %r9d, %ebx
movl %ebx, %ebp
negl %ebp
cmovsl %ebx, %ebp
movl %ecx, %ebx
sarl $0x3, %ebx
movl %ebx, %r14d
subl %r10d, %r14d
movl %r14d, %r15d
negl %r15d
cmovsl %r14d, %r15d
cmpl %r15d, %ebp
cmoval %ebp, %r15d
subl %esi, %r15d
cmpl $0x2, %r15d
jl 0xca3a
movl %r11d, %ebp
andl $0x7, %ebp
subl %ebp, %eax
movl %eax, %ebp
negl %ebp
cmovsl %eax, %ebp
sarl $0x3, %r11d
subl %r11d, %ebx
movl %ebx, %r11d
negl %r11d
cmovsl %ebx, %r11d
cmpl %r11d, %ebp
cmoval %ebp, %r11d
subl %esi, %r11d
xorl %eax, %eax
cmpl $0x1, %r11d
jg 0xcd6f
testl %r9d, %r9d
jne 0xcc0c
jmp 0xcd0e
leal 0x38(%r9), %ebp
cmpl $0x5, %r10d
jne 0xcabe
movl %edx, %eax
andl $0x7, %eax
subl %r9d, %eax
movl %eax, %r15d
negl %r15d
cmovsl %eax, %r15d
movl %edx, %eax
sarl $0x3, %eax
addl $-0x7, %eax
movl %eax, %r12d
negl %r12d
cmovsl %eax, %r12d
cmpl %r12d, %r15d
cmoval %r15d, %r12d
cmpl $0x1, %r12d
ja 0xcabe
movl %ecx, %eax
sarl $0x3, %eax
addl %esi, %eax
cmpl $0x5, %eax
jg 0xcabe
xorl %eax, %eax
cmpl $0x8, %r11d
jb 0xcd6f
cmpl %ebx, %r14d
je 0xcb08
movl %r11d, %ebx
andl $0x7, %ebx
subl %r9d, %ebx
movl %ebx, %r14d
negl %r14d
cmovsl %ebx, %r14d
cmpl $0x2, %r14d
jbe 0xcb08
jmp 0xcd6f
cmpl %ebp, %edx
jne 0xcb08
cmpl $0x7, %r11d
ja 0xcb08
xorl %eax, %eax
cmpl %ebx, %r14d
jne 0xcd6f
movl %ecx, %ebx
andl $0x7, %ebx
subl %r9d, %ebx
movl %ebx, %r14d
negl %r14d
cmovsl %ebx, %r14d
movl %ecx, %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 0xcd6f
movl %edx, %eax
andl $-0x2, %eax
cmpl $0x36, %eax
jne 0xcb4d
cmpl $0x30, %edi
jne 0xcb4d
cmpl $0x38, %r8d
jne 0xcb4d
testb $0x7, %r11b
jne 0xcd6a
xorl %eax, %eax
cmpl $0x11, %r11d
jl 0xcd6f
cmpl $0x28, %ecx
jl 0xcd6f
andl $0x7, %ecx
cmpl $0x2, %ecx
jbe 0xcd6a
jmp 0xcd6f
cmpl $0x6, %r10d
setne %al
testl %r9d, %r9d
sete %r11b
orb %al, %r11b
jne 0xcc03
movl %r8d, %eax
andl $0x7, %eax
cmpl %r9d, %eax
jne 0xcc0c
cmpl %ebp, %r8d
je 0xcc0c
movl %ecx, %eax
andl $0x7, %eax
subl %r9d, %eax
movl %eax, %ebx
negl %ebx
cmovsl %eax, %ebx
movl %ecx, %eax
sarl $0x3, %eax
addl $-0x7, %eax
movl %eax, %r11d
negl %r11d
cmovsl %eax, %r11d
cmpl %r11d, %ebx
cmoval %ebx, %r11d
movl %edx, %ebx
andl $0x7, %ebx
subl %r9d, %ebx
movl %ebx, %eax
negl %eax
cmovsl %ebx, %eax
movl %edx, %ebx
sarl $0x3, %ebx
leal -0x7(%rbx), %ebp
movl %ebp, %r14d
negl %r14d
cmovsl %ebp, %r14d
cmpl %r14d, %eax
cmoval %eax, %r14d
leal (%r14,%rsi), %ebp
addl $-0x2, %ebp
cmpl %ebp, %r11d
jge 0xcc0c
movl %r8d, %ebp
sarl $0x3, %ebp
subl %ebp, %ebx
movl %ebx, %ebp
negl %ebp
cmovsl %ebx, %ebp
cmpl %ebp, %eax
cmoval %eax, %ebp
addl %esi, %ebp
cmpl %ebp, %r11d
jae 0xcc0c
addl %r11d, %r11d
movl $0x80, %eax
subl %r11d, %eax
jmp 0xcd6f
testl %r9d, %r9d
je 0xcd6a
cmpl %edi, %r8d
jge 0xcd0e
movl %r8d, %eax
andl $0x7, %eax
cmpl %r9d, %eax
jne 0xcd0e
movl %ecx, %eax
andl $0x7, %eax
subl %r9d, %eax
movl %eax, %ebp
negl %ebp
cmovsl %eax, %ebp
movl %ecx, %r14d
sarl $0x3, %r14d
leal -0x7(%r14), %r11d
movl %r11d, %eax
negl %eax
cmovsl %r11d, %eax
cmpl %eax, %ebp
cmoval %ebp, %eax
movl %edx, %ebx
andl $0x7, %ebx
subl %r9d, %ebx
movl %ebx, %r11d
negl %r11d
cmovsl %ebx, %r11d
movl %edx, %ebx
sarl $0x3, %ebx
leal -0x7(%rbx), %r15d
movl %r15d, %r12d
negl %r12d
cmovsl %r15d, %r12d
cmpl %r12d, %r11d
cmoval %r11d, %r12d
leal (%r12,%rsi), %r15d
addl $-0x2, %r15d
cmpl %r15d, %eax
jge 0xcd0e
leal 0x8(%rdi), %r12d
sarl $0x3, %r12d
subl %r12d, %r14d
movl %r14d, %r15d
negl %r15d
cmovsl %r14d, %r15d
cmpl %r15d, %ebp
cmoval %ebp, %r15d
movl %ebx, %ebp
subl %r12d, %ebp
movl %ebp, %r14d
negl %r14d
cmovsl %ebp, %r14d
cmpl %r14d, %r11d
cmoval %r11d, %r14d
leal (%r14,%rsi), %ebp
addl $-0x2, %ebp
cmpl %ebp, %r15d
jge 0xcd0e
sarl $0x3, %r8d
subl %r8d, %ebx
movl %ebx, %r8d
negl %r8d
cmovsl %ebx, %r8d
cmpl %r8d, %r11d
cmoval %r11d, %r8d
addl %esi, %r8d
cmpl $0x2, %r8d
ja 0xccf2
cmpl %r8d, %eax
jae 0xcd0e
cmpl %r8d, %r15d
jae 0xcd0e
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 0xcd6f
cmpl %edi, %edx
jle 0xcd6a
cmpl $0x3, %r10d
jg 0xcd6a
movl %edx, %esi
andl $0x7, %esi
movl $0xa, %eax
movl %esi, %edi
subl %r9d, %edi
je 0xcd6f
incl %edi
testl $0xfffffffd, %edi       # imm = 0xFFFFFFFD
jne 0xcd6a
movl %ecx, %eax
andl $0x7, %eax
subl %esi, %eax
movl %eax, %esi
negl %esi
cmovsl %eax, %esi
sarl $0x3, %ecx
sarl $0x3, %edx
subl %edx, %ecx
movl %ecx, %edx
negl %edx
cmovsl %ecx, %edx
cmpl %edx, %esi
cmoval %esi, %edx
movl $0xff, %eax
cmpl $0x3, %edx
jb 0xcd6f
addl %edx, %edx
movl $0x18, %eax
subl %edx, %eax
jmp 0xcd6f
movl $0xff, %eax
popq %rbx
popq %r12
popq %r14
popq %r15
popq %rbp
retq