// File: tyhsu[P]Ewn/mcts.cpp
// Function: MCTS::run(Game const&)
int MCTS::run(const Game& cur_game) {
	// initialize root Tree_node with current state
	Tree_node* root_node_ptr = new Tree_node(cur_game);

	int iteration = 0;  // nodes
	while(iteration++ < this->max_iterations) {
		// 1. select
		// Start from the root, digging down until finding an unvistied node
		Tree_node* node_ptr = root_node_ptr;
		int best_child_index;
		// The root has been visited
		if (root_node_ptr->is_visit()) {
			while(!node_ptr->is_terminate()) {
				best_child_index = this->selection_ptr->select_children_list_index(node_ptr);
				node_ptr = node_ptr->get_child_ptr(best_child_index);
				// The next child pointer hasn't been visited
				if(!node_ptr->is_visit()) {
					break;
				}
			}
		}

		int win_reward;
		if (node_ptr->is_terminate()) {
			win_reward = node_ptr->get_game_status() == (this->ai_side? 2: 1);
		}
		else {
			// 2. expand by adding a single child (if not terminal or not fully expanded)
			node_ptr->new_child_nodes();
			
			// 3. simulate
			win_reward = this->simulation(node_ptr->game);
		}

		// 4. back propagation
		while(true) {
			node_ptr->update(win_reward);
			if(node_ptr->get_parent_ptr() == NULL) break;
			node_ptr = node_ptr->get_parent_ptr();
		}
	}

	int result = root_node_ptr->get_win_count();
	this->recursive_delete_tree_node(root_node_ptr);
	return result;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x50, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0x50(%rbp)
movl $0x190, %edi            # imm = 0x190
callq 0x2160
movq %rax, %rdi
movq %rdi, %rax
movq %rax, -0x48(%rbp)
movq -0x10(%rbp), %rsi
callq 0x7610
jmp 0x6d37
movq -0x48(%rbp), %rax
movq %rax, -0x18(%rbp)
movl $0x0, -0x28(%rbp)
movq -0x50(%rbp), %rcx
movl -0x28(%rbp), %eax
movl %eax, %edx
addl $0x1, %edx
movl %edx, -0x28(%rbp)
cmpl 0x4(%rcx), %eax
jge 0x6e70
movq -0x18(%rbp), %rax
movq %rax, -0x30(%rbp)
movq -0x18(%rbp), %rdi
callq 0x79a0
testb $0x1, %al
jne 0x6d75
jmp 0x6ddf
jmp 0x6d77
movq -0x30(%rbp), %rdi
callq 0x7980
xorb $-0x1, %al
testb $0x1, %al
jne 0x6d88
jmp 0x6ddd
movq -0x50(%rbp), %rax
movq 0x8(%rax), %rdi
movq -0x30(%rbp), %rsi
movq (%rdi), %rax
callq *(%rax)
movl %eax, -0x34(%rbp)
movq -0x30(%rbp), %rdi
leaq -0x34(%rbp), %rsi
callq 0x7a80
movq %rax, -0x30(%rbp)
movq -0x30(%rbp), %rdi
callq 0x79a0
testb $0x1, %al
jne 0x6ddb
jmp 0x6ddd
movq -0x48(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x20(%rbp)
movl %eax, -0x24(%rbp)
movl $0x190, %esi            # imm = 0x190
callq 0x2170
jmp 0x6e92
jmp 0x6d77
jmp 0x6ddf
movq -0x30(%rbp), %rdi
callq 0x7980
testb $0x1, %al
jne 0x6dee
jmp 0x6e1e
movq -0x30(%rbp), %rdi
callq 0x7a40
movq -0x50(%rbp), %rcx
movb (%rcx), %sil
movl $0x1, %ecx
movl $0x2, %edx
testb $0x1, %sil
cmovnel %edx, %ecx
cmpl %ecx, %eax
sete %al
andb $0x1, %al
movzbl %al, %eax
movl %eax, -0x38(%rbp)
jmp 0x6e3b
movq -0x30(%rbp), %rdi
callq 0x7670
movq -0x50(%rbp), %rdi
movq -0x30(%rbp), %rsi
addq $0x10, %rsi
callq 0x6ea0
movl %eax, -0x38(%rbp)
jmp 0x6e3d
movq -0x30(%rbp), %rdi
cvtsi2ssl -0x38(%rbp), %xmm0
callq 0x79e0
movq -0x30(%rbp), %rdi
callq 0x7a60
cmpq $0x0, %rax
jne 0x6e5c
jmp 0x6e6b
movq -0x30(%rbp), %rdi
callq 0x7a60
movq %rax, -0x30(%rbp)
jmp 0x6e3d
jmp 0x6d46
movq -0x18(%rbp), %rdi
callq 0x7a10
movq -0x50(%rbp), %rdi
movl %eax, -0x3c(%rbp)
movq -0x18(%rbp), %rsi
callq 0x7150
movl -0x3c(%rbp), %eax
addq $0x50, %rsp
popq %rbp
retq
movq -0x20(%rbp), %rdi
callq 0x2210
nopl (%rax,%rax)