// File: /workspace/github_cpp_makefile_star2_O3/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
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x138, %rsp            # imm = 0x138
movq %rsi, %r14
movq %rdi, %rbx
movl %edx, -0x38(%rbp)
testl %edx, %edx
je 0x5563
movq %r14, %rdi
callq 0x855c
movb 0x10(%rbx), %dl
movb %al, -0x2a(%rbp)
cmpb %al, %dl
movq %rbx, -0x48(%rbp)
movb %dl, -0x29(%rbp)
jne 0x5583
movb 0x11(%rbx), %al
xorl %ecx, %ecx
movl $0xc4653600, -0x70(%rbp,%rcx,4) # imm = 0xC4653600
incq %rcx
cmpq $0x6, %rcx
jne 0x5543
movzbl %dl, %ecx
incl %ecx
movl %ecx, -0x3c(%rbp)
movl $0xc4653600, %ebx       # imm = 0xC4653600
jmp 0x55b1
movq (%rbx), %rax
movq 0x8(%rax), %rax
movq %rbx, %rdi
movq %r14, %rsi
addq $0x138, %rsp            # imm = 0x138
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmpq *%rax
movzbl %dl, %eax
movl $0x2, %ecx
subl %eax, %ecx
movl %ecx, -0x3c(%rbp)
xorl %eax, %eax
movl $0x3b9aca00, -0x70(%rbp,%rax,4) # imm = 0x3B9ACA00
incq %rax
cmpq $0x6, %rax
jne 0x5592
movl %edx, %eax
xorb $0x1, %al
shlb $0x4, %al
addb $0x31, %al
movl $0x3b9aca00, %ebx       # imm = 0x3B9ACA00
leaq -0x30(%rbp), %r15
movl $0x0, (%r15)
movsbl %al, %eax
movl %eax, -0x40(%rbp)
decl -0x38(%rbp)
xorl %r12d, %r12d
leaq -0x50(%rbp), %r13
movq %r14, %rdi
movq %r15, %rsi
callq 0x850e
btl $0x8, %eax
jb 0x5600
incl %r12d
movl -0x30(%rbp), %eax
movl %eax, %ecx
subl %r12d, %ecx
js 0x5718
movslq %eax, %rdx
movl %ecx, %ecx
movl -0x70(%rbp,%rcx,4), %ecx
movl %ecx, -0x70(%rbp,%rdx,4)
jmp 0x5718
movq %r12, -0x78(%rbp)
movl %ebx, -0x34(%rbp)
movsbl %al, %r15d
subl -0x40(%rbp), %r15d
xorl %r12d, %r12d
movl %r15d, -0x50(%rbp)
movl %r12d, -0x4c(%rbp)
movq %r14, %rdi
movq %r13, %rsi
callq 0x7f74
testb %al, %al
je 0x5699
movq %r14, %rsi
movq %r13, %r14
leaq -0x160(%rbp), %r13
movq %r13, %rdi
movq %rsi, %rbx
callq 0x78e2
movq %r13, %rdi
movq %r14, %r13
movq %r14, %rsi
callq 0x7fea
cmpl -0x3c(%rbp), %eax
je 0x573a
testl %eax, %eax
jne 0x5696
leaq -0x160(%rbp), %r13
movq %r13, %rdi
callq 0x8150
movq -0x48(%rbp), %rdi
movq (%rdi), %rax
movq %r13, %rsi
movq %r14, %r13
movl -0x38(%rbp), %edx
callq *(%rax)
movl -0x34(%rbp), %edx
cmpl %eax, %edx
movl %edx, %ecx
cmovll %eax, %ecx
cmovgl %eax, %edx
movb -0x29(%rbp), %al
cmpb -0x2a(%rbp), %al
cmovel %ecx, %edx
movl %edx, -0x34(%rbp)
movq %rbx, %r14
incl %r12d
cmpl $0x3, %r12d
jne 0x5612
movl -0x30(%rbp), %eax
movslq %eax, %rcx
movl -0x34(%rbp), %ebx
movl %ebx, -0x70(%rbp,%rcx,4)
movq -0x78(%rbp), %rdi
testl %edi, %edi
je 0x56d6
movl -0x74(%rbp,%rcx,4), %edx
movb -0x29(%rbp), %sil
cmpb -0x2a(%rbp), %sil
jne 0x56df
testl %edi, %edi
setle %sil
cmpl %edx, %ebx
setle %dl
jmp 0x56ea
xorl %r12d, %r12d
leaq -0x30(%rbp), %r15
jmp 0x5718
testl %edi, %edi
setle %sil
cmpl %edx, %ebx
setge %dl
orb %sil, %dl
leaq -0x30(%rbp), %r15
jne 0x5715
incl %edi
leaq -0x70(,%rcx,4), %rcx
addq %rbp, %rcx
negq %rdi
movq $-0x1, %rdx
movl %ebx, (%rcx,%rdx,4)
decq %rdx
cmpq %rdx, %rdi
jne 0x570a
xorl %r12d, %r12d
leal 0x1(%rax), %ecx
movl %ecx, -0x30(%rbp)
cmpl $0x5, %eax
jl 0x55cc
xorl %ecx, %ecx
xorl %eax, %eax
addl -0x70(%rbp,%rcx,4), %eax
incq %rcx
cmpq $0x6, %rcx
jne 0x572b
jmp 0x574a
leaq -0x160(%rbp), %rsi
movq -0x48(%rbp), %rdi
callq 0x6da0
addq $0x138, %rsp            # imm = 0x138
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq