// File: /workspace/github_cpp_makefile_star2_O1/Alcaro[P]bridges/solver.cpp
// Function: gamemap::solve()
bool solve()
	{
//puts("SOLVEBEGIN");
		possibilities = possibilities_buf;
		
		int num_roots = 0;
		
		//make sure that existing bridges are labeled as such on all tiles they're on
		//'map' is known correct, but anything other than that should use set_state
		
		for (int y=0;y<map.height;y++)
		for (int x=0;x<map.width;x++)
		{
			nextjoined[y*100+x] = y*100+x;
		}
		
		for (int y=0;y<map.height;y++)
		for (int x=0;x<map.width;x++)
		{
			gamemap::island& here = map.map[y][x];
			int index = y*100+x;
			
			if (here.rootnode != index)
			{
				int tmp = nextjoined[here.rootnode];
				nextjoined[here.rootnode] = nextjoined[index];
				nextjoined[index] = tmp;
			}
			
			if (here.rootnode == index && here.population > 0) num_roots++;
			
			uint16_t flags = 0x000F;
			for (int dir=0;dir<4;dir++)
			{
				if (here.bridgelen[dir] != -1) flags |= 0x0110<<dir;
				if (op!=op_another && op!=op_difficulty && here.bridges[dir] == 1) flags &= ~(0x0001<<dir);
				if (op!=op_another && op!=op_difficulty && here.bridges[dir] == 2) flags &= ~(0x0011<<dir);
				if (here.bridges[dir] == 3) { flags &= ~(0x0111<<dir); flags |= 0x1000<<dir; }
			}
			possibilities[index] = flags;
		}
		
		if (map.numislands == 0) return (op!=op_another);
		if (op==op_hint || op==op_difficulty) accumulator=0;
		
		//block 1s and 2s from using both of their bindings towards each other
		if (num_roots > 2) // except if that's the only two islands
		{
			for (int y=0;y<map.height;y++)
			for (int x=0;x<map.width;x++)
			{
				gamemap::island& here = map.map[y][x];
				uint16_t flags = possibilities[y*100+x];
				uint16_t newflags = flags;
				
				//keep the pointless flags&0x1234 checks, here.bridgelen[0] is undefined if the relevant flag isn't set
				//this isn't a pure performance optimization - the isolation rule processor ignores pop-1 islands,
				//  so without this, it could claim the map '1111' is solvable
				if (here.population == 2 && (flags&0x0100) && map.map[y][x+here.bridgelen[0]].population == 2)
					newflags &= ~0x0100;
				if (here.population == 1 && (flags&0x0010) && map.map[y][x+here.bridgelen[0]].population == 1)
					newflags &= ~0x0010;
				
				if (here.population == 2 && (flags&0x0800) && map.map[y+here.bridgelen[3]][x].population == 2)
					newflags &= ~0x0800;
				if (here.population == 1 && (flags&0x0080) && map.map[y+here.bridgelen[3]][x].population == 1)
					newflags &= ~0x0080;
				
				if (flags != newflags)
				{
//printf("%.3i(%.3i) %.4X->%.4X\n",y*100+x,here.population,flags,newflags);
					if (!set_state(y*100+x, newflags)) return false;
				}
			}
		}
		
		for (int y=0;y<map.height;y++)
		for (int x=0;x<map.width;x++)
		{
			if (map.map[y][x].rootnode != y*100+x) continue; // only poke the roots, no point doing duplicate checks
			if (!fill_simple(y*100+x)) return false;
		}
		
		if (op==op_hint && accumulator) return false;
		
		if (op == op_hint || op == op_difficulty)
		{
			int maxdepth = 1;
		again: ;
			int ret = solve_rec(0, maxdepth);
			if (ret == 0) return false;
			if (ret == -1) { maxdepth++; goto again; }
			maxdepth--; // needs at least depth 1, or it won't notice that it's finished. this should not contribute to difficulty
			add_difficulty(100*maxdepth*maxdepth);
#ifndef STDOUT_ERROR
if(maxdepth>=2)puts("#######"),puts(map.serialize()),puts("#######");
#endif
		}
		else
		{
			if (solve_rec(0, 0) <= 0) return false;
		}
		
		if (op==op_hint || op==op_difficulty) return false; // return value for these operations is irrelevant
		
		assign();
		return true;
	}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0xc8378, %rsp          # imm = 0xC8378
leaq 0x4e70(%rsp), %rax
movq %rdi, -0x4e30(%rax)
movq %rax, -0x8(%rax)
movslq 0x4(%rdi), %rax
movb $0x1, %cl
testq %rax, %rax
setg 0xf(%rsp)
jle 0x25f64
movl (%rdi), %ecx
xorl %edx, %edx
xorl %esi, %esi
movq %rdx, %r9
movq %rcx, %r8
testl %ecx, %ecx
jle 0x25e1a
movw %r9w, 0x48(%rsp,%r9,2)
incq %r9
decq %r8
jne 0x25e0c
incq %rsi
addq $0x64, %rdx
cmpq %rax, %rsi
jne 0x25e02
movb $0x1, %cl
testl %eax, %eax
jle 0x25f64
movl (%rdi), %edx
leaq 0xc(%rdi), %rcx
movq %rcx, 0x20(%rsp)
movq %rdi, 0x18(%rsp)
leaq 0x14(%rdi), %r12
xorl %r9d, %r9d
movl $0xffff, %r10d          # imm = 0xFFFF
xorl %ebx, %ebx
xorl %r11d, %r11d
movq %rax, 0x28(%rsp)
testl %edx, %edx
movq %r12, 0x10(%rsp)
jle 0x25f3b
imulq $0x64, %rbx, %r14
imulq $0x4b0, %rbx, %r15      # imm = 0x4B0
addq 0x20(%rsp), %r15
xorl %r13d, %r13d
leaq (,%r13,2), %rsi
addq %r13, %rsi
leaq (%r14,%r13), %rbp
movswq 0x2(%r15,%rsi,4), %rcx
movl %ecx, %edi
cmpq %rdi, %rbp
jne 0x25ea5
leaq (%r15,%rsi,4), %rcx
xorl %esi, %esi
cmpb $0x0, (%rcx)
setg %sil
addl %esi, %r11d
jmp 0x25eb9
movzwl 0x48(%rsp,%rcx,2), %esi
movzwl 0x48(%rsp,%rbp,2), %edi
movw %di, 0x48(%rsp,%rcx,2)
movw %si, 0x48(%rsp,%rbp,2)
movw $0xf, %r8w
xorl %ecx, %ecx
movl $0x110, %edi            # imm = 0x110
shll %cl, %edi
movb (%r12,%rcx), %al
cmpb $-0x1, -0x4(%r12,%rcx)
cmovel %r9d, %edi
orl %edi, %r8d
movl $0xfffffffe, %edi       # imm = 0xFFFFFFFE
roll %cl, %edi
cmpb $0x1, %al
cmovnel %r10d, %edi
movl $0x11, %esi
shll %cl, %esi
cmpb $0x2, %al
notl %esi
cmovnel %r10d, %esi
andl %edi, %esi
andl %r8d, %esi
movl %esi, %r8d
cmpb $0x3, %al
jne 0x25f19
movl $0x111, %eax            # imm = 0x111
shll %cl, %eax
movl $0x1000, %esi           # imm = 0x1000
shll %cl, %esi
notl %eax
andl %eax, %r8d
orl %r8d, %esi
movl %esi, %r8d
incq %rcx
cmpq $0x4, %rcx
jne 0x25ec0
movw %r8w, 0x4e70(%rsp,%rbp,2)
incq %r13
addq $0xc, %r12
cmpq %rdx, %r13
jne 0x25e77
incq %rbx
movq 0x10(%rsp), %r12
addq $0x4b0, %r12            # imm = 0x4B0
movq 0x28(%rsp), %rax
cmpq %rax, %rbx
jne 0x25e57
cmpl $0x3, %r11d
setl %cl
movq 0x18(%rsp), %rdi
cmpl $0x0, 0x8(%rdi)
je 0x26120
testl %eax, %eax
setle %al
orb %al, %cl
jne 0x26132
xorl %r15d, %r15d
xorl %r12d, %r12d
movq $0x0, 0x10(%rsp)
xorl %ebx, %ebx
xorl %ebp, %ebp
movq 0x40(%rsp), %rax
cmpl $0x0, (%rax)
jle 0x260ee
movl $0xc, %r14d
xorl %r13d, %r13d
leaq 0xc(%rax), %r8
leaq (%rax,%r15), %rsi
movq 0x4e68(%rsp), %rcx
addq %r12, %rcx
movzwl (%rcx,%r13,2), %ecx
movb (%r14,%rsi), %dil
movl %ecx, %edx
cmpb $0x2, %dil
jne 0x26004
movl %ecx, %r9d
movl %ecx, %edx
andl $0x100, %r9d            # imm = 0x100
je 0x26004
movsbl 0x4(%r14,%rsi), %edx
addl %r13d, %edx
movslq %edx, %rdx
imulq $0x4b0, %rbp, %r9       # imm = 0x4B0
addq %r8, %r9
leaq (%rdx,%rdx,2), %rdx
cmpb $0x2, (%r9,%rdx,4)
je 0x25ffc
movl %ecx, %edx
jmp 0x26004
movl %ecx, %edx
andl $0xfffffeff, %edx       # imm = 0xFFFFFEFF
cmpb $0x1, %dil
jne 0x26040
movl %ecx, %r9d
andl $0x10, %r9d
je 0x26040
movsbl 0x4(%r14,%rsi), %r9d
addl %r13d, %r9d
movslq %r9d, %r9
imulq $0x4b0, %rbp, %r10      # imm = 0x4B0
addq %r10, %r8
leaq (%r9,%r9,2), %r9
movl %edx, %r10d
andl $-0x11, %r10d
cmpb $0x1, (%r8,%r9,4)
cmovnel %edx, %r10d
movl %r10d, %edx
cmpb $0x2, %dil
jne 0x2607e
movl %ecx, %r8d
andl $0x800, %r8d            # imm = 0x800
je 0x2607e
movsbl 0x7(%r14,%rsi), %r8d
addl %ebx, %r8d
movslq %r8d, %r8
imulq $0x4b0, %r8, %r8        # imm = 0x4B0
addq %rax, %r8
movl %edx, %r9d
andl $0xfffff7ff, %r9d       # imm = 0xFFFFF7FF
cmpb $0x2, (%r14,%r8)
cmovnel %edx, %r9d
movl %r9d, %edx
cmpb $0x1, %dil
jne 0x260b5
movl %ecx, %edi
andl $0x80, %edi
je 0x260b5
movsbl 0x7(%r14,%rsi), %esi
addl %ebx, %esi
movslq %esi, %rsi
imulq $0x4b0, %rsi, %rsi      # imm = 0x4B0
addq %rsi, %rax
movl %edx, %esi
andl $0xffffff7f, %esi       # imm = 0xFFFFFF7F
cmpb $0x1, (%r14,%rax)
cmovnel %edx, %esi
movl %esi, %edx
cmpw %dx, %cx
je 0x260d6
movq 0x10(%rsp), %rax
addl %r13d, %eax
movzwl %ax, %esi
movzwl %dx, %edx
leaq 0x40(%rsp), %rdi
callq 0x26ed2
testb %al, %al
je 0x26127
incq %r13
movq 0x40(%rsp), %rax
movslq (%rax), %rcx
addq $0xc, %r14
cmpq %rcx, %r13
jl 0x25fa5
incq %rbp
movq 0x40(%rsp), %rax
movslq 0x4(%rax), %rax
incl %ebx
addq $0x64, 0x10(%rsp)
addq $0xc8, %r12
addq $0x4b0, %r15            # imm = 0x4B0
cmpq %rax, %rbp
setl 0xf(%rsp)
jl 0x25f8e
jmp 0x26132
movb $0x1, %al
jmp 0x26329
testb $0x1, 0xf(%rsp)
jne 0x26327
movq 0x40(%rsp), %rax
cmpl $0x0, 0x4(%rax)
setg %al
jle 0x261ca
movl $0xe, %ebx
xorl %r15d, %r15d
leaq 0x40(%rsp), %r14
xorl %r12d, %r12d
movb %al, 0x10(%rsp)
movq 0x40(%rsp), %rax
cmpl $0x0, (%rax)
jle 0x2619e
movq %rbx, %r13
xorl %ebp, %ebp
movswq (%rax,%r13), %rax
leaq (%r15,%rbp), %rcx
movl %eax, %eax
cmpq %rax, %rcx
jne 0x2618a
leal (%r15,%rbp), %eax
movzwl %ax, %esi
movq %r14, %rdi
callq 0x270b2
testb %al, %al
je 0x261bf
incq %rbp
movq 0x40(%rsp), %rax
movslq (%rax), %rcx
addq $0xc, %r13
cmpq %rcx, %rbp
jl 0x26167
incq %r12
movq 0x40(%rsp), %rax
movslq 0x4(%rax), %rax
addq $0x64, %r15
addq $0x4b0, %rbx            # imm = 0x4B0
cmpq %rax, %r12
setl %al
jl 0x26154
jmp 0x261ca
testb $0x1, 0x10(%rsp)
jne 0x26327
leaq 0x40(%rsp), %rdi
xorl %esi, %esi
callq 0x274d2
testl %eax, %eax
jle 0x26327
movq 0x40(%rsp), %rdi
cmpl $0x0, 0x4(%rdi)
jle 0x262de
xorl %r14d, %r14d
movq 0x40(%rsp), %rax
cmpl $0x0, (%rax)
jle 0x262c9
imulq $0xc8, %r14, %rax
movq %rax, 0x10(%rsp)
imulq $0x4b0, %r14, %r12      # imm = 0x4B0
xorl %r15d, %r15d
leaq (%r15,%r15), %rax
addq 0x4e68(%rsp), %rax
movq 0x10(%rsp), %rcx
movzwl (%rcx,%rax), %eax
movl %eax, %ecx
notl %ecx
andl $0x1, %ecx
xorl %r13d, %r13d
testb $0x11, %al
sete %r13b
movl %eax, %edx
andl $0x111, %edx            # imm = 0x111
cmpl $0x1, %edx
adcw %cx, %r13w
xorl %ecx, %ecx
testb $0x8, %al
sete %cl
xorl %ebp, %ebp
testb $-0x78, %al
sete %bpl
andl $0x888, %eax            # imm = 0x888
cmpl $0x1, %eax
adcw %cx, %bp
movq 0x40(%rsp), %rdi
leaq (%rdi,%r12), %rax
leaq (%r15,%r15,2), %rbx
movzbl 0x14(%rax,%rbx,4), %eax
cmpw %ax, %r13w
je 0x262a2
movl %r15d, %esi
movl %r14d, %edx
xorl %ecx, %ecx
callq 0x23244
movq 0x40(%rsp), %rdi
leaq (%rdi,%r12), %rax
jmp 0x2626f
movl %r15d, %esi
movl %r14d, %edx
movl $0x3, %ecx
callq 0x23244
movq 0x40(%rsp), %rdi
leaq (%rdi,%r12), %rax
movzbl 0x17(%rax,%rbx,4), %eax
cmpw %ax, %bp
jne 0x26292
incq %r15
movq 0x40(%rsp), %rax
movslq (%rax), %rax
cmpq %rax, %r15
jl 0x26214
incq %r14
movq 0x40(%rsp), %rdi
movslq 0x4(%rdi), %rax
cmpq %rax, %r14
jl 0x261f0
callq 0x23458
testb %al, %al
movb $0x1, %al
jne 0x26329
leaq 0xcabc(%rip), %rdi      # 0x32dac
callq 0x3590
movq 0x40(%rsp), %rsi
leaq 0x30(%rsp), %rbx
movq %rbx, %rdi
callq 0x236d6
cmpb $0x0, 0xf(%rbx)
movq %rbx, %rdi
jns 0x26315
movq 0x30(%rsp), %rdi
callq 0x3590
movq %rbx, %rdi
callq 0x2a54c
callq 0x3180
xorl %eax, %eax
addq $0xc8378, %rsp          # imm = 0xC8378
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
nop