// File: codeandkey[P]neocortex/src/position.cpp
// Function: neocortex::Position::Position(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>)
Position::Position(std::string fen) {
	std::vector<std::string> fields = util::split(fen, ' ');

	if (fields.size() != 6) {
		throw util::fmterr("Invalid FEN: expected 6 fields, parsed %d", fields.size());
	}

	board = Board(fields[0]);
	color_to_move = piece::color_from_uci(fields[1][0]);

	reset_history_table();
	
	State first_state;

	first_state.castle_rights = 0;

	for (auto c : fields[2]) {
		switch (c) {
		case 'K':
			first_state.castle_rights |= CASTLE_WHITE_K;
			break;
		case 'Q':
			first_state.castle_rights |= CASTLE_WHITE_Q;
			break;
		case 'k':
			first_state.castle_rights |= CASTLE_BLACK_K;
			break;
		case 'q':
			first_state.castle_rights |= CASTLE_BLACK_Q;
			break;
		}
	}

	first_state.en_passant_square = square::from_uci(fields[3]);
	first_state.halfmove_clock = std::stoi(fields[4]);
	first_state.fullmove_number = std::stoi(fields[5]);

	first_state.captured_piece = piece::null;
	first_state.captured_square = piece::null;
	first_state.last_move = Move::null;

	first_state.key = 0;
	first_state.key ^= board.get_tt_key();
	first_state.key ^= zobrist::en_passant(first_state.en_passant_square);
	first_state.key ^= zobrist::castle(first_state.castle_rights);
	first_state.was_castle = false;
	first_state.was_en_passant = false;

	first_state.in_check = test_check(color_to_move);

	if (color_to_move == piece::BLACK) {
		first_state.key ^= zobrist::black_to_move();
	}

	ply.push_back(first_state);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x2f0, %rsp            # imm = 0x2F0
movq %rsi, -0x278(%rbp)
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq -0x8(%rbp), %rdi
movq %rdi, -0x288(%rbp)
callq 0x7450
movq -0x288(%rbp), %rdi
addq $0x158, %rdi            # imm = 0x158
movq %rdi, -0x280(%rbp)
callq 0x149b0
movq -0x278(%rbp), %rsi
leaq -0x48(%rbp), %rdi
callq 0x5150
jmp 0xc7f6
leaq -0x28(%rbp), %rdi
leaq -0x48(%rbp), %rsi
movl $0x20, %edx
callq 0x21e90
jmp 0xc80a
leaq -0x48(%rbp), %rdi
callq 0x5230
leaq -0x28(%rbp), %rdi
callq 0x88c0
cmpq $0x6, %rax
je 0xc915
movb $0x1, -0x7a(%rbp)
movl $0x8, %edi
callq 0x51b0
movq %rax, -0x298(%rbp)
leaq -0x79(%rbp), %rdi
movq %rdi, -0x290(%rbp)
callq 0x56d0
movq -0x290(%rbp), %rdx
leaq 0x1af37(%rip), %rsi     # 0x27790
leaq -0x78(%rbp), %rdi
callq 0x89b0
jmp 0xc864
leaq -0x28(%rbp), %rdi
callq 0x88c0
movq -0x298(%rbp), %rdi
movq %rax, %rdx
leaq -0x78(%rbp), %rsi
callq 0x88e0
jmp 0xc882
movq -0x298(%rbp), %rdi
movb $0x0, -0x7a(%rbp)
movq 0x2673c(%rip), %rsi     # 0x32fd0
movq 0x2674d(%rip), %rdx     # 0x32fe8
callq 0x5680
jmp 0xcd3b
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
jmp 0xcd26
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
leaq -0x48(%rbp), %rdi
callq 0x5230
jmp 0xcd26
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
jmp 0xc8f3
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
leaq -0x78(%rbp), %rdi
callq 0x5230
leaq -0x79(%rbp), %rdi
callq 0x5480
testb $0x1, -0x7a(%rbp)
jne 0xc904
jmp 0xc910
movq -0x298(%rbp), %rdi
callq 0x5300
jmp 0xcd1d
xorl %eax, %eax
movl %eax, %esi
leaq -0x28(%rbp), %rdi
callq 0x14b30
movq %rax, %rsi
leaq -0x1f8(%rbp), %rdi
callq 0x5150
jmp 0xc933
leaq -0x1d8(%rbp), %rdi
leaq -0x1f8(%rbp), %rsi
callq 0x7510
jmp 0xc948
movq -0x288(%rbp), %rdi
leaq -0x1d8(%rbp), %rsi
movl $0x158, %edx            # imm = 0x158
callq 0x5360
leaq -0x1f8(%rbp), %rdi
callq 0x5230
leaq -0x28(%rbp), %rdi
movl $0x1, %esi
callq 0x14b30
movq %rax, %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x5740
movq %rax, -0x2a0(%rbp)
jmp 0xc98f
movq -0x2a0(%rbp), %rax
movsbl (%rax), %edi
callq 0xbfa0
movl %eax, -0x2a4(%rbp)
jmp 0xc9a6
movq -0x288(%rbp), %rdi
movl -0x2a4(%rbp), %eax
movl %eax, 0x170(%rdi)
callq 0xc710
jmp 0xc9c0
leaq -0x230(%rbp), %rdi
callq 0x149d0
movl $0x0, -0x220(%rbp)
leaq -0x28(%rbp), %rdi
movl $0x2, %esi
callq 0x14b30
movq %rax, -0x238(%rbp)
movq -0x238(%rbp), %rdi
callq 0x5380
movq %rax, -0x240(%rbp)
movq -0x238(%rbp), %rdi
callq 0x5200
movq %rax, -0x248(%rbp)
leaq -0x240(%rbp), %rdi
leaq -0x248(%rbp), %rsi
callq 0x8b20
testb $0x1, %al
jne 0xca2d
jmp 0xcaf7
leaq -0x240(%rbp), %rdi
callq 0x8b60
movb (%rax), %al
movb %al, -0x249(%rbp)
movsbl -0x249(%rbp), %eax
addl $-0x4b, %eax
movl %eax, %ecx
movq %rcx, -0x2b0(%rbp)
subl $0x26, %eax
ja 0xcae4
movq -0x2b0(%rbp), %rax
leaq 0x1a265(%rip), %rcx     # 0x26cd0
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
jmp 0xcd1d
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
leaq -0x1f8(%rbp), %rdi
callq 0x5230
jmp 0xcd1d
movl -0x220(%rbp), %eax
orl $0x1, %eax
movl %eax, -0x220(%rbp)
jmp 0xcae4
movl -0x220(%rbp), %eax
orl $0x2, %eax
movl %eax, -0x220(%rbp)
jmp 0xcae4
movl -0x220(%rbp), %eax
orl $0x4, %eax
movl %eax, -0x220(%rbp)
jmp 0xcae4
movl -0x220(%rbp), %eax
orl $0x8, %eax
movl %eax, -0x220(%rbp)
jmp 0xcae6
leaq -0x240(%rbp), %rdi
callq 0x8c50
jmp 0xca11
leaq -0x28(%rbp), %rdi
movl $0x3, %esi
callq 0x14b30
movq %rax, %rsi
leaq -0x270(%rbp), %rdi
callq 0x5150
jmp 0xcb16
leaq -0x270(%rbp), %rdi
callq 0x1bdd0
movl %eax, -0x2b4(%rbp)
jmp 0xcb2a
movl -0x2b4(%rbp), %eax
movl %eax, -0x224(%rbp)
leaq -0x270(%rbp), %rdi
callq 0x5230
leaq -0x28(%rbp), %rdi
movl $0x4, %esi
callq 0x14b30
movq %rax, %rdi
xorl %eax, %eax
movl %eax, %esi
movl $0xa, %edx
callq 0x14b50
movl %eax, -0x2b8(%rbp)
jmp 0xcb69
movl -0x2b8(%rbp), %eax
movl %eax, -0x214(%rbp)
leaq -0x28(%rbp), %rdi
movl $0x5, %esi
callq 0x14b30
movq %rax, %rdi
xorl %eax, %eax
movl %eax, %esi
movl $0xa, %edx
callq 0x14b50
movl %eax, -0x2bc(%rbp)
jmp 0xcb9c
movq -0x288(%rbp), %rdi
movl -0x2bc(%rbp), %eax
movl %eax, -0x210(%rbp)
movl $0xffffffff, -0x21c(%rbp) # imm = 0xFFFFFFFF
movl $0xffffffff, -0x218(%rbp) # imm = 0xFFFFFFFF
leaq 0x300be(%rip), %rax     # 0x3cc88
movl 0x8(%rax), %ecx
movl %ecx, -0x228(%rbp)
movq (%rax), %rax
movq %rax, -0x230(%rbp)
movq $0x0, -0x200(%rbp)
callq 0x14a40
movq %rax, -0x2c8(%rbp)
jmp 0xcbf6
movq -0x2c8(%rbp), %rcx
movq -0x200(%rbp), %rax
xorq %rcx, %rax
movq %rax, -0x200(%rbp)
movl -0x224(%rbp), %edi
callq 0x23d80
movq %rax, -0x2d0(%rbp)
jmp 0xcc22
movq -0x2d0(%rbp), %rcx
movq -0x200(%rbp), %rax
xorq %rcx, %rax
movq %rax, -0x200(%rbp)
movl -0x220(%rbp), %edi
callq 0x23d30
movq %rax, -0x2d8(%rbp)
jmp 0xcc4e
movq -0x288(%rbp), %rdi
movq -0x2d8(%rbp), %rcx
movq -0x200(%rbp), %rax
xorq %rcx, %rax
movq %rax, -0x200(%rbp)
movb $0x0, -0x207(%rbp)
movb $0x0, -0x208(%rbp)
movl 0x170(%rdi), %esi
callq 0x14b90
movb %al, -0x2d9(%rbp)
jmp 0xcc8e
movq -0x288(%rbp), %rax
movb -0x2d9(%rbp), %cl
andb $0x1, %cl
movzbl %cl, %ecx
movl %ecx, -0x20c(%rbp)
cmpl $0x1, 0x170(%rax)
jne 0xccef
callq 0x23df0
movq %rax, -0x2e8(%rbp)
jmp 0xccbe
movq -0x2e8(%rbp), %rax
xorq -0x200(%rbp), %rax
movq %rax, -0x200(%rbp)
jmp 0xccef
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
leaq -0x270(%rbp), %rdi
callq 0x5230
jmp 0xcd1d
movq -0x288(%rbp), %rdi
addq $0x158, %rdi            # imm = 0x158
leaq -0x230(%rbp), %rsi
callq 0x14a60
jmp 0xcd0b
leaq -0x28(%rbp), %rdi
callq 0x8c90
addq $0x2f0, %rsp            # imm = 0x2F0
popq %rbp
retq
leaq -0x28(%rbp), %rdi
callq 0x8c90
movq -0x280(%rbp), %rdi
callq 0x14ad0
movq -0x50(%rbp), %rdi
callq 0x56c0
nopl (%rax,%rax)