// File: /workspace/github_cpp_makefile_star2_O2/codeandkey[P]neocortex/src/position.cpp
// Function: neocortex::Position::see(int, int)
int Position::see(int sq, int attacking_col) {
	bitboard ctm = board.get_color_occ(attacking_col);
	int lva = square::null;

#ifndef NDEBUG
	zobrist::Key starting_bkey = board.get_tt_key();
#endif

	/* Find least valuable attacker */

	// Search for pawn attacks
	bitboard pawn_attackers = attacks::pawn(!attacking_col, sq) & board.get_piece_occ(piece::PAWN) & ctm;

	if (pawn_attackers) {
		lva = bb::poplsb(pawn_attackers);
	}
	else {
		// Find bishop attackers
		bitboard bishop_attacks = attacks::bishop(sq, board.get_global_occ());
		bitboard bishop_attackers = bishop_attacks & ctm & board.get_piece_occ(piece::BISHOP);

		if (bishop_attackers) {
			lva = bb::poplsb(bishop_attackers);
		}
		else {
			// Find knight attackers
			bitboard knight_attackers = attacks::knight(sq) & ctm & board.get_piece_occ(piece::KNIGHT);

			if (knight_attackers) {
				lva = bb::poplsb(knight_attackers);
			}
			else {
				// Find rook attackers
				bitboard rook_attacks = attacks::rook(sq, board.get_global_occ());
				bitboard rook_attackers = rook_attacks & ctm & board.get_piece_occ(piece::ROOK);

				if (rook_attackers) {
					lva = bb::poplsb(rook_attackers);
				}
				else {
					// Find queen attackers
					bitboard queen_attackers = (bishop_attacks | rook_attacks) & ctm & board.get_piece_occ(piece::QUEEN);

					if (queen_attackers) {
						lva = bb::poplsb(queen_attackers);
					}
					else {
						// Find king attackers
						bitboard king_attackers = attacks::king(sq) & ctm & board.get_piece_occ(piece::KING);

						if (king_attackers) {
							lva = bb::poplsb(king_attackers);
						}
					}
				}
			}
		}
	}

	if (square::is_valid(lva)) {
		/* Remove LVA from board */
		int removed = board.remove(lva);

		/* Perform capture with LVA, record material gain */
		int dst_removed = board.replace(sq, removed);
		int dst_value = eval::MATERIAL_MG[piece::type(dst_removed)];

		int ret = dst_value - see(sq, !attacking_col);

		/* Undo capture */
		board.replace(sq, dst_removed);
		board.place(lva, removed);

		assert(board.get_tt_key() == starting_bkey);
		return ret;
	} else {
		// No valid attackers, SEE is 0
		assert(board.get_tt_key() == starting_bkey);
		return 0;
	}
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x48, %rsp
movq %rdi, %rbx
movslq %edx, %rax
movq 0x8(%rdi,%rax,8), %r12
movq 0x150(%rdi), %rbp
xorl %r14d, %r14d
testl %eax, %eax
sete %r14b
movslq %esi, %r13
movl %r14d, %eax
shll $0x9, %eax
addq 0x11b5b(%rip), %rax     # 0x1cf90
movq (%rax,%r13,8), %rax
andq 0x18(%rdi), %rax
andq %r12, %rax
movq %rax, 0x40(%rsp)
movl %esi, 0xc(%rsp)
je 0xb455
leaq 0x40(%rsp), %rdi
jmp 0xb4fa
movl %esi, %ecx
movq (%rbx), %rsi
movl %ecx, %edi
callq 0x6440
movq %rax, %r15
movq 0x20(%rbx), %rax
andq %r12, %rax
andq %r15, %rax
movq %rax, 0x38(%rsp)
je 0xb47c
leaq 0x38(%rsp), %rdi
jmp 0xb4fa
leaq 0x1233d(%rip), %rax     # 0x1d7c0
movq (%rax,%r13,8), %rax
andq 0x28(%rbx), %rax
andq %r12, %rax
movq %rax, 0x30(%rsp)
je 0xb49c
leaq 0x30(%rsp), %rdi
jmp 0xb4fa
movq (%rbx), %rsi
movl 0xc(%rsp), %edi
callq 0x649e
movq 0x30(%rbx), %rcx
andq %r12, %rcx
andq %rax, %rcx
movq %rcx, 0x28(%rsp)
je 0xb4c0
leaq 0x28(%rsp), %rdi
jmp 0xb4fa
orq %r15, %rax
andq 0x38(%rbx), %rax
andq %r12, %rax
movq %rax, 0x20(%rsp)
je 0xb4d8
leaq 0x20(%rsp), %rdi
jmp 0xb4fa
leaq 0x120e1(%rip), %rax     # 0x1d5c0
movq (%rax,%r13,8), %rax
andq 0x40(%rbx), %rax
andq %r12, %rax
movq %rax, 0x18(%rsp)
je 0xb5ad
leaq 0x18(%rsp), %rdi
callq 0x64fc
movl %eax, %r15d
cmpl $0x3f, %r15d
ja 0xb58f
movq %rbx, %rdi
movl %r15d, %esi
callq 0x5b86
movl %eax, %r13d
movq %rbx, %rdi
movl %r14d, 0x8(%rsp)
movl 0xc(%rsp), %r14d
movl %r14d, %esi
movl %eax, %edx
callq 0x5c54
movq %rbp, 0x10(%rsp)
movl %eax, %ebp
movl %eax, %edi
callq 0x63ef
cltq
leaq 0x9348(%rip), %rcx      # 0x14890
movl (%rcx,%rax,4), %r12d
movq %rbx, %rdi
movl %r14d, %esi
movl 0x8(%rsp), %edx
callq 0xb3fc
movl %eax, 0x8(%rsp)
movq %rbx, %rdi
movl %r14d, %esi
movl %ebp, %edx
callq 0x5c54
movq %rbx, %rdi
movl %r15d, %esi
movl %r13d, %edx
callq 0x5a44
movq 0x10(%rsp), %rax
cmpq %rax, 0x150(%rbx)
jne 0xb5b6
subl 0x8(%rsp), %r12d
jmp 0xb59b
xorl %r12d, %r12d
cmpq %rbp, 0x150(%rbx)
jne 0xb5d5
movl %r12d, %eax
addq $0x48, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
pushq $-0x1
popq %r15
jmp 0xb502
leaq 0x9a5d(%rip), %rdi      # 0x1501a
leaq 0x9751(%rip), %rsi      # 0x14d15
leaq 0x9a73(%rip), %rcx      # 0x1503e
movl $0x4ce, %edx            # imm = 0x4CE
callq 0x41f0
leaq 0x9a3e(%rip), %rdi      # 0x1501a
leaq 0x9732(%rip), %rsi      # 0x14d15
leaq 0x9a54(%rip), %rcx      # 0x1503e
movl $0x4d2, %edx            # imm = 0x4D2
callq 0x41f0