// File: tewalds[P]morat/hex/../lib/policy_instantwin.h
// Function: Morat::InstantWin<Morat::Hex::Board>::choose_move(Morat::Hex::Board const&, Morat::Move const&)
Move choose_move(const Board & board, const Move & prev) {
		if(saved_loss != M_UNKNOWN)
			return saved_loss;

		if(cur_rollout_moves++ >= max_rollout_moves)
			return M_UNKNOWN;

		//must have an edge connection, or it has nothing to offer a group towards a win
		const auto * c = board.cell(prev);
		if(c->numedges() == 0)
			return M_UNKNOWN;

		MoveValid start, cur, loss = M_UNKNOWN;
		Side turn = ~board.to_play();

		//find the first empty cell
		int dir = -1;
		const MoveValid* neighbors = board.neighbors(prev);
		for(int i = 0; i < 6; i++){
			start = neighbors[i];

			if(!board.on_board(start) || board.get(start) != turn){
				dir = (i + 5) % 6;
				break;
			}
		}

		if(dir == -1) //possible if it's in the middle of a ring
			return M_UNKNOWN;

		cur = start;

//		logerr(board.to_s(true));
//		logerr(prev.to_s() + ":");

		//follow contour of the current group looking for wins
		do{
//			logerr(" " + cur.to_s());
			//check the current cell
			if(board.on_board(cur) && board.get(cur) == Side::NONE && board.test_outcome(cur, turn) == +turn){
//				logerr(" loss");
				if(loss == M_UNKNOWN){
					loss = cur;
				}else if(loss != cur){
					saved_loss = loss;
					return cur; //game over, two wins found for opponent
				}
			}

			//advance to the next cell
			const MoveValid* neighbors = board.neighbors(cur);
			for(int i = 5; i <= 9; i++){
				int nd = (dir + i) % 6;
				MoveValid next = neighbors[nd];

				if(!board.on_board(next) || board.get(next) != turn){
					cur = next;
					dir = nd;
					break;
				}
			}
		}while(cur != start); //potentially skips part of it when the start is in a pocket, rare bug

//		logerr("\n");

		return loss; // usually M_UNKNOWN
	}

// Assembly:
subq $0x88, %rsp
movq %rdi, 0x78(%rsp)
movq %rsi, 0x70(%rsp)
movq %rdx, 0x68(%rsp)
movq 0x78(%rsp), %rdi
movq %rdi, 0x8(%rsp)
addq $0x8, %rdi
movl $0xfffffffc, 0x64(%rsp) # imm = 0xFFFFFFFC
leaq 0x64(%rsp), %rsi
callq 0x2a390
testb $0x1, %al
jne 0x29fec
jmp 0x2a002
movq 0x8(%rsp), %rax
movw 0x8(%rax), %ax
movw %ax, 0x86(%rsp)
jmp 0x2a37a
movq 0x8(%rsp), %rcx
movl 0x4(%rcx), %eax
movl %eax, %edx
addl $0x1, %edx
movl %edx, 0x4(%rcx)
cmpl (%rcx), %eax
jl 0x2a02d
leaq 0x86(%rsp), %rdi
movl $0xfffffffc, %esi       # imm = 0xFFFFFFFC
callq 0xff00
jmp 0x2a37a
movq 0x70(%rsp), %rdi
movq 0x68(%rsp), %rsi
callq 0x2c7e0
movq %rax, 0x58(%rsp)
movq 0x58(%rsp), %rdi
callq 0x2c820
cmpl $0x0, %eax
jne 0x2a067
leaq 0x86(%rsp), %rdi
movl $0xfffffffc, %esi       # imm = 0xFFFFFFFC
callq 0xff00
jmp 0x2a37a
leaq 0x54(%rsp), %rdi
movl $0xfffffffc, %esi       # imm = 0xFFFFFFFC
callq 0x1fdf0
leaq 0x50(%rsp), %rdi
movl $0xfffffffc, %esi       # imm = 0xFFFFFFFC
callq 0x1fdf0
leaq 0x4c(%rsp), %rdi
movl $0xfffffffc, %esi       # imm = 0xFFFFFFFC
callq 0x1fdf0
movq 0x70(%rsp), %rdi
callq 0x1a8a0
movb %al, 0x4a(%rsp)
movzbl 0x4a(%rsp), %edi
callq 0x1c680
movb %al, 0x4b(%rsp)
movl $0xffffffff, 0x44(%rsp) # imm = 0xFFFFFFFF
movq 0x70(%rsp), %rdi
movq 0x68(%rsp), %rsi
callq 0x29bd0
movq %rax, 0x38(%rsp)
movl $0x0, 0x34(%rsp)
cmpl $0x6, 0x34(%rsp)
jge 0x2a165
movq 0x38(%rsp), %rax
movslq 0x34(%rsp), %rcx
movl (%rax,%rcx,4), %eax
movl %eax, 0x54(%rsp)
movq 0x70(%rsp), %rdi
leaq 0x54(%rsp), %rsi
callq 0x29c10
movb %al, %cl
movb $0x1, %al
testb $0x1, %cl
movb %al, 0x7(%rsp)
jne 0x2a10e
jmp 0x2a134
movq 0x70(%rsp), %rdi
leaq 0x54(%rsp), %rsi
callq 0x29c30
movb %al, 0x33(%rsp)
leaq 0x33(%rsp), %rdi
leaq 0x4b(%rsp), %rsi
callq 0x29c60
movb %al, 0x7(%rsp)
movb 0x7(%rsp), %al
testb $0x1, %al
jne 0x2a13e
jmp 0x2a153
movl 0x34(%rsp), %eax
addl $0x5, %eax
movl $0x6, %ecx
cltd
idivl %ecx
movl %edx, 0x44(%rsp)
jmp 0x2a165
jmp 0x2a155
movl 0x34(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x34(%rsp)
jmp 0x2a0d4
cmpl $-0x1, 0x44(%rsp)
jne 0x2a183
leaq 0x86(%rsp), %rdi
movl $0xfffffffc, %esi       # imm = 0xFFFFFFFC
callq 0xff00
jmp 0x2a37a
movl 0x54(%rsp), %eax
movl %eax, 0x50(%rsp)
movq 0x70(%rsp), %rdi
leaq 0x50(%rsp), %rsi
callq 0x29c10
movb %al, %cl
xorl %eax, %eax
testb $0x1, %cl
movb %al, 0x6(%rsp)
jne 0x2a1a9
jmp 0x2a225
movq 0x70(%rsp), %rdi
leaq 0x50(%rsp), %rsi
callq 0x29c30
movb %al, 0x32(%rsp)
leaq 0x32(%rsp), %rdi
leaq 0x432f3(%rip), %rsi     # 0x6d4bb
callq 0x1f930
movb %al, %cl
xorl %eax, %eax
testb $0x1, %cl
movb %al, 0x6(%rsp)
jne 0x2a1dc
jmp 0x2a225
movq 0x70(%rsp), %rdi
movb 0x4b(%rsp), %al
movb %al, 0x30(%rsp)
leaq 0x50(%rsp), %rsi
movzbl 0x30(%rsp), %edx
callq 0x29460
movb %al, 0x31(%rsp)
movb 0x4b(%rsp), %al
movb %al, 0x2e(%rsp)
movzbl 0x2e(%rsp), %edi
callq 0x1fba0
movb %al, 0x2f(%rsp)
leaq 0x31(%rsp), %rdi
leaq 0x2f(%rsp), %rsi
callq 0x1c810
movb %al, 0x6(%rsp)
movb 0x6(%rsp), %al
testb $0x1, %al
jne 0x2a22f
jmp 0x2a296
leaq 0x2a(%rsp), %rdi
movl $0xfffffffc, %esi       # imm = 0xFFFFFFFC
callq 0x1fdf0
leaq 0x4c(%rsp), %rdi
leaq 0x2a(%rsp), %rsi
callq 0x2c840
testb $0x1, %al
jne 0x2a253
jmp 0x2a25d
movl 0x50(%rsp), %eax
movl %eax, 0x4c(%rsp)
jmp 0x2a294
leaq 0x4c(%rsp), %rdi
leaq 0x50(%rsp), %rsi
callq 0x1fe50
testb $0x1, %al
jne 0x2a272
jmp 0x2a292
movq 0x8(%rsp), %rax
movw 0x4c(%rsp), %cx
movw %cx, 0x8(%rax)
movw 0x50(%rsp), %ax
movw %ax, 0x86(%rsp)
jmp 0x2a37a
jmp 0x2a294
jmp 0x2a296
movq 0x70(%rsp), %rdi
leaq 0x50(%rsp), %rsi
callq 0x2b460
movq %rax, 0x20(%rsp)
movl $0x5, 0x1c(%rsp)
cmpl $0x9, 0x1c(%rsp)
jg 0x2a354
movl 0x44(%rsp), %eax
addl 0x1c(%rsp), %eax
movl $0x6, %ecx
cltd
idivl %ecx
movl %edx, 0x18(%rsp)
movq 0x20(%rsp), %rax
movslq 0x18(%rsp), %rcx
movl (%rax,%rcx,4), %eax
movl %eax, 0x14(%rsp)
movq 0x70(%rsp), %rdi
leaq 0x14(%rsp), %rsi
callq 0x29c10
movb %al, %cl
movb $0x1, %al
testb $0x1, %cl
movb %al, 0x5(%rsp)
jne 0x2a300
jmp 0x2a326
movq 0x70(%rsp), %rdi
leaq 0x14(%rsp), %rsi
callq 0x29c30
movb %al, 0x13(%rsp)
leaq 0x13(%rsp), %rdi
leaq 0x4b(%rsp), %rsi
callq 0x29c60
movb %al, 0x5(%rsp)
movb 0x5(%rsp), %al
testb $0x1, %al
jne 0x2a330
jmp 0x2a342
movl 0x14(%rsp), %eax
movl %eax, 0x50(%rsp)
movl 0x18(%rsp), %eax
movl %eax, 0x44(%rsp)
jmp 0x2a354
jmp 0x2a344
movl 0x1c(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x1c(%rsp)
jmp 0x2a2b2
jmp 0x2a356
leaq 0x50(%rsp), %rdi
leaq 0x54(%rsp), %rsi
callq 0x1fe50
testb $0x1, %al
jne 0x2a18b
movw 0x4c(%rsp), %ax
movw %ax, 0x86(%rsp)
movw 0x86(%rsp), %ax
addq $0x88, %rsp
retq
nopw (%rax,%rax)