// File: tyhsu[P]Ewn/./minimax1.h
// Function: Minimax1::minimax(Game&, int)
int minimax(Game& cur_game, int height) {
		// check if end;
		if (height == 0) {
			return evaluate_simulation(cur_game);
		}
		int best_val;
		int chs_val_list[6];
		int lookahead_cnt = 0;

		bool is_ai_side;
		int cur_win;
		char cur_symbol;
		if (cur_game.get_is_switch() == this->ai_side) {
			// ai's cur_side		=> the largest, the better
			is_ai_side = true;
			best_val = -1e9;
			cur_win = this->ai_side ? 2 : 1;
			cur_symbol = this->ai_symbol;
			for (int i=0; i<6; i++)
				chs_val_list[i] = -1e9;
		}
		else {
			// opponent's cur_side	=> the smallest, the better
			is_ai_side = false;
			best_val = 1e9;
			cur_win = this->ai_side ? 1 : 2;
			cur_symbol = this->ai_side? '1' : 'A';
			for (int i=0; i<6; i++)
				chs_val_list[i] = 1e9;
		}

		// ai's cur_side, find the max
		// opponent's cur_side, find the min
		for (int dice = 0; dice < 6; dice++) {
			Chess cur_chs = cur_game.get_cur_chs_list(dice);
			if (cur_chs.exist) {
				int chs_index = cur_chs.symbol - cur_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 == cur_win) return evaluate_feature(child_game);
						else if (game_status != 0) continue;
						child_game.switch_player();

						// return child value.
						int child_val = minimax(child_game, height-1);
						if (is_ai_side) {
							best_val = max(best_val, child_val);
						}
						else {
							best_val = min(best_val, child_val);
						}
					}
					else {
					}
				}
				chs_val_list[dice] = best_val;

				// if there is lookahead_cnt, compare those values of the non-existing with the existing
				// check if the current value is bigger than the previous one.
				if (lookahead_cnt) {
					int offset;
					if ((is_ai_side && best_val>chs_val_list[dice-1]) || (!is_ai_side && best_val<chs_val_list[dice-1])) {
						for (int j = 1; j <= lookahead_cnt; j++) {
							offset = dice - j;
							chs_val_list[offset] = best_val;
						}
					}
					lookahead_cnt = 0;
				}
			}
			else {
				// this chess can't move, use other's value
				lookahead_cnt++;
				if (dice - lookahead_cnt < 0) {
					// there's no chess exists before the selected one
					continue;
				}
				else {
					chs_val_list[dice] = chs_val_list[dice - lookahead_cnt];
				}
			}
		}

		// return the sum of the best values in the chs_val_list (chance node)
		best_val = 0;
		for(int i = 0; i < 6; i++)
			best_val += chs_val_list[i];

		return best_val;
	}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x1a0, %rsp            # imm = 0x1A0
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
movl %edx, -0x1c(%rbp)
movq -0x10(%rbp), %rax
movq %rax, -0x190(%rbp)
cmpl $0x0, -0x1c(%rbp)
jne 0x58d0
movq -0x190(%rbp), %rdi
movq -0x18(%rbp), %rsi
movq (%rdi), %rax
callq *0x8(%rax)
movl %eax, -0x4(%rbp)
jmp 0x5c2e
movl $0x0, -0x44(%rbp)
movq -0x18(%rbp), %rdi
callq 0xb910
movq -0x190(%rbp), %rcx
andb $0x1, %al
movzbl %al, %eax
movb 0x10(%rcx), %cl
andb $0x1, %cl
movzbl %cl, %ecx
cmpl %ecx, %eax
jne 0x594f
movq -0x190(%rbp), %rax
movb $0x1, -0x45(%rbp)
movl $0xc4653600, -0x20(%rbp) # imm = 0xC4653600
movb 0x10(%rax), %sil
movl $0x1, %ecx
movl $0x2, %edx
testb $0x1, %sil
cmovnel %edx, %ecx
movl %ecx, -0x4c(%rbp)
movb 0x11(%rax), %al
movb %al, -0x4d(%rbp)
movl $0x0, -0x54(%rbp)
cmpl $0x6, -0x54(%rbp)
jge 0x594d
movslq -0x54(%rbp), %rax
movl $0xc4653600, -0x40(%rbp,%rax,4) # imm = 0xC4653600
movl -0x54(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x54(%rbp)
jmp 0x5930
jmp 0x59cc
movq -0x190(%rbp), %rax
movb $0x0, -0x45(%rbp)
movl $0x3b9aca00, -0x20(%rbp) # imm = 0x3B9ACA00
movb 0x10(%rax), %sil
movl $0x2, %ecx
movl $0x1, %edx
testb $0x1, %sil
cmovnel %edx, %ecx
movl %ecx, -0x4c(%rbp)
movb 0x10(%rax), %cl
movb $0x31, %al
movb $0x41, %dl
movb %dl, -0x192(%rbp)
testb $0x1, %cl
movb %al, -0x191(%rbp)
jne 0x599d
movb -0x192(%rbp), %al
movb %al, -0x191(%rbp)
movb -0x191(%rbp), %al
movb %al, -0x4d(%rbp)
movl $0x0, -0x58(%rbp)
cmpl $0x6, -0x58(%rbp)
jge 0x59ca
movslq -0x58(%rbp), %rax
movl $0x3b9aca00, -0x40(%rbp,%rax,4) # imm = 0x3B9ACA00
movl -0x58(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x58(%rbp)
jmp 0x59ad
jmp 0x59cc
movl $0x0, -0x5c(%rbp)
cmpl $0x6, -0x5c(%rbp)
jge 0x5bec
movq -0x18(%rbp), %rdi
leaq -0x5c(%rbp), %rsi
callq 0xb810
movl %edx, -0x70(%rbp)
movq %rax, -0x78(%rbp)
movq -0x78(%rbp), %rax
movq %rax, -0x68(%rbp)
movl -0x70(%rbp), %eax
movl %eax, -0x60(%rbp)
testb $0x1, -0x67(%rbp)
je 0x5bb0
movsbl -0x68(%rbp), %eax
movsbl -0x4d(%rbp), %ecx
subl %ecx, %eax
movl %eax, -0x7c(%rbp)
movl $0x0, -0x80(%rbp)
cmpl $0x3, -0x80(%rbp)
jge 0x5b21
leaq -0x88(%rbp), %rdi
leaq -0x7c(%rbp), %rsi
leaq -0x80(%rbp), %rdx
callq 0x5c40
movq -0x18(%rbp), %rdi
leaq -0x88(%rbp), %rsi
callq 0xafe0
testb $0x1, %al
jne 0x5a54
jmp 0x5b0f
movq -0x18(%rbp), %rsi
leaq -0x170(%rbp), %rdi
callq 0xa520
leaq -0x170(%rbp), %rdi
leaq -0x88(%rbp), %rsi
callq 0xb120
movl %eax, -0x174(%rbp)
movl -0x174(%rbp), %eax
cmpl -0x4c(%rbp), %eax
jne 0x5aa3
movq -0x190(%rbp), %rdi
leaq -0x170(%rbp), %rsi
callq 0x8190
movl %eax, -0x4(%rbp)
jmp 0x5c2e
cmpl $0x0, -0x174(%rbp)
je 0x5aae
jmp 0x5b13
jmp 0x5ab0
leaq -0x170(%rbp), %rdi
callq 0xb440
movq -0x190(%rbp), %rdi
movl -0x1c(%rbp), %edx
subl $0x1, %edx
movq (%rdi), %rax
leaq -0x170(%rbp), %rsi
callq *(%rax)
movl %eax, -0x178(%rbp)
testb $0x1, -0x45(%rbp)
je 0x5af8
leaq -0x20(%rbp), %rdi
leaq -0x178(%rbp), %rsi
callq 0x5c70
movl (%rax), %eax
movl %eax, -0x20(%rbp)
jmp 0x5b0d
leaq -0x20(%rbp), %rdi
leaq -0x178(%rbp), %rsi
callq 0x5cb0
movl (%rax), %eax
movl %eax, -0x20(%rbp)
jmp 0x5b11
jmp 0x5b11
jmp 0x5b13
movl -0x80(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x80(%rbp)
jmp 0x5a1d
movl -0x20(%rbp), %ecx
movslq -0x5c(%rbp), %rax
movl %ecx, -0x40(%rbp,%rax,4)
cmpl $0x0, -0x44(%rbp)
je 0x5bae
testb $0x1, -0x45(%rbp)
je 0x5b4a
movl -0x20(%rbp), %eax
movl -0x5c(%rbp), %ecx
subl $0x1, %ecx
movslq %ecx, %rcx
cmpl -0x40(%rbp,%rcx,4), %eax
jg 0x5b62
testb $0x1, -0x45(%rbp)
jne 0x5ba7
movl -0x20(%rbp), %eax
movl -0x5c(%rbp), %ecx
subl $0x1, %ecx
movslq %ecx, %rcx
cmpl -0x40(%rbp,%rcx,4), %eax
jge 0x5ba7
movl $0x1, -0x180(%rbp)
movl -0x180(%rbp), %eax
cmpl -0x44(%rbp), %eax
jg 0x5ba5
movl -0x5c(%rbp), %eax
subl -0x180(%rbp), %eax
movl %eax, -0x17c(%rbp)
movl -0x20(%rbp), %ecx
movslq -0x17c(%rbp), %rax
movl %ecx, -0x40(%rbp,%rax,4)
movl -0x180(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x180(%rbp)
jmp 0x5b6c
jmp 0x5ba7
movl $0x0, -0x44(%rbp)
jmp 0x5bdc
movl -0x44(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x44(%rbp)
movl -0x5c(%rbp), %eax
subl -0x44(%rbp), %eax
cmpl $0x0, %eax
jge 0x5bc6
jmp 0x5bde
movl -0x5c(%rbp), %eax
subl -0x44(%rbp), %eax
cltq
movl -0x40(%rbp,%rax,4), %ecx
movslq -0x5c(%rbp), %rax
movl %ecx, -0x40(%rbp,%rax,4)
jmp 0x5bdc
jmp 0x5bde
movl -0x5c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x5c(%rbp)
jmp 0x59d3
movl $0x0, -0x20(%rbp)
movl $0x0, -0x184(%rbp)
cmpl $0x6, -0x184(%rbp)
jge 0x5c28
movslq -0x184(%rbp), %rax
movl -0x40(%rbp,%rax,4), %eax
addl -0x20(%rbp), %eax
movl %eax, -0x20(%rbp)
movl -0x184(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x184(%rbp)
jmp 0x5bfd
movl -0x20(%rbp), %eax
movl %eax, -0x4(%rbp)
movl -0x4(%rbp), %eax
addq $0x1a0, %rsp            # imm = 0x1A0
popq %rbp
retq
nopw (%rax,%rax)