// File: /workspace/github_cpp_makefile_star2_O1/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), %edx
movq %rdi, %r9
shlq $0x9, %r9
movl 0x250(%rsi,%r9), %r8d
movl %r8d, %ecx
xorl %edx, %ecx
movl %ecx, %esi
shrl $0x3, %esi
xorl %ecx, %esi
movl $0xff, %ebp
testb $0x1, %sil
je 0xcd31
movl %r8d, 0x4(%rsp)
movl %edx, (%rsp)
leaq 0x190(%rbx), %r13
movl 0x40(%r13,%rax), %r15d
movl 0x44(%r13,%rax), %r12d
movl %r15d, %r8d
sarl $0x3, %r8d
movl %r12d, %edx
sarl $0x3, %edx
leal (,%r11,8), %ecx
subl %r11d, %ecx
movl %r8d, %eax
xorl %ecx, %eax
movl %edx, %r10d
xorl %ecx, %r10d
xorl %esi, %esi
testq %r11, %r11
sete %sil
shll $0x4, %esi
addl $-0x8, %esi
cmpl %r10d, %eax
jle 0xcc91
movl %r12d, %eax
andl $0x7, %eax
movl %r15d, %r11d
andl $-0x8, %r11d
orl %eax, %r11d
movl %r15d, %eax
jmp 0xcca4
movl %r15d, %eax
andl $0x7, %eax
movl %r12d, %r11d
andl $-0x8, %r11d
orl %eax, %r11d
movl %r12d, %eax
movl 0x180(%r13,%r9), %r9d
addl %eax, %esi
andl $0x7, %r15d
andl $0x7, %r12d
subl %r12d, %r15d
movl %r15d, %r12d
negl %r12d
cmovsl %r15d, %r12d
cmpl $0x1, %r12d
je 0xccfb
testl %r12d, %r12d
jne 0xcd31
xorl %r9d, %eax
testb $0x7, %al
jne 0xcd2c
movl %r9d, %eax
sarl $0x3, %eax
xorl %ecx, %eax
sarl $0x3, %esi
xorl %ecx, %esi
cmpl %esi, %eax
jl 0xcd2c
xorl (%rsp), %r9d
movl %r9d, %eax
shrl $0x3, %eax
xorl %r9d, %eax
xorl %ebp, %ebp
testb $0x1, %al
je 0xcd2c
jmp 0xcd31
cmpl %esi, %r9d
jne 0xcd12
movl %r9d, %eax
xorl (%rsp), %eax
movl %eax, %ecx
shrl $0x3, %ecx
xorl %eax, %ecx
testb $0x1, %cl
jne 0xcd42
cmpl %r11d, %r9d
jne 0xcd2c
xorl (%rsp), %r9d
movl %r9d, %eax
shrl $0x3, %eax
xorl %r9d, %eax
testb $0x1, %al
jne 0xcdd3
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 0xcd31
movslq %r11d, %rax
leaq 0x100d4b(%rip), %rcx    # 0x10daa0
movq (%rcx,%rax,8), %rcx
andq 0x100(%rbx), %rcx
leaq 0x100f39(%rip), %r10    # 0x10dca0
leaq 0x215d2(%rip), %r15     # 0x2e340
movq (%r15,%rax,8), %r15
movl %r15d, %r12d
imull %ecx, %r12d
shrq $0x20, %rcx
shrq $0x20, %r15
imull %ecx, %r15d
xorl %r12d, %r15d
leaq 0x219b1(%rip), %rcx     # 0x2e740
movb (%rcx,%rax,4), %cl
shrl %cl, %r15d
addl (%r10,%rax,4), %r15d
leaq 0x101000(%rip), %rax    # 0x10dda0
movq 0x118(%rbx), %rcx
andq (%rax,%r15,8), %rcx
testq %rcx, 0x140(%rbx,%rdi,8)
jne 0xcd31
subl %edx, %r8d
movl %r8d, %eax
negl %eax
cmovsl %r8d, %eax
cmpl $0x1, %eax
jbe 0xcd12
jmp 0xcd31
xorl %ebp, %ebp
cmpl %esi, 0x4(%rsp)
je 0xcd31
movq %rbx, %rdi
callq 0xe010
movl 0xc(%r14), %ecx
andq 0x118(%rbx), %rax
testq %rax, 0x140(%rbx,%rcx,8)
jne 0xcd31
jmp 0xcd2c
nop