// File: /workspace/github_cpp_makefile_star2_O1/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 $0x18, %rsp
movl %esi, %ebp
movq %rdi, %rbx
movslq %edx, %rcx
movq 0x8(%rdi,%rcx,8), %rax
movq 0x150(%rdi), %r11
xorl %r14d, %r14d
testl %ecx, %ecx
sete %r14b
movslq %esi, %rdx
movl %r14d, %ecx
shll $0x9, %ecx
addq 0x13e8d(%rip), %rcx     # 0x20f98
movq (%rcx,%rdx,8), %rcx
andq 0x18(%rdi), %rcx
andq %rax, %rcx
jne 0xd186
cmpl $0x40, %ebp
jae 0xd2ec
movq (%rbx), %rsi
movl %ebp, %edi
leaq 0x15663(%rip), %rcx     # 0x22790
movq (%rcx,%rdi,8), %r8
leaq 0xc718(%rip), %rcx      # 0x19850
movq (%rcx,%rdi,8), %r9
andq %rsi, %r9
leaq 0xc90a(%rip), %rcx      # 0x19a50
leaq 0xcb03(%rip), %r10      # 0x19c50
imulq (%rcx,%rdi,8), %r9
xorl %ecx, %ecx
subb (%r10,%rdi,4), %cl
shrq %cl, %r9
movslq %r9d, %rcx
movq (%r8,%rcx,8), %r8
movq 0x20(%rbx), %rcx
andq %rax, %rcx
andq %r8, %rcx
jne 0xd186
leaq 0x1461b(%rip), %rcx     # 0x21790
movq (%rcx,%rdx,8), %rcx
andq 0x28(%rbx), %rcx
andq %rax, %rcx
je 0xd22d
bsfq %rcx, %r15
xorl %r13d, %r13d
cmpl $0x3f, %r15d
ja 0xd21b
movl %r14d, 0xc(%rsp)
movq %r11, 0x10(%rsp)
movq %rbx, %rdi
movl %r15d, %esi
callq 0x647c
movl %eax, %r12d
movq %rbx, %rdi
movl %ebp, %esi
movl %eax, %edx
callq 0x6540
cmpl $0xc, %eax
jae 0xd2ae
movl %ebp, %r14d
movl %eax, %ebp
shrl %eax
leaq 0xb5ce(%rip), %rcx      # 0x187a0
movl (%rcx,%rax,4), %r13d
movq %rbx, %rdi
movl %r14d, %esi
movl 0xc(%rsp), %edx
callq 0xd0d0
movl %eax, 0xc(%rsp)
movq %rbx, %rdi
movl %r14d, %esi
movl %ebp, %edx
callq 0x6540
movq %rbx, %rdi
movl %r15d, %esi
movl %r12d, %edx
callq 0x6320
movq 0x10(%rsp), %rax
cmpq %rax, 0x150(%rbx)
jne 0xd2cd
subl 0xc(%rsp), %r13d
movl %r13d, %eax
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x1535c(%rip), %rcx     # 0x22590
movq (%rcx,%rdi,8), %r9
leaq 0xc111(%rip), %rcx      # 0x19350
andq (%rcx,%rdi,8), %rsi
leaq 0xc306(%rip), %rcx      # 0x19550
leaq 0xc4ff(%rip), %r10      # 0x19750
imulq (%rcx,%rdi,8), %rsi
xorl %ecx, %ecx
subb (%r10,%rdi,4), %cl
shrq %cl, %rsi
movslq %esi, %rcx
movq (%r9,%rcx,8), %rcx
movq 0x30(%rbx), %rsi
andq %rax, %rsi
andq %rcx, %rsi
je 0xd27b
bsfq %rsi, %r15
jmp 0xd18a
orq %r8, %rcx
andq 0x38(%rbx), %rcx
andq %rax, %rcx
jne 0xd186
leaq 0x142fe(%rip), %rcx     # 0x21590
movq (%rcx,%rdx,8), %rcx
andq 0x40(%rbx), %rcx
andq %rax, %rcx
jne 0xd186
movl $0xffffffff, %r15d      # imm = 0xFFFFFFFF
jmp 0xd18a
leaq 0xaa30(%rip), %rdi      # 0x17ce5
leaq 0xaa39(%rip), %rsi      # 0x17cf5
leaq 0xaa3e(%rip), %rcx      # 0x17d01
movl $0x45, %edx
callq 0x4190
leaq 0xbbd6(%rip), %rdi      # 0x18eaa
leaq 0xb8ca(%rip), %rsi      # 0x18ba5
leaq 0xbbec(%rip), %rcx      # 0x18ece
movl $0x4ce, %edx            # imm = 0x4CE
callq 0x4190
leaq 0xa790(%rip), %rdi      # 0x17a83
leaq 0xbefc(%rip), %rsi      # 0x191f6
leaq 0xbf03(%rip), %rcx      # 0x19204
movl $0x68, %edx
callq 0x4190
nop