// File: /workspace/github_cpp_makefile_star2_O3/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
movq %rdi, %rbx
movslq %edx, %rcx
movq 0x8(%rdi,%rcx,8), %rax
movq 0x150(%rdi), %r11
xorl %ebp, %ebp
testl %ecx, %ecx
sete %bpl
movl %esi, 0x8(%rsp)
movslq %esi, %rdx
movl %ebp, %ecx
shll $0x9, %ecx
addq 0x14e0b(%rip), %rcx     # 0x21f98
movq (%rcx,%rdx,8), %rcx
andq 0x18(%rdi), %rcx
andq %rax, %rcx
jne 0xd27c
cmpl $0x40, 0x8(%rsp)
jae 0xd34f
movq (%rbx), %rsi
movl 0x8(%rsp), %edi
leaq 0x165d9(%rip), %rcx     # 0x23790
movq (%rcx,%rdi,8), %r8
leaq 0xd77e(%rip), %rcx      # 0x1a940
movq (%rcx,%rdi,8), %r9
andq %rsi, %r9
leaq 0xd970(%rip), %rcx      # 0x1ab40
leaq 0xdb69(%rip), %r10      # 0x1ad40
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 0xd27c
leaq 0x1558d(%rip), %rcx     # 0x22790
movq (%rcx,%rdx,8), %rcx
andq 0x28(%rbx), %rcx
andq %rax, %rcx
jne 0xd27c
leaq 0x16379(%rip), %rcx     # 0x23590
movq (%rcx,%rdi,8), %r9
leaq 0xd21e(%rip), %rcx      # 0x1a440
andq (%rcx,%rdi,8), %rsi
leaq 0xd413(%rip), %rcx      # 0x1a640
leaq 0xd60c(%rip), %r10      # 0x1a840
imulq (%rcx,%rdi,8), %rsi
xorl %ecx, %ecx
subb (%r10,%rdi,4), %cl
shrq %cl, %rsi
movslq %esi, %rcx
movq (%r9,%rcx,8), %rsi
movq 0x30(%rbx), %rcx
andq %rax, %rcx
andq %rsi, %rcx
jne 0xd27c
orq %r8, %rsi
andq 0x38(%rbx), %rsi
andq %rax, %rsi
movq %rsi, %rcx
jne 0xd27c
leaq 0x15325(%rip), %rcx     # 0x22590
movq (%rcx,%rdx,8), %rcx
andq 0x40(%rbx), %rcx
andq %rax, %rcx
je 0xd30c
movl %ebp, 0xc(%rsp)
movq %r11, 0x10(%rsp)
bsfq %rcx, %r15
movq %rbx, %rdi
movl %r15d, %esi
callq 0x6586
movl %eax, %r12d
movq %rbx, %rdi
movl 0x8(%rsp), %esi
movl %eax, %edx
callq 0x664c
cmpl $0xc, %eax
jae 0xd311
movl %eax, %r14d
shrl %eax
leaq 0xc52a(%rip), %rcx      # 0x197e0
movl (%rcx,%rax,4), %r13d
movq %rbx, %rdi
movl 0x8(%rsp), %ebp
movl %ebp, %esi
movl 0xc(%rsp), %edx
callq 0xd152
movl %ebp, %esi
movl %eax, %ebp
movq %rbx, %rdi
movl %r14d, %edx
callq 0x664c
movq %rbx, %rdi
movl %r15d, %esi
movl %r12d, %edx
callq 0x642c
movq 0x10(%rsp), %rax
cmpq %rax, 0x150(%rbx)
jne 0xd330
subl %ebp, %r13d
movl %r13d, %eax
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
xorl %r13d, %r13d
jmp 0xd2fa
leaq 0xba06(%rip), %rdi      # 0x18d1e
leaq 0xba0f(%rip), %rsi      # 0x18d2e
leaq 0xba14(%rip), %rcx      # 0x18d3a
movl $0x45, %edx
callq 0x4190
leaq 0xcc33(%rip), %rdi      # 0x19f6a
leaq 0xc927(%rip), %rsi      # 0x19c65
leaq 0xcc49(%rip), %rcx      # 0x19f8e
movl $0x4ce, %edx            # imm = 0x4CE
callq 0x4190
leaq 0xb8c2(%rip), %rdi      # 0x18c18
leaq 0xcf8a(%rip), %rsi      # 0x1a2e7
leaq 0xcf91(%rip), %rcx      # 0x1a2f5
movl $0x68, %edx
callq 0x4190