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

  assert(pos.non_pawn_material(strongerSide) == BishopValueMidgame);
  assert(pos.piece_count(strongerSide, BISHOP) == 1);
  assert(pos.piece_count(strongerSide, PAWN) == 2);
  assert(pos.non_pawn_material(weakerSide) == BishopValueMidgame);
  assert(pos.piece_count(weakerSide, BISHOP) == 1);
  assert(pos.piece_count(weakerSide, PAWN) == 0);

  Square wbsq = pos.piece_list(strongerSide, BISHOP, 0);
  Square bbsq = pos.piece_list(weakerSide, BISHOP, 0);

  if (!opposite_color_squares(wbsq, bbsq))
      return SCALE_FACTOR_NONE;

  Square ksq = pos.king_square(weakerSide);
  Square psq1 = pos.piece_list(strongerSide, PAWN, 0);
  Square psq2 = pos.piece_list(strongerSide, PAWN, 1);
  Rank r1 = square_rank(psq1);
  Rank r2 = square_rank(psq2);
  Square blockSq1, blockSq2;

  if (relative_rank(strongerSide, psq1) > relative_rank(strongerSide, psq2))
  {
      blockSq1 = psq1 + pawn_push(strongerSide);
      blockSq2 = make_square(square_file(psq2), square_rank(psq1));
  }
  else
  {
      blockSq1 = psq2 + pawn_push(strongerSide);
      blockSq2 = make_square(square_file(psq1), square_rank(psq2));
  }

  switch (file_distance(psq1, psq2))
  {
  case 0:
    // Both pawns are on the same file. Easy draw if defender firmly controls
    // some square in the frontmost pawn's path.
    if (   square_file(ksq) == square_file(blockSq1)
        && relative_rank(strongerSide, ksq) >= relative_rank(strongerSide, blockSq1)
        && opposite_color_squares(ksq, wbsq))
        return SCALE_FACTOR_ZERO;
    else
        return SCALE_FACTOR_NONE;

  case 1:
    // Pawns on neighboring files. Draw if defender firmly controls the square
    // in front of the frontmost pawn's path, and the square diagonally behind
    // this square on the file of the other pawn.
    if (   ksq == blockSq1
        && opposite_color_squares(ksq, wbsq)
        && (   bbsq == blockSq2
            || (pos.attacks_from<BISHOP>(blockSq2) & pos.pieces(BISHOP, weakerSide))
            || abs(r1 - r2) >= 2))
        return SCALE_FACTOR_ZERO;

    else if (   ksq == blockSq2
             && opposite_color_squares(ksq, wbsq)
             && (   bbsq == blockSq1
                 || (pos.attacks_from<BISHOP>(blockSq1) & pos.pieces(BISHOP, weakerSide))))
        return SCALE_FACTOR_ZERO;
    else
        return SCALE_FACTOR_NONE;

  default:
    // The pawns are not on the same file or adjacent files. No scaling.
    return SCALE_FACTOR_NONE;
  }
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
pushq %rax
movq %rsi, %rbx
movq %rdi, %r14
movl 0x8(%rdi), %r11d
movl 0xc(%rdi), %edi
movq %r11, %rax
shlq $0x9, %rax
movl 0x250(%rsi,%rax), %esi
movq %rdi, %r10
shlq $0x9, %r10
movl 0x250(%rbx,%r10), %r8d
movl %r8d, %ecx
xorl %esi, %ecx
movl %ecx, %edx
shrl $0x3, %edx
xorl %ecx, %edx
movl $0xff, %ebp
testb $0x1, %dl
je 0xd1cd
movl %r8d, 0x4(%rsp)
movl %esi, (%rsp)
leaq 0x190(%rbx), %r12
movl 0x40(%r12,%rax), %r8d
movl 0x44(%r12,%rax), %r13d
movl %r8d, %eax
sarl $0x3, %eax
movl %r13d, %r9d
sarl $0x3, %r9d
leal (,%r11,8), %ecx
subl %r11d, %ecx
movl %eax, %edx
xorl %ecx, %edx
movl %r9d, %r15d
xorl %ecx, %r15d
xorl %esi, %esi
testq %r11, %r11
sete %sil
shll $0x4, %esi
addl $-0x8, %esi
cmpl %r15d, %edx
jle 0xd12e
andl $0x7, %r13d
movl %r8d, %r11d
andl $-0x8, %r11d
orl %r13d, %r11d
movl %r8d, %r15d
andl $0x7, %r15d
movl %r13d, %edx
jmp 0xd148
andl $0x7, %r8d
movl %r13d, %r11d
andl $-0x8, %r11d
orl %r8d, %r11d
movl %r13d, %edx
andl $0x7, %edx
movl %r8d, %r15d
movl %r13d, %r8d
subl %edx, %r15d
movl 0x180(%r12,%r10), %r10d
addl %r8d, %esi
movl %r15d, %edx
negl %edx
cmovsl %r15d, %edx
cmpl $0x1, %edx
je 0xd197
testl %edx, %edx
jne 0xd1cd
xorl %r10d, %r8d
testb $0x7, %r8b
jne 0xd1c8
movl %r10d, %eax
sarl $0x3, %eax
xorl %ecx, %eax
sarl $0x3, %esi
xorl %ecx, %esi
cmpl %esi, %eax
jl 0xd1c8
xorl (%rsp), %r10d
movl %r10d, %eax
shrl $0x3, %eax
xorl %r10d, %eax
xorl %ebp, %ebp
testb $0x1, %al
je 0xd1c8
jmp 0xd1cd
cmpl %esi, %r10d
jne 0xd1ae
movl %r10d, %ecx
xorl (%rsp), %ecx
movl %ecx, %edx
shrl $0x3, %edx
xorl %ecx, %edx
testb $0x1, %dl
jne 0xd1de
cmpl %r11d, %r10d
jne 0xd1c8
xorl (%rsp), %r10d
movl %r10d, %eax
shrl $0x3, %eax
xorl %r10d, %eax
testb $0x1, %al
jne 0xd26d
movl $0xff, %ebp
movl %ebp, %eax
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
xorl %ebp, %ebp
cmpl %r11d, 0x4(%rsp)
je 0xd1cd
movslq %r11d, %rdx
leaq 0x1018af(%rip), %rcx    # 0x10eaa0
movq (%rcx,%rdx,8), %rcx
andq 0x100(%rbx), %rcx
leaq 0x101a9d(%rip), %r8     # 0x10eca0
leaq 0x221b6(%rip), %r15     # 0x2f3c0
movq (%r15,%rdx,8), %r15
movl %r15d, %r12d
imull %ecx, %r12d
shrq $0x20, %rcx
shrq $0x20, %r15
imull %ecx, %r15d
xorl %r12d, %r15d
leaq 0x22595(%rip), %rcx     # 0x2f7c0
movb (%rcx,%rdx,4), %cl
shrl %cl, %r15d
addl (%r8,%rdx,4), %r15d
leaq 0x101b64(%rip), %rcx    # 0x10eda0
movq 0x118(%rbx), %rdx
andq (%rcx,%r15,8), %rdx
testq %rdx, 0x140(%rbx,%rdi,8)
jne 0xd1cd
subl %r9d, %eax
movl %eax, %ecx
negl %ecx
cmovsl %eax, %ecx
cmpl $0x1, %ecx
jbe 0xd1ae
jmp 0xd1cd
xorl %ebp, %ebp
cmpl %esi, 0x4(%rsp)
je 0xd1cd
movq %rbx, %rdi
callq 0xe44e
movl 0xc(%r14), %ecx
andq 0x118(%rbx), %rax
testq %rax, 0x140(%rbx,%rcx,8)
jne 0xd1cd
jmp 0xd1c8
nop