// File: tyhsu[P]Ewn/minimax.cpp
// Function: Minimax::AI_move(Game&, int)
Movement Minimax::AI_move(Game& cur_game, int dice)
{
    //cerr << "calculating..." ;
    //cerr.flush();
	clock_t init_time = clock();
	this->ai_side = cur_game.get_is_switch();
	this->ai_symbol = this->ai_side? 'A': '1';

	Movement answer;	//the best move will return
	int best_val = -1e9, child_val;
	int win = this->ai_side? 2: 1;
	int next_move_cnt = cur_game.count_movable_chs(dice);

	for (int i=0; i<next_move_cnt; i++) {
		int chs_index = cur_game.get_movable_chs(i).symbol - this->ai_symbol;
		for (int direct = 0; direct < 3; direct++) {
			Movement mvmt(chs_index, direct);
			if (cur_game.check_in_board(mvmt)) {
				Game child_game = cur_game;
				int game_status = child_game.update_game_status(mvmt);
				// check if the game ends
				if (game_status == win)
					child_val = evaluate_feature(child_game);
				else if (game_status != 0)	// lose the game
					continue;
				else {
					child_game.switch_player();
					child_val = minimax(child_game, HEIGHT);
				}
				// update the best value and the best movement
				if (child_val >= best_val) {
					best_val = child_val;
					answer = mvmt;
				}
			}
		}
	}
	double timeCost = (double)(clock() - init_time) / CLOCKS_PER_SEC;
	//printf("\ntime cost: %.2fs\n", timeCost);
	return answer;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x180, %rsp            # imm = 0x180
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
movl %edx, -0x1c(%rbp)
movq -0x10(%rbp), %rax
movq %rax, -0x178(%rbp)
callq 0x20b0
movq %rax, -0x28(%rbp)
movq -0x18(%rbp), %rdi
callq 0xb910
movb %al, %cl
movq -0x178(%rbp), %rax
andb $0x1, %cl
movb %cl, 0x10(%rax)
movb 0x10(%rax), %cl
movb $0x41, %al
movb $0x31, %dl
movb %dl, -0x16a(%rbp)
testb $0x1, %cl
movb %al, -0x169(%rbp)
jne 0x7fd6
movb -0x16a(%rbp), %al
movb %al, -0x169(%rbp)
movq -0x178(%rbp), %rax
movb -0x169(%rbp), %cl
movb %cl, 0x11(%rax)
leaq -0x8(%rbp), %rdi
callq 0x4c60
movq -0x178(%rbp), %rax
movl $0xc4653600, -0x2c(%rbp) # imm = 0xC4653600
movb 0x10(%rax), %dl
movl $0x1, %eax
movl $0x2, %ecx
testb $0x1, %dl
cmovnel %ecx, %eax
movl %eax, -0x34(%rbp)
movq -0x18(%rbp), %rdi
leaq -0x1c(%rbp), %rsi
callq 0xada0
movl %eax, -0x38(%rbp)
movl $0x0, -0x3c(%rbp)
movl -0x3c(%rbp), %eax
cmpl -0x38(%rbp), %eax
jge 0x815c
movq -0x18(%rbp), %rdi
leaq -0x3c(%rbp), %rsi
callq 0xb7c0
movq -0x178(%rbp), %rcx
movl %edx, -0x58(%rbp)
movq %rax, -0x60(%rbp)
movq -0x60(%rbp), %rax
movq %rax, -0x4c(%rbp)
movl -0x58(%rbp), %eax
movl %eax, -0x44(%rbp)
movsbl -0x4c(%rbp), %eax
movsbl 0x11(%rcx), %ecx
subl %ecx, %eax
movl %eax, -0x40(%rbp)
movl $0x0, -0x64(%rbp)
cmpl $0x3, -0x64(%rbp)
jge 0x814c
leaq -0x6c(%rbp), %rdi
leaq -0x40(%rbp), %rsi
leaq -0x64(%rbp), %rdx
callq 0x5c40
movq -0x18(%rbp), %rdi
leaq -0x6c(%rbp), %rsi
callq 0xafe0
testb $0x1, %al
jne 0x80a4
jmp 0x813c
movq -0x18(%rbp), %rsi
leaq -0x158(%rbp), %rdi
callq 0xa520
leaq -0x158(%rbp), %rdi
leaq -0x6c(%rbp), %rsi
callq 0xb120
movl %eax, -0x15c(%rbp)
movl -0x15c(%rbp), %eax
cmpl -0x34(%rbp), %eax
jne 0x80ed
movq -0x178(%rbp), %rdi
leaq -0x158(%rbp), %rsi
callq 0x8190
movl %eax, -0x30(%rbp)
jmp 0x811f
cmpl $0x0, -0x15c(%rbp)
je 0x80f8
jmp 0x813e
leaq -0x158(%rbp), %rdi
callq 0xb440
movq -0x178(%rbp), %rdi
movl 0x8(%rdi), %edx
movq (%rdi), %rax
leaq -0x158(%rbp), %rsi
callq *(%rax)
movl %eax, -0x30(%rbp)
jmp 0x811f
movl -0x30(%rbp), %eax
cmpl -0x2c(%rbp), %eax
jl 0x813a
movl -0x30(%rbp), %eax
movl %eax, -0x2c(%rbp)
leaq -0x8(%rbp), %rdi
leaq -0x6c(%rbp), %rsi
callq 0x6a30
jmp 0x813c
jmp 0x813e
movl -0x64(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x64(%rbp)
jmp 0x8073
jmp 0x814e
movl -0x3c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x3c(%rbp)
jmp 0x802a
callq 0x20b0
subq -0x28(%rbp), %rax
cvtsi2sd %rax, %xmm0
movsd 0x4f3e(%rip), %xmm1     # 0xd0b0
divsd %xmm1, %xmm0
movsd %xmm0, -0x168(%rbp)
movq -0x8(%rbp), %rax
addq $0x180, %rsp            # imm = 0x180
popq %rbp
retq
nopl (%rax,%rax)