// File: tewalds[P]morat/havannah/board.h
// Function: Morat::Havannah::Board::move(Morat::MoveValid const&, bool, bool)
bool move(const MoveValid & pos, bool checkwin = true, bool permanent = true) {
		assert(!outcome_.solved());

		if(!valid_move(pos))
			return false;

		last_move_ = pos;
		num_moves_++;

		Cell& cell = cells_[pos.xy];
		cell.piece = to_play_;
		cell.perm = permanent;

		update_hash(pos, to_play_); //depends on num_moves_
		update_pattern(pos, to_play_);

		// join the groups for win detection
		bool alreadyjoined = false; //useful for finding rings
		auto it = neighbors_small(pos);
		for (const MoveValid *i = it.begin(), *e = it.end(); i < e; i++) {
			if(i->on_board() && to_play_ == get(i->xy)){
				alreadyjoined |= join_groups(pos.xy, i->xy);
				i++; //skip the next one. If it is the same group,
					 //it is already connected and forms a corner, which we can ignore
			}
		}

		if(checkwin){
			Cell * g = & cells_[find_group(pos.xy)];
			if(g->numedges() >= 3){
				outcome_ = +to_play_;
				win_type_ = 0;
			}else if(g->numcorners() >= 2){
				outcome_ = +to_play_;
				win_type_ = 1;
			}else if(check_rings && alreadyjoined && g->size >= 6 && checkring_df(pos, to_play_)){
				outcome_ = +to_play_;
				win_type_ = 2;
			}else if(num_moves_ == num_cells_){
				outcome_ = Outcome::DRAW;
			}
		}

		to_play_ = ~to_play_;

		return true;
	}

// Assembly:
subq $0x98, %rsp
movb %cl, %al
movb %dl, %cl
movq %rdi, 0x88(%rsp)
movq %rsi, 0x80(%rsp)
andb $0x1, %cl
movb %cl, 0x7f(%rsp)
andb $0x1, %al
movb %al, 0x7e(%rsp)
movq 0x88(%rsp), %rdi
movq %rdi, 0x20(%rsp)
addq $0xb, %rdi
callq 0x1cce0
xorb $-0x1, %al
testb $0x1, %al
jne 0x1f626
jmp 0x1f628
jmp 0x1f647
leaq 0x3038e(%rip), %rdi     # 0x4f9bd
leaq 0x2f23b(%rip), %rsi     # 0x4e871
movl $0x131, %edx            # imm = 0x131
leaq 0x3038e(%rip), %rcx     # 0x4f9d0
callq 0x52a0
movq 0x20(%rsp), %rdi
movq 0x80(%rsp), %rsi
callq 0x1f9a0
testb $0x1, %al
jne 0x1f66a
movb $0x0, 0x97(%rsp)
jmp 0x1f98e
movq 0x20(%rsp), %rdi
movq 0x80(%rsp), %rax
movw (%rax), %ax
movw %ax, 0x8(%rdi)
movw 0x6(%rdi), %ax
addw $0x1, %ax
movw %ax, 0x6(%rdi)
addq $0x10, %rdi
movq 0x80(%rsp), %rax
movswq 0x2(%rax), %rsi
callq 0x11630
movq 0x20(%rsp), %rdi
movq %rax, 0x70(%rsp)
movq 0x70(%rsp), %rax
movb 0xa(%rdi), %cl
movb %cl, (%rax)
movb 0x7e(%rsp), %cl
andb $0x1, %cl
movq 0x70(%rsp), %rax
movb %cl, 0x7(%rax)
movq 0x80(%rsp), %rsi
movb 0xa(%rdi), %al
movb %al, 0x6f(%rsp)
movzbl 0x6f(%rsp), %edx
callq 0x1fa10
movq 0x20(%rsp), %rdi
movq 0x80(%rsp), %rsi
movb 0xa(%rdi), %al
movb %al, 0x6e(%rsp)
movzbl 0x6e(%rsp), %edx
callq 0x1fd50
movq 0x20(%rsp), %rdi
movb $0x0, 0x6d(%rsp)
movq 0x80(%rsp), %rsi
callq 0x1fe50
movq %rax, 0x58(%rsp)
movq %rdx, 0x60(%rsp)
leaq 0x58(%rsp), %rdi
callq 0x11810
movq %rax, 0x50(%rsp)
leaq 0x58(%rsp), %rdi
callq 0x11820
movq %rax, 0x48(%rsp)
movq 0x50(%rsp), %rax
cmpq 0x48(%rsp), %rax
jae 0x1f800
movq 0x50(%rsp), %rdi
callq 0x11830
movb %al, %cl
xorl %eax, %eax
testb $0x1, %cl
movb %al, 0x1f(%rsp)
jne 0x1f762
jmp 0x1f798
movq 0x20(%rsp), %rdi
movq %rdi, %rax
addq $0xa, %rax
movq %rax, 0x10(%rsp)
movq 0x50(%rsp), %rax
movswl 0x2(%rax), %esi
callq 0x1fed0
movq 0x10(%rsp), %rdi
movb %al, 0x47(%rsp)
leaq 0x47(%rsp), %rsi
callq 0x1fe90
movb %al, 0x1f(%rsp)
movb 0x1f(%rsp), %al
testb $0x1, %al
jne 0x1f7a2
jmp 0x1f7eb
movq 0x20(%rsp), %rdi
movq 0x80(%rsp), %rax
movswl 0x2(%rax), %esi
movq 0x50(%rsp), %rax
movswl 0x2(%rax), %edx
callq 0x1ff00
andb $0x1, %al
movzbl %al, %ecx
movb 0x6d(%rsp), %al
andb $0x1, %al
movzbl %al, %eax
orl %ecx, %eax
cmpl $0x0, %eax
setne %al
andb $0x1, %al
movb %al, 0x6d(%rsp)
movq 0x50(%rsp), %rax
addq $0x4, %rax
movq %rax, 0x50(%rsp)
jmp 0x1f7ed
movq 0x50(%rsp), %rax
addq $0x4, %rax
movq %rax, 0x50(%rsp)
jmp 0x1f739
testb $0x1, 0x7f(%rsp)
je 0x1f95e
movq 0x20(%rsp), %rdi
movq %rdi, %rax
addq $0x10, %rax
movq %rax, 0x8(%rsp)
movq 0x80(%rsp), %rax
movswl 0x2(%rax), %esi
callq 0x20080
movq 0x8(%rsp), %rdi
movslq %eax, %rsi
callq 0x11630
movq %rax, 0x38(%rsp)
movq 0x38(%rsp), %rdi
callq 0x20130
cmpl $0x3, %eax
jl 0x1f87f
movq 0x20(%rsp), %rax
movb 0xa(%rax), %al
movb %al, 0x36(%rsp)
movzbl 0x36(%rsp), %edi
callq 0x20150
movb %al, %cl
movq 0x20(%rsp), %rax
movb %cl, 0x37(%rsp)
movb 0x37(%rsp), %cl
movb %cl, 0xb(%rax)
movb $0x0, 0xc(%rax)
jmp 0x1f95c
movq 0x38(%rsp), %rdi
callq 0x20180
cmpl $0x2, %eax
jl 0x1f8bf
movq 0x20(%rsp), %rax
movb 0xa(%rax), %al
movb %al, 0x34(%rsp)
movzbl 0x34(%rsp), %edi
callq 0x20150
movb %al, %cl
movq 0x20(%rsp), %rax
movb %cl, 0x35(%rsp)
movb 0x35(%rsp), %cl
movb %cl, 0xb(%rax)
movb $0x1, 0xc(%rax)
jmp 0x1f95a
movq 0x20(%rsp), %rax
testb $0x1, 0x98(%rax)
je 0x1f934
testb $0x1, 0x6d(%rsp)
je 0x1f934
movq 0x38(%rsp), %rax
movzbl 0x1(%rax), %eax
cmpl $0x6, %eax
jl 0x1f934
movq 0x20(%rsp), %rdi
movq 0x80(%rsp), %rsi
movb 0xa(%rdi), %al
movb %al, 0x33(%rsp)
movzbl 0x33(%rsp), %edx
callq 0x38880
testb $0x1, %al
jne 0x1f906
jmp 0x1f934
movq 0x20(%rsp), %rax
movb 0xa(%rax), %al
movb %al, 0x31(%rsp)
movzbl 0x31(%rsp), %edi
callq 0x20150
movb %al, %cl
movq 0x20(%rsp), %rax
movb %cl, 0x32(%rsp)
movb 0x32(%rsp), %cl
movb %cl, 0xb(%rax)
movb $0x2, 0xc(%rax)
jmp 0x1f958
movq 0x20(%rsp), %rcx
movswl 0x6(%rcx), %eax
movswl 0x4(%rcx), %ecx
cmpl %ecx, %eax
jne 0x1f956
movq 0x20(%rsp), %rax
leaq 0x4fb92(%rip), %rcx     # 0x6f4e3
movb (%rcx), %cl
movb %cl, 0xb(%rax)
jmp 0x1f958
jmp 0x1f95a
jmp 0x1f95c
jmp 0x1f95e
movq 0x20(%rsp), %rax
movb 0xa(%rax), %al
movb %al, 0x2f(%rsp)
movzbl 0x2f(%rsp), %edi
callq 0x1c850
movb %al, %cl
movq 0x20(%rsp), %rax
movb %cl, 0x30(%rsp)
movb 0x30(%rsp), %cl
movb %cl, 0xa(%rax)
movb $0x1, 0x97(%rsp)
movb 0x97(%rsp), %al
andb $0x1, %al
addq $0x98, %rsp
retq
nop