// File: /workspace/github_cpp_makefile_star2_O2/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
subq $0x18, %rsp
movq %rsi, %rbx
movq %rdi, %r14
movl 0x8(%rdi), %r8d
movl 0xc(%rdi), %ecx
movq %r8, %rax
shlq $0x9, %rax
movl 0x250(%rsi,%rax), %r11d
shlq $0x9, %rcx
movl 0x250(%rsi,%rcx), %edi
movl %edi, %edx
xorl %r11d, %edx
movl %edx, %esi
shrl $0x3, %esi
xorl %edx, %esi
movl $0xff, %edx
testb $0x1, %sil
je 0xc059
movl %edi, 0xc(%rsp)
leaq 0x190(%rbx), %rsi
movl 0x40(%rsi,%rax), %edx
movl 0x44(%rsi,%rax), %edi
movl %edx, %r13d
sarl $0x3, %r13d
movl %edi, %ebp
sarl $0x3, %ebp
imull $0x7, %r8d, %eax
movl %r13d, %r9d
xorl %eax, %r9d
movl %ebp, %r10d
xorl %eax, %r10d
xorl %r15d, %r15d
testq %r8, %r8
sete %r15b
shll $0x4, %r15d
addl $-0x8, %r15d
cmpl %r10d, %r9d
jle 0xbfc7
andl $0x7, %edi
movl %edx, %r12d
andl $-0x8, %r12d
orl %edi, %r12d
movl %edx, %r8d
andl $0x7, %r8d
movl %edi, %r9d
jmp 0xbfe0
andl $0x7, %edx
movl %edi, %r12d
andl $-0x8, %r12d
orl %edx, %r12d
movl %edi, %r9d
andl $0x7, %r9d
movl %edx, %r8d
movl %edi, %edx
subl %r9d, %r8d
movl 0x180(%rsi,%rcx), %esi
addl %edx, %r15d
movl %r8d, %ecx
negl %ecx
cmovsl %r8d, %ecx
cmpl $0x1, %ecx
je 0xc02b
testl %ecx, %ecx
jne 0xc054
xorl %esi, %edx
testb $0x7, %dl
jne 0xc054
movl %esi, %ecx
sarl $0x3, %ecx
xorl %eax, %ecx
sarl $0x3, %r15d
xorl %eax, %r15d
cmpl %r15d, %ecx
jl 0xc054
xorl %r11d, %esi
movl %esi, %eax
shrl $0x3, %eax
xorl %esi, %eax
xorl %edx, %edx
testb $0x1, %al
je 0xc054
jmp 0xc059
cmpl %r15d, %esi
jne 0xc041
movl %esi, %eax
xorl %r11d, %eax
movl %eax, %ecx
shrl $0x3, %ecx
xorl %eax, %ecx
testb $0x1, %cl
jne 0xc06a
cmpl %r12d, %esi
jne 0xc054
xorl %r11d, %esi
movl %esi, %eax
shrl $0x3, %eax
xorl %esi, %eax
testb $0x1, %al
jne 0xc0a0
movl $0xff, %edx
movl %edx, %eax
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
xorl %edx, %edx
cmpl %r12d, 0xc(%rsp)
je 0xc059
movl %esi, 0x10(%rsp)
movl %r11d, 0x14(%rsp)
movq %rbx, %rdi
movl %r12d, %esi
callq 0xcf20
movl 0xc(%r14), %ecx
andq 0x118(%rbx), %rax
testq %rax, 0x140(%rbx,%rcx,8)
je 0xc0cd
xorl %edx, %edx
jmp 0xc059
xorl %edx, %edx
cmpl %r15d, 0xc(%rsp)
je 0xc059
movq %rbx, %rdi
movl %r15d, %esi
callq 0xcf20
xorl %edx, %edx
movl 0xc(%r14), %ecx
andq 0x118(%rbx), %rax
testq %rax, 0x140(%rbx,%rcx,8)
jne 0xc059
jmp 0xc054
subl %ebp, %r13d
movl %r13d, %eax
negl %eax
cmovsl %r13d, %eax
cmpl $0x1, %eax
movl 0x14(%rsp), %r11d
movl $0x0, %edx
movl 0x10(%rsp), %esi
jbe 0xc041
jmp 0xc059
nop