// File: tewalds[P]morat/havannah/board.cpp
// Function: Morat::Havannah::Board::checkring_o1(Morat::MoveValid const&, Morat::Side) const
bool Board::checkring_o1(const MoveValid & pos, const Side turn) const {
	static const unsigned char ringdata[64][10] = {
		{0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, //000000
		{0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, //000001
		{0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, //000010
		{0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, //000011
		{0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, //000100
		{1, 3, 5, 0, 0, 0, 0, 0, 0, 0}, //000101
		{0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, //000110
		{3,16,10, 9, 0, 0, 0, 0, 0, 0}, //000111
		{0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, //001000
		{1, 2, 5, 0, 0, 0, 0, 0, 0, 0}, //001001
		{1, 2, 4, 0, 0, 0, 0, 0, 0, 0}, //001010
		{1, 2, 4, 0, 0, 0, 0, 0, 0, 0}, //001011
		{0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, //001100
		{1, 2, 5, 0, 0, 0, 0, 0, 0, 0}, //001101
		{3,15, 9, 8, 0, 0, 0, 0, 0, 0}, //001110
		{4,16,10, 9,15, 8, 9, 0, 0, 0}, //001111
		{0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, //010000
		{1, 1, 5, 0, 0, 0, 0, 0, 0, 0}, //010001
		{1, 1, 4, 0, 0, 0, 0, 0, 0, 0}, //010010
		{1, 1, 4, 0, 0, 0, 0, 0, 0, 0}, //010011
		{1, 1, 3, 0, 0, 0, 0, 0, 0, 0}, //010100
		{2, 1, 3, 5, 0, 0, 0, 0, 0, 0}, //010101
		{1, 1, 3, 0, 0, 0, 0, 0, 0, 0}, //010110
		{7,16,10, 9, 1, 3, 0, 0, 0, 0}, //010111
		{0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, //011000
		{1, 1, 5, 0, 0, 0, 0, 0, 0, 0}, //011001
		{1, 1, 4, 0, 0, 0, 0, 0, 0, 0}, //011010
		{1, 1, 4, 0, 0, 0, 0, 0, 0, 0}, //011011
		{3,14, 8, 7, 0, 0, 0, 0, 0, 0}, //011100
		{7,14, 8, 7, 1, 5, 0, 0, 0, 0}, //011101
		{4,15, 9, 8,14, 7, 8, 0, 0, 0}, //011110
		{5,16,10, 9,15, 8, 9,14, 8, 7}, //011111
		{0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, //100000
		{0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, //100001
		{1, 0, 4, 0, 0, 0, 0, 0, 0, 0}, //100010
		{3,17,11,10, 0, 0, 0, 0, 0, 0}, //100011
		{1, 0, 3, 0, 0, 0, 0, 0, 0, 0}, //100100
		{1, 0, 3, 0, 0, 0, 0, 0, 0, 0}, //100101
		{1, 0, 3, 0, 0, 0, 0, 0, 0, 0}, //100110
		{4,17,11,10,16, 9,10, 0, 0, 0}, //100111
		{1, 0, 2, 0, 0, 0, 0, 0, 0, 0}, //101000
		{1, 0, 2, 0, 0, 0, 0, 0, 0, 0}, //101001
		{2, 0, 2, 4, 0, 0, 0, 0, 0, 0}, //101010
		{7,17,11,10, 0, 2, 0, 0, 0, 0}, //101011
		{1, 0, 2, 0, 0, 0, 0, 0, 0, 0}, //101100
		{1, 0, 2, 0, 0, 0, 0, 0, 0, 0}, //101101
		{7,15, 9, 8, 0, 2, 0, 0, 0, 0}, //101110
		{5,17,11,10,16, 9,10,15, 9, 8}, //101111
		{0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, //110000
		{3,12, 6,11, 0, 0, 0, 0, 0, 0}, //110001
		{1, 0, 4, 0, 0, 0, 0, 0, 0, 0}, //110010
		{4,12, 6,11,17,10,11, 0, 0, 0}, //110011
		{1, 0, 3, 0, 0, 0, 0, 0, 0, 0}, //110100
		{7,12, 6,11, 0, 3, 0, 0, 0, 0}, //110101
		{1, 0, 3, 0, 0, 0, 0, 0, 0, 0}, //110110
		{5,12, 6,11,17,10,11,16,10, 9}, //110111
		{3,13, 7, 6, 0, 0, 0, 0, 0, 0}, //111000
		{4,13, 7, 6,12,11, 6, 0, 0, 0}, //111001
		{7,13, 7, 6, 0, 4, 0, 0, 0, 0}, //111010
		{5,13, 7, 6,12,11, 6,17,11,10}, //111011
		{4,14, 8, 7,13, 6, 7, 0, 0, 0}, //111100
		{5,14, 8, 7,13, 6, 7,12, 6,11}, //111101
		{5,15, 9, 8,14, 7, 8,13, 7, 6}, //111110
		{6, 0, 0, 0, 0, 0, 0, 0, 0, 0}, //111111
	};

	int bitpattern = 0;
	const MoveValid * s = neighbors(pos);
	for (auto m : neighbors_small(pos)) {
		bitpattern <<= 1;
		if(m.on_board() && turn == get(m.xy))
			bitpattern |= 1;
	}

	const unsigned char * d = ringdata[bitpattern];

	switch(d[0]){
		case 0: //no ring (000000, 000001, 000011)
			return false;

		case 1: //simple case (000101, 001101, 001011, 011011)
			return (find_group(s[d[1]]) == find_group(s[d[2]]));

		case 2:{ //3 non-neighbors (010101)
			int a = find_group(s[d[1]]), b = find_group(s[d[2]]), c = find_group(s[d[3]]);
			return (a == b || a == c || b == c);
		}

		case 7: //case 1 and 3 (010111)
			if(find_group(s[d[4]]) == find_group(s[d[5]]))
				return true;
			//fall through

		case 3: // 3 neighbors (000111)
			return checkring_back(s[d[1]], s[d[2]], s[d[3]], turn);

		case 4: // 4 neighbors (001111)
			return checkring_back(s[d[1]], s[d[2]], s[d[3]], turn) ||
			       checkring_back(s[d[4]], s[d[5]], s[d[6]], turn);

		case 5: // 5 neighbors (011111)
			return checkring_back(s[d[1]], s[d[2]], s[d[3]], turn) ||
			       checkring_back(s[d[4]], s[d[5]], s[d[6]], turn) ||
			       checkring_back(s[d[7]], s[d[8]], s[d[9]], turn);

		case 6: // 6 neighbors (111111)
			return true; //a ring around this position? how'd that happen

		default:
			return false;
	}
}

// Assembly:
subq $0xa8, %rsp
movb %dl, %al
movb %al, 0xa6(%rsp)
movq %rdi, 0x98(%rsp)
movq %rsi, 0x90(%rsp)
movq 0x98(%rsp), %rdi
movq %rdi, 0x28(%rsp)
movl $0x0, 0x8c(%rsp)
movq 0x90(%rsp), %rsi
callq 0x2c830
movq 0x28(%rsp), %rdi
movq %rax, 0x80(%rsp)
movq 0x90(%rsp), %rsi
callq 0x1fe50
movq %rax, 0x68(%rsp)
movq %rdx, 0x70(%rsp)
leaq 0x68(%rsp), %rax
movq %rax, 0x78(%rsp)
movq 0x78(%rsp), %rdi
callq 0x11810
movq %rax, 0x60(%rsp)
movq 0x78(%rsp), %rdi
callq 0x11820
movq %rax, 0x58(%rsp)
movq 0x60(%rsp), %rax
cmpq 0x58(%rsp), %rax
je 0x38c1e
movq 0x60(%rsp), %rax
movl (%rax), %eax
movl %eax, 0x54(%rsp)
movl 0x8c(%rsp), %eax
shll %eax
movl %eax, 0x8c(%rsp)
leaq 0x54(%rsp), %rdi
callq 0x11830
movb %al, %cl
xorl %eax, %eax
testb $0x1, %cl
movb %al, 0x27(%rsp)
jne 0x38bc5
jmp 0x38bee
movq 0x28(%rsp), %rdi
movswl 0x56(%rsp), %esi
callq 0x1fed0
movb %al, 0x53(%rsp)
leaq 0xa6(%rsp), %rdi
leaq 0x53(%rsp), %rsi
callq 0x1fe90
movb %al, 0x27(%rsp)
movb 0x27(%rsp), %al
testb $0x1, %al
jne 0x38bf8
jmp 0x38c09
movl 0x8c(%rsp), %eax
orl $0x1, %eax
movl %eax, 0x8c(%rsp)
jmp 0x38c0b
movq 0x60(%rsp), %rax
addq $0x4, %rax
movq %rax, 0x60(%rsp)
jmp 0x38b81
movslq 0x8c(%rsp), %rax
leaq (%rax,%rax,4), %rcx
leaq 0x18c6f(%rip), %rax     # 0x518a0
leaq (%rax,%rcx,2), %rax
movq %rax, 0x48(%rsp)
movq 0x48(%rsp), %rax
movzbl (%rax), %eax
movq %rax, 0x18(%rsp)
subq $0x7, %rax
ja 0x390a6
movq 0x18(%rsp), %rax
leaq 0x18c23(%rip), %rcx     # 0x51880
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movb $0x0, 0xa7(%rsp)
jmp 0x390ae
movq 0x28(%rsp), %rdi
movq 0x80(%rsp), %rsi
movq 0x48(%rsp), %rax
movzbl 0x1(%rax), %eax
shlq $0x2, %rax
addq %rax, %rsi
callq 0x395b0
movq 0x28(%rsp), %rdi
movl %eax, 0x14(%rsp)
movq 0x80(%rsp), %rsi
movq 0x48(%rsp), %rax
movzbl 0x2(%rax), %eax
shlq $0x2, %rax
addq %rax, %rsi
callq 0x395b0
movl %eax, %ecx
movl 0x14(%rsp), %eax
cmpl %ecx, %eax
sete %al
andb $0x1, %al
movb %al, 0xa7(%rsp)
jmp 0x390ae
movq 0x28(%rsp), %rdi
movq 0x80(%rsp), %rsi
movq 0x48(%rsp), %rax
movzbl 0x1(%rax), %eax
shlq $0x2, %rax
addq %rax, %rsi
callq 0x395b0
movq 0x28(%rsp), %rdi
movl %eax, 0x44(%rsp)
movq 0x80(%rsp), %rsi
movq 0x48(%rsp), %rax
movzbl 0x2(%rax), %eax
shlq $0x2, %rax
addq %rax, %rsi
callq 0x395b0
movq 0x28(%rsp), %rdi
movl %eax, 0x40(%rsp)
movq 0x80(%rsp), %rsi
movq 0x48(%rsp), %rax
movzbl 0x3(%rax), %eax
shlq $0x2, %rax
addq %rax, %rsi
callq 0x395b0
movl %eax, 0x3c(%rsp)
movl 0x44(%rsp), %ecx
movb $0x1, %al
cmpl 0x40(%rsp), %ecx
movb %al, 0x13(%rsp)
je 0x38d75
movl 0x44(%rsp), %ecx
movb $0x1, %al
cmpl 0x3c(%rsp), %ecx
movb %al, 0x13(%rsp)
je 0x38d75
movl 0x40(%rsp), %eax
cmpl 0x3c(%rsp), %eax
sete %al
movb %al, 0x13(%rsp)
movb 0x13(%rsp), %al
andb $0x1, %al
movb %al, 0xa7(%rsp)
jmp 0x390ae
movq 0x28(%rsp), %rdi
movq 0x80(%rsp), %rsi
movq 0x48(%rsp), %rax
movzbl 0x4(%rax), %eax
shlq $0x2, %rax
addq %rax, %rsi
callq 0x395b0
movq 0x28(%rsp), %rdi
movl %eax, 0xc(%rsp)
movq 0x80(%rsp), %rsi
movq 0x48(%rsp), %rax
movzbl 0x5(%rax), %eax
shlq $0x2, %rax
addq %rax, %rsi
callq 0x395b0
movl %eax, %ecx
movl 0xc(%rsp), %eax
cmpl %ecx, %eax
jne 0x38de6
movb $0x1, 0xa7(%rsp)
jmp 0x390ae
jmp 0x38de8
movq 0x28(%rsp), %rdi
movq 0x80(%rsp), %rsi
movq 0x48(%rsp), %rax
movzbl 0x1(%rax), %eax
shlq $0x2, %rax
addq %rax, %rsi
movq 0x80(%rsp), %rdx
movq 0x48(%rsp), %rax
movzbl 0x2(%rax), %eax
shlq $0x2, %rax
addq %rax, %rdx
movq 0x80(%rsp), %rcx
movq 0x48(%rsp), %rax
movzbl 0x3(%rax), %eax
shlq $0x2, %rax
addq %rax, %rcx
movb 0xa6(%rsp), %al
movb %al, 0x3b(%rsp)
movzbl 0x3b(%rsp), %r8d
callq 0x390c0
andb $0x1, %al
movb %al, 0xa7(%rsp)
jmp 0x390ae
movq 0x28(%rsp), %rdi
movq 0x80(%rsp), %rsi
movq 0x48(%rsp), %rax
movzbl 0x1(%rax), %eax
shlq $0x2, %rax
addq %rax, %rsi
movq 0x80(%rsp), %rdx
movq 0x48(%rsp), %rax
movzbl 0x2(%rax), %eax
shlq $0x2, %rax
addq %rax, %rdx
movq 0x80(%rsp), %rcx
movq 0x48(%rsp), %rax
movzbl 0x3(%rax), %eax
shlq $0x2, %rax
addq %rax, %rcx
movb 0xa6(%rsp), %al
movb %al, 0x3a(%rsp)
movzbl 0x3a(%rsp), %r8d
callq 0x390c0
movb %al, %cl
movb $0x1, %al
testb $0x1, %cl
movb %al, 0xb(%rsp)
jne 0x38f30
movq 0x28(%rsp), %rdi
movq 0x80(%rsp), %rsi
movq 0x48(%rsp), %rax
movzbl 0x4(%rax), %eax
shlq $0x2, %rax
addq %rax, %rsi
movq 0x80(%rsp), %rdx
movq 0x48(%rsp), %rax
movzbl 0x5(%rax), %eax
shlq $0x2, %rax
addq %rax, %rdx
movq 0x80(%rsp), %rcx
movq 0x48(%rsp), %rax
movzbl 0x6(%rax), %eax
shlq $0x2, %rax
addq %rax, %rcx
movb 0xa6(%rsp), %al
movb %al, 0x39(%rsp)
movzbl 0x39(%rsp), %r8d
callq 0x390c0
movb %al, 0xb(%rsp)
movb 0xb(%rsp), %al
andb $0x1, %al
movb %al, 0xa7(%rsp)
jmp 0x390ae
movq 0x28(%rsp), %rdi
movq 0x80(%rsp), %rsi
movq 0x48(%rsp), %rax
movzbl 0x1(%rax), %eax
shlq $0x2, %rax
addq %rax, %rsi
movq 0x80(%rsp), %rdx
movq 0x48(%rsp), %rax
movzbl 0x2(%rax), %eax
shlq $0x2, %rax
addq %rax, %rdx
movq 0x80(%rsp), %rcx
movq 0x48(%rsp), %rax
movzbl 0x3(%rax), %eax
shlq $0x2, %rax
addq %rax, %rcx
movb 0xa6(%rsp), %al
movb %al, 0x38(%rsp)
movzbl 0x38(%rsp), %r8d
callq 0x390c0
movb %al, %cl
movb $0x1, %al
testb $0x1, %cl
movb %al, 0xa(%rsp)
jne 0x3908d
movq 0x28(%rsp), %rdi
movq 0x80(%rsp), %rsi
movq 0x48(%rsp), %rax
movzbl 0x4(%rax), %eax
shlq $0x2, %rax
addq %rax, %rsi
movq 0x80(%rsp), %rdx
movq 0x48(%rsp), %rax
movzbl 0x5(%rax), %eax
shlq $0x2, %rax
addq %rax, %rdx
movq 0x80(%rsp), %rcx
movq 0x48(%rsp), %rax
movzbl 0x6(%rax), %eax
shlq $0x2, %rax
addq %rax, %rcx
movb 0xa6(%rsp), %al
movb %al, 0x37(%rsp)
movzbl 0x37(%rsp), %r8d
callq 0x390c0
movb %al, %cl
movb $0x1, %al
testb $0x1, %cl
movb %al, 0xa(%rsp)
jne 0x3908d
movq 0x28(%rsp), %rdi
movq 0x80(%rsp), %rsi
movq 0x48(%rsp), %rax
movzbl 0x7(%rax), %eax
shlq $0x2, %rax
addq %rax, %rsi
movq 0x80(%rsp), %rdx
movq 0x48(%rsp), %rax
movzbl 0x8(%rax), %eax
shlq $0x2, %rax
addq %rax, %rdx
movq 0x80(%rsp), %rcx
movq 0x48(%rsp), %rax
movzbl 0x9(%rax), %eax
shlq $0x2, %rax
addq %rax, %rcx
movb 0xa6(%rsp), %al
movb %al, 0x36(%rsp)
movzbl 0x36(%rsp), %r8d
callq 0x390c0
movb %al, 0xa(%rsp)
movb 0xa(%rsp), %al
andb $0x1, %al
movb %al, 0xa7(%rsp)
jmp 0x390ae
movb $0x1, 0xa7(%rsp)
jmp 0x390ae
movb $0x0, 0xa7(%rsp)
movb 0xa7(%rsp), %al
andb $0x1, %al
addq $0xa8, %rsp
retq
nop