// File: vygr[P]C-Chess/chess.cpp
// Function: main
int main(int, const char *[])
{
	//setup first board, loop for white..black..white..black...
	auto game_start_time = std::chrono::high_resolution_clock::now();
	auto brd = board("rnbqkbnrpppppppp                                PPPPPPPPRNBQKBNR");
	//auto brd = board("rnb kbnrpppppppp                                PPPPPPPPRNBQKBNR");
	//auto brd = board(" k                         Q P     Q P  K                       ");
	//auto brd = board(" k                           P     Q P  K                       ");
	//auto brd = board("        p         k    p   rb         p      r              K   ");
	//auto brd = board("        p         k    p   r          p      r              K   ");
	//auto brd = board("                   k               K         Q                  ");
	//auto brd = board("    k     R                               K                      ");
	//auto brd = board("   k              KBB                                            ");
	auto history = boards{};
	auto colour = white;
	display_board(brd);
	for (;;)
	{
		auto end_time = std::chrono::high_resolution_clock::now();
		std::chrono::duration<double> elapsed = end_time - game_start_time;
		std::cout << "\nElapsed Time: " << elapsed.count() << "\n";
		if (colour == white)
		{
			std::cout << "White to move:\n";
		}
		else
		{
			std::cout << "Black to move:\n";
		}
		auto new_brd = best_move(brd, colour, history);
		if (new_brd == "")
		{
			std::size_t king_index = 0;
			if (in_check(brd, colour, king_index))
			{
				std::cout << "\n** Checkmate **\n";
			}
			else
			{
				std::cout << "\n** Stalemate **\n";
			}
			break;
		}
		auto rep = std::count(begin(history), end(history), brd);
		if (rep >= 3)
		{
			std::cout << "\n** Draw **\n";
			break;
		}
		history.push_back(new_brd);
		for (auto i = 0; i < 3; ++i)
		{
			display_board(brd);
			std::this_thread::sleep_for(std::chrono::duration<float>(0.1));
			display_board(new_brd);
			std::this_thread::sleep_for(std::chrono::duration<float>(0.1));
		}
		colour = -colour;
		brd = new_brd;
	}
	return 0;
}

// Assembly:
subq $0x138, %rsp            # imm = 0x138
movl $0x0, 0x134(%rsp)
movl %edi, 0x130(%rsp)
movq %rsi, 0x128(%rsp)
callq 0x2050
movq %rax, 0x120(%rsp)
leaq 0xff(%rsp), %rdi
movq %rdi, 0x40(%rsp)
callq 0x2390
movq 0x40(%rsp), %rdx
leaq 0x147a6(%rip), %rsi     # 0x1ac62
leaq 0x100(%rsp), %rdi
callq 0x22e0
jmp 0x64cb
leaq 0xff(%rsp), %rdi
callq 0x2260
xorps %xmm0, %xmm0
movaps %xmm0, 0xd0(%rsp)
movq $0x0, 0xe0(%rsp)
leaq 0xd0(%rsp), %rdi
callq 0xb2a0
movl $0x1, 0xcc(%rsp)
leaq 0x100(%rsp), %rdi
callq 0x44e0
jmp 0x6516
jmp 0x6518
callq 0x2050
movq %rax, 0xc0(%rsp)
leaq 0xc0(%rsp), %rdi
leaq 0x120(%rsp), %rsi
callq 0xadb0
movq %rax, 0x38(%rsp)
jmp 0x6541
movq 0x38(%rsp), %rax
movq %rax, 0xb0(%rsp)
leaq 0xb8(%rsp), %rdi
leaq 0xb0(%rsp), %rsi
callq 0xb2b0
jmp 0x6565
movq 0x1fa64(%rip), %rdi     # 0x25fd0
leaq 0x14730(%rip), %rsi     # 0x1aca3
callq 0x2210
movq %rax, 0x30(%rsp)
jmp 0x657f
leaq 0xb8(%rsp), %rdi
callq 0xb2f0
movsd %xmm0, 0x28(%rsp)
jmp 0x6594
movsd 0x28(%rsp), %xmm0
movq 0x30(%rsp), %rdi
callq 0x23b0
movq %rax, 0x20(%rsp)
jmp 0x65ab
movq 0x20(%rsp), %rdi
leaq 0x1473e(%rip), %rsi     # 0x1acf5
callq 0x2210
jmp 0x65be
cmpl $0x1, 0xcc(%rsp)
jne 0x661e
movq 0x1fa01(%rip), %rdi     # 0x25fd0
leaq 0x146dd(%rip), %rsi     # 0x1acb3
callq 0x2210
jmp 0x65dd
jmp 0x6635
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0xf0(%rsp)
movl %eax, 0xec(%rsp)
leaq 0xff(%rsp), %rdi
callq 0x2260
jmp 0x690b
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0xf0(%rsp)
movl %eax, 0xec(%rsp)
jmp 0x68f1
movq 0x1f9ab(%rip), %rdi     # 0x25fd0
leaq 0x14697(%rip), %rsi     # 0x1acc3
callq 0x2210
jmp 0x6633
jmp 0x6635
movl 0xcc(%rsp), %edx
leaq 0x90(%rsp), %rdi
leaq 0x100(%rsp), %rsi
leaq 0xd0(%rsp), %rcx
callq 0x5d40
jmp 0x665b
leaq 0x14694(%rip), %rsi     # 0x1acf6
leaq 0x90(%rsp), %rdi
callq 0xb300
movb %al, 0x1f(%rsp)
jmp 0x6675
movb 0x1f(%rsp), %al
testb $0x1, %al
jne 0x6682
jmp 0x671e
movq $0x0, 0x88(%rsp)
movl 0xcc(%rsp), %esi
leaq 0x100(%rsp), %rdi
leaq 0x88(%rsp), %rdx
callq 0x4800
movb %al, 0x1e(%rsp)
jmp 0x66b0
movb 0x1e(%rsp), %al
testb $0x1, %al
jne 0x66ba
jmp 0x66f7
movq 0x1f90f(%rip), %rdi     # 0x25fd0
leaq 0x1460b(%rip), %rsi     # 0x1acd3
callq 0x2210
jmp 0x66cf
jmp 0x670e
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0xf0(%rsp)
movl %eax, 0xec(%rsp)
leaq 0x90(%rsp), %rdi
callq 0x2140
jmp 0x68f1
movq 0x1f8d2(%rip), %rdi     # 0x25fd0
leaq 0x145e0(%rip), %rsi     # 0x1ace5
callq 0x2210
jmp 0x670c
jmp 0x670e
movl $0x2, 0x84(%rsp)
jmp 0x6891
leaq 0xd0(%rsp), %rdi
callq 0xb380
movq %rax, 0x10(%rsp)
jmp 0x6732
movq 0x10(%rsp), %rax
movq %rax, 0x70(%rsp)
leaq 0xd0(%rsp), %rdi
callq 0xb3b0
movq %rax, 0x8(%rsp)
jmp 0x6750
movq 0x8(%rsp), %rax
movq %rax, 0x68(%rsp)
movq 0x70(%rsp), %rdi
movq 0x68(%rsp), %rsi
leaq 0x100(%rsp), %rdx
callq 0xb330
movq %rax, (%rsp)
jmp 0x6777
movq (%rsp), %rax
movq %rax, 0x78(%rsp)
cmpq $0x3, 0x78(%rsp)
jl 0x67ad
movq 0x1f841(%rip), %rdi     # 0x25fd0
leaq 0x14561(%rip), %rsi     # 0x1acf7
callq 0x2210
jmp 0x679d
movl $0x2, 0x84(%rsp)
jmp 0x6891
leaq 0xd0(%rsp), %rdi
leaq 0x90(%rsp), %rsi
callq 0xb3e0
jmp 0x67c4
movl $0x0, 0x64(%rsp)
cmpl $0x3, 0x64(%rsp)
jge 0x685f
leaq 0x100(%rsp), %rdi
callq 0x44e0
jmp 0x67e6
movabsq $0x3fb999999999999a, %rax # imm = 0x3FB999999999999A
movq %rax, 0x58(%rsp)
leaq 0x60(%rsp), %rdi
leaq 0x58(%rsp), %rsi
callq 0xb520
jmp 0x6806
leaq 0x60(%rsp), %rdi
callq 0xb450
jmp 0x6812
leaq 0x90(%rsp), %rdi
callq 0x44e0
jmp 0x6821
movabsq $0x3fb999999999999a, %rax # imm = 0x3FB999999999999A
movq %rax, 0x48(%rsp)
leaq 0x54(%rsp), %rdi
leaq 0x48(%rsp), %rsi
callq 0xb520
jmp 0x6841
leaq 0x54(%rsp), %rdi
callq 0xb450
jmp 0x684d
jmp 0x684f
movl 0x64(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x64(%rsp)
jmp 0x67cc
movl 0xcc(%rsp), %eax
negl %eax
movl %eax, 0xcc(%rsp)
leaq 0x100(%rsp), %rdi
leaq 0x90(%rsp), %rsi
callq 0x2030
jmp 0x6886
movl $0x0, 0x84(%rsp)
leaq 0x90(%rsp), %rdi
callq 0x2140
movl 0x84(%rsp), %eax
testl %eax, %eax
je 0x68ad
jmp 0x68ab
jmp 0x68b2
jmp 0x6518
movl $0x0, 0x134(%rsp)
movl $0x1, 0x84(%rsp)
leaq 0xd0(%rsp), %rdi
callq 0xb550
leaq 0x100(%rsp), %rdi
callq 0x2140
movl 0x134(%rsp), %eax
addq $0x138, %rsp            # imm = 0x138
retq
leaq 0xd0(%rsp), %rdi
callq 0xb550
leaq 0x100(%rsp), %rdi
callq 0x2140
movq 0xf0(%rsp), %rdi
callq 0x2380
nopl (%rax,%rax)