// File: /workspace/github_cpp_makefile_star2_O1/Alcaro[P]bridges/solver.cpp
// Function: (anonymous namespace)::solver<((anonymous namespace)::op_t)3>::do_isolation_rule()
bool do_isolation_rule()
	{
		//use the isolation rule
	link_again_top: ;
		link.init(map, possibilities);
//puts("BEGIN");
		for (int y=0;y<map.height;y++)
		for (int x=0;x<map.width;x++)
		{
			uint16_t index = y*100+x;
			gamemap::island& here = map.map[y][x];
			
			uint16_t flags = possibilities[index];
			if (here.population>0 && !(flags & 0x0001) && link.can_join(index, 0))
			{
				if (!link.join(index, index+here.bridgelen[0])) return false;
			}
			if (here.population>0 && !(flags & 0x0008) && link.can_join(index, 3))
			{
				if (!link.join(index, index+here.bridgelen[3]*100)) return false;
			}
//if(x==0&&y!=0)puts("");printf("%.4X ",flags);
		}
//puts("");
		
		bool link_did_any = false;
		
		if (map.has_castles)
		{
			//if map has castles, enforce that they don't touch each other
			for (int y=0;y<map.height;y++)
			for (int x=0;x<map.width;x++)
			{
				uint16_t index = y*100+x;
				gamemap::island& here = map.map[y][x];
				if (here.population < 0) continue;
				
				uint16_t flags = possibilities[index];
				uint16_t newflags = flags;
				//test all four links, to ensure the offending bridge is always caught
				for (int dir=0;dir<4;dir++)
				{
					if (!(flags & (0x0110<<dir))) continue;
					
					static const int16_t offsets[4] = { 1, -100, -1, 100 };
					uint16_t other = index + offsets[dir]*here.bridgelen[dir];
					
					uint16_t mycolor = link.color(index);
					uint16_t othercolor = link.color(other);
					
					if (mycolor != othercolor && mycolor >= 80 && othercolor >= 80)
					{
						newflags &= ~(0x0110<<dir);
					}
				}
				if (newflags != flags)
				{
					if (!set_state(index, newflags)) return false;
					link_did_any = true;
				}
//if(x==0&&y!=0)puts("");printf("%.4X ",flags);
			}
			if (link_did_any) goto link_again_top; // to ensure it doesn't try to create the bridges we just removed
			
			//then create fake links between the castles, so the solver won't say
			// 'okay, only one path, it must exist' when reaching another castle
			
			uint16_t prevcastle = -1;
			for (int castletype=1;castletype<=4;castletype++)
			{
				if (map.an_island[castletype] == -1) continue;
				
				uint16_t newcastle = map.an_island[castletype];
				if (prevcastle != (uint16_t)-1)
					link.join(prevcastle, newcastle);
				prevcastle = newcastle;
			}
		}
		
		
//puts("HELLO");
		if (link.count() != 0)
		{
	link_again: ;
			uint16_t index1 = link.any();
			uint16_t index2 = index1;
			uint16_t index1p = -1;
			uint16_t index2p = -1;
			
			//TODO: this can go 1,2,3,4,5,3,2 and consider 2 part of the loop,
			// rather than enforcing the existence of that bridge
			
			do
			{
				uint16_t next;
				
//printf("1:%.3i(...),%.3i(...),...\n",index1,index1p);
//printf("1:%.3i(%.3i),%.3i(%.3i),...\n",
//index1,link.root(index1),
//index1p,(index1p==65535)?-1:link.root(index1p));
				next = link.query(index1, index1p);
//printf("1:%.3i(%.3i),%.3i(%.3i),%.3i(%.3i)\n",
//index1,link.root(index1),
//index1p,(index1p==65535)?-1:link.root(index1p),
//next,(next==65535)?-1:link.root(next));
				index1p = index1;
				index1 = next;
				if (next == (uint16_t)-1) goto link_done; // only a single island left? then we're done here, try the other castles
				
				next = link.query(index2, index2p);
//printf("2:%.3i(%.3i),%.3i(%.3i),%.3i(%.3i)\n",
//index2,link.root(index2),
//index2p,(index2p==65535)?-1:link.root(index2p),
//next,(next==65535)?-1:link.root(next));
				if (next != (uint16_t)-1)
				{
					index2p = index2;
					index2 = next;
					
					next = link.query(index2, index2p);
//printf("3:%.3i(%.3i),%.3i(%.3i),%.3i(%.3i)\n",
//index2,link.root(index2),
//index2p,(index2p==65535)?-1:link.root(index2p),
//next,(next==65535)?-1:link.root(next));
				}
				if (next != (uint16_t)-1)
				{
					index2p = index2;
					index2 = next;
				}
				
				if (next == (uint16_t)-1)
				{
					//if (map.get(index2).population < 80 && map.get(index2p).population < 80)
					{
						uint16_t topleft;
						bool down;
						link.lookback(map, index2, index2p, topleft, down);
//printf("FORCEJOIN=%.3i(%.3i) - join %.3i dir %i\n", index2, index2p, topleft, down*3);
						if (possibilities[topleft] & (down ? 0x0008 : 0x0001))
						{
							add_difficulty(10);
//puts("A");
							if (!set_state(topleft, possibilities[topleft] & ~(down ? 0x0008 : 0x0001))) return false;
//puts("A+");
							link_did_any = true;
						}
					}
//else printf("FORCEJOINCASTLE=%.3i,%.3i\n",index2,index2p);
					link.join(index2, index2p);
					goto link_again;
				}
			} while (index1 != index2);
			
//printf("LOOP=%.3i\n",index1);
			int numvisited = 0;
			do {
				map.towalk[numvisited++] = index1;
				
				uint16_t next = link.query(index1, index1p);
//printf("LOOPWALK:%.3i(%.3i),%.3i(%.3i),%.3i(%.3i)\n",
//index1,link.root(index1),
//index1p,(index1p==65535)?-1:link.root(index1p),
//next,(next==65535)?-1:link.root(next));
				index1p = index1;
				index1 = next;
			} while (index1 != index2);
			
			for (int i=1;i<numvisited;i++)
			{
//printf("JOINLOOP:%.3i,%.3i\n",index1,map.towalk[i]);
				link.join(index1, map.towalk[i]);
			}
			goto link_again;
		}
		link_done:
		// if a set_state from a forced join helped, perhaps that set_state blocked some other bridges,
		// so let's check if we can prove anything new
		if (link_did_any) goto link_again_top;
		
		
		if (link.count() != 0)
		{
			//iterate everything joined with a_linkable_island; if not equal to n_linkable_islands, it's disjoint, so return false
			uint16_t n_linked_islands = 0;
			
			uint16_t index = link.any();
			uint16_t indexstart = index;
			do {
//printf("LINK::%.3i\n",index);
				n_linked_islands++;
				index = link.iter(index);
			} while (index != indexstart);
			
//printf("LINKS=%i,%i\n",n_linked_islands,link.count());
			if (n_linked_islands != link.count()) return false;
		}
		
		return true;
	}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x38, %rsp
leaq 0xa1230(%rdi), %r14
movl %eax, 0x8(%rsp)
movq %rdi, (%rsp)
movq (%rdi), %rsi
movq 0x4e28(%rdi), %rdx
movq %r14, %rdi
callq 0x27eb0
movq (%rsp), %rdi
movq (%rdi), %rax
cmpl $0x0, 0x4(%rax)
setg %al
jle 0x2a076
movl $0xc, %r15d
xorl %r12d, %r12d
xorl %ecx, %ecx
movq %rcx, 0x28(%rsp)
movb %al, 0xe(%rsp)
movq (%rdi), %r13
cmpl $0x0, (%r13)
setg %al
movq %r15, 0x10(%rsp)
movq %r12, 0x30(%rsp)
jle 0x2a03c
xorl %ebx, %ebx
movb %al, 0x20(%rsp)
movq 0x4e28(%rdi), %rax
movzwl %r12w, %ecx
movzwl (%rax,%rcx,2), %ebp
cmpb $0x0, (%r13,%r15)
jle 0x29fc2
movl %ebp, %eax
andl $0x1, %eax
jne 0x29fc2
movzwl %r12w, %eax
shll $0x4, %eax
cmpw $-0x1, (%r14,%rax)
je 0x29fc2
movsbl 0x4(%r13,%r15), %edx
addl %r12d, %edx
movl %r12d, %esi
movl $0xffff, %eax           # imm = 0xFFFF
andl %eax, %esi
andl %eax, %edx
movq %r14, %rdi
callq 0x2809c
movq (%rsp), %rdi
testb %al, %al
je 0x2a00b
cmpb $0x0, (%r13,%r15)
jle 0x2a007
andl $0x8, %ebp
jne 0x2a007
movzwl %r12w, %eax
shll $0x4, %eax
cmpw $-0x1, 0x6(%r14,%rax)
je 0x2a007
movsbl 0x7(%r13,%r15), %eax
imull $0x64, %eax, %edx
addl %r12d, %edx
movl %r12d, %esi
movl $0xffff, %eax           # imm = 0xFFFF
andl %eax, %esi
andl %eax, %edx
movq %r14, %rdi
callq 0x2809c
movq (%rsp), %rdi
testb %al, %al
je 0x2a00b
movb $0x1, %al
jmp 0x2a015
xorl %eax, %eax
movl $0x0, 0x8(%rsp)
testb %al, %al
je 0x2a038
incq %rbx
movq (%rdi), %r13
movslq (%r13), %rax
incq %r12
addq $0xc, %r15
cmpq %rax, %rbx
setl %al
jl 0x29f6c
jmp 0x2a03c
movb 0x20(%rsp), %al
testb $0x1, %al
movq 0x28(%rsp), %rcx
jne 0x2a072
incq %rcx
movq (%rdi), %rax
movslq 0x4(%rax), %rax
movq 0x30(%rsp), %r12
addq $0x64, %r12
movq 0x10(%rsp), %r15
addq $0x4b0, %r15            # imm = 0x4B0
cmpq %rax, %rcx
setl %al
jl 0x29f46
jmp 0x2a076
movb 0xe(%rsp), %al
testb $0x1, %al
jne 0x2a537
movq (%rdi), %rax
cmpb $0x1, 0x1d4cc(%rax)
jne 0x2a274
movq (%rdi), %rax
movl $0x9, %ecx
cmpl $0x0, 0x4(%rax)
jle 0x2a4c7
xorl %r12d, %r12d
movl $0x0, 0x10(%rsp)
movq (%rdi), %rax
movl $0xc, %ecx
cmpl $0x0, (%rax)
jle 0x2a24e
imulq $0x64, %r12, %rcx
movq %rcx, 0x20(%rsp)
xorl %ebp, %ebp
imulq $0x4b0, %r12, %rcx      # imm = 0x4B0
addq %rax, %rcx
leaq (,%rbp,2), %rdx
addq %rbp, %rdx
cmpb $0x0, 0xc(%rcx,%rdx,4)
js 0x2a216
movq 0x20(%rsp), %rax
addq %rbp, %rax
leaq 0xc(%rcx,%rdx,4), %rdx
movq 0x4e28(%rdi), %rcx
movzwl %ax, %esi
movzwl (%rcx,%rsi,2), %esi
movzwl %si, %r8d
xorl %ecx, %ecx
movl %esi, %edi
movl $0x110, %r9d            # imm = 0x110
shll %cl, %r9d
testl %r8d, %r9d
je 0x2a1e5
movsbl 0x4(%rdx,%rcx), %r10d
leaq 0x8ca7(%rip), %r11      # 0x32dd0
imulw (%r11,%rcx,2), %r10w
addl %eax, %r10d
movl %eax, %ebx
movl %ebx, %r13d
movzwl %bx, %r11d
movl %r11d, %ebx
shll $0x4, %ebx
movzwl 0x8(%r14,%rbx), %ebx
cmpw %bx, %r11w
jne 0x2a134
cmpw %ax, %r13w
je 0x2a16f
movl %eax, %ebx
movzwl %bx, %r15d
shll $0x4, %r15d
movzwl 0x8(%r14,%r15), %ebx
movw %r13w, 0x8(%r14,%r15)
cmpw %r13w, %bx
jne 0x2a155
shll $0x4, %r11d
movzwl 0xe(%r14,%r11), %r11d
movl %r10d, %r15d
movl %r15d, %ebx
movzwl %r15w, %r13d
movl %r13d, %r15d
shll $0x4, %r15d
movzwl 0x8(%r14,%r15), %r15d
cmpw %r15w, %r13w
jne 0x2a17c
cmpw %r10w, %bx
je 0x2a1b6
movzwl %r10w, %r15d
shll $0x4, %r15d
movzwl 0x8(%r14,%r15), %r10d
movw %bx, 0x8(%r14,%r15)
cmpw %bx, %r10w
jne 0x2a19c
shll $0x4, %r13d
movzwl 0xe(%r14,%r13), %r10d
cmpw %r10w, %r11w
notl %r9d
movl $0xffff, %ebx           # imm = 0xFFFF
cmovel %ebx, %r9d
cmpw $0x50, %r11w
cmovbl %ebx, %r9d
cmpw $0x50, %r10w
cmovbl %ebx, %r9d
andl %r9d, %edi
incq %rcx
cmpq $0x4, %rcx
jne 0x2a10a
xorl %ecx, %ecx
cmpw %si, %di
je 0x2a22a
movzwl %ax, %esi
movzwl %di, %edx
movq (%rsp), %rdi
callq 0x29512
xorl %ecx, %ecx
testb %al, %al
je 0x2a21d
movb $0x1, %al
movl %eax, 0x10(%rsp)
jmp 0x2a22a
movl $0xe, %ecx
jmp 0x2a22e
movl $0x1, %ecx
movl $0x0, 0x8(%rsp)
movq (%rsp), %rdi
cmpl $0xe, %ecx
je 0x2a237
testl %ecx, %ecx
jne 0x2a24e
incq %rbp
movq (%rdi), %rax
movslq (%rax), %rcx
cmpq %rcx, %rbp
jl 0x2a0c7
movl $0xc, %ecx
cmpl $0xc, %ecx
jne 0x2a4cf
incq %r12
movq (%rdi), %rax
movslq 0x4(%rax), %rax
cmpq %rax, %r12
jl 0x2a0ab
movl $0x9, %ecx
jmp 0x2a4cf
movl $0x0, 0x10(%rsp)
cmpw $0x0, 0xc8332(%rdi)
je 0x2a474
movzwl 0xc8330(%rdi), %ebp
movw $0xffff, %bx            # imm = 0xFFFF
movl %ebp, %r13d
movw $0xffff, %r15w          # imm = 0xFFFF
movl %ebx, %eax
movl %ebp, %ebx
movzwl %bp, %esi
movzwl %ax, %edx
movq %r14, %rdi
callq 0x2817c
movl %eax, %ebp
cmpw $-0x1, %ax
je 0x2a2f1
movw %bx, 0x20(%rsp)
movzwl %r13w, %r12d
movl %r15d, %ebx
movzwl %bx, %edx
movq %r14, %rdi
movl %r12d, %esi
callq 0x2817c
movl %eax, %r15d
cmpw $-0x1, %ax
je 0x2a301
movzwl %r15w, %esi
movq %r14, %rdi
movl %r12d, %edx
callq 0x2817c
movl %r15d, %ecx
movl %eax, %r15d
jmp 0x2a307
movl $0x18, %ecx
xorl %eax, %eax
movq (%rsp), %rdi
jmp 0x2a3e9
movl %r13d, %ecx
movl %ebx, %r13d
movq (%rsp), %rdi
cmpw $-0x1, %r15w
cmovel %ecx, %r15d
movl %r13d, %eax
movl %r15d, %r13d
cmovnel %ecx, %eax
movzwl 0x20(%rsp), %ebx
je 0x2a330
movl %eax, %r15d
xorl %ecx, %ecx
movb $0x1, %al
jmp 0x2a3e9
movq (%rdi), %rsi
movzwl %r13w, %edx
movl %eax, %r15d
movzwl %ax, %r12d
movq %r14, %rdi
movl %edx, 0x28(%rsp)
movl %r12d, %ecx
leaq 0x1e(%rsp), %r8
leaq 0xf(%rsp), %r9
callq 0x282b8
movq (%rsp), %rdi
movq 0x4e28(%rdi), %rcx
movzwl 0x1e(%rsp), %eax
movzwl (%rcx,%rax,2), %edx
movb 0xf(%rsp), %cl
testb %cl, %cl
movl $0x1, %esi
movl $0x8, %r8d
cmovnel %r8d, %esi
testl %edx, %esi
je 0x2a3b2
addl $0xa, 0xc8334(%rdi)
testb %cl, %cl
movl $0xfffe, %ecx           # imm = 0xFFFE
movl $0xfff7, %esi           # imm = 0xFFF7
cmovnel %esi, %ecx
andl %ecx, %edx
movzwl %ax, %esi
callq 0x29512
testb %al, %al
je 0x2a3b6
movb $0x1, %al
movl %eax, 0x10(%rsp)
movb $0x1, %al
jmp 0x2a3c0
movb $0x1, %al
jmp 0x2a3c4
xorl %eax, %eax
movl $0x0, 0x8(%rsp)
movq (%rsp), %rdi
testb %al, %al
je 0x2a3e2
movq %r14, %rdi
movl 0x28(%rsp), %esi
movl %r12d, %edx
callq 0x2809c
movq (%rsp), %rdi
movl $0x15, %ecx
jmp 0x2a3e7
movl $0x1, %ecx
xorl %eax, %eax
testb %al, %al
je 0x2a462
cmpw %r13w, %bp
jne 0x2a29d
xorl %r15d, %r15d
movl %ebx, %ecx
movl %r13d, %ebx
movl %ebp, %r13d
movq %r15, %r12
movq (%rdi), %rax
incq %r15
movw %bp, 0x1fbe8(%rax,%r12,2)
movzwl %bp, %esi
movzwl %cx, %edx
movq %r14, %rdi
callq 0x2817c
movq (%rsp), %rdi
movl %eax, %ebp
movl %r13d, %ecx
movl %ebx, %r13d
cmpw %bx, %ax
jne 0x2a3fc
cmpq $0x1, %r15
je 0x2a45d
xorl %ebx, %ebx
movq (%rdi), %rax
movzwl 0x1fbea(%rax,%rbx,2), %edx
movzwl %bp, %esi
movq %r14, %rdi
callq 0x2809c
movq (%rsp), %rdi
incq %rbx
cmpq %rbx, %r12
jne 0x2a43b
movl $0x15, %ecx
cmpl $0x15, %ecx
je 0x2a28a
cmpl $0x18, %ecx
jne 0x2a52e
movl $0x2, %ecx
testb $0x1, 0x10(%rsp)
jne 0x2a52e
movzwl 0xc8332(%rdi), %eax
testw %ax, %ax
je 0x2a523
movzwl 0xc8330(%rdi), %ecx
movl %ecx, %edx
movzwl %dx, %edx
shll $0x4, %edx
movzwl 0xa(%r14,%rdx), %edx
decl %eax
cmpw %cx, %dx
jne 0x2a49d
testw %ax, %ax
sete %al
je 0x2a523
andb 0x8(%rsp), %al
movl $0x1, %ecx
movl %eax, 0x8(%rsp)
jmp 0x2a52e
movl $0x0, 0x10(%rsp)
cmpl $0x9, %ecx
jne 0x2a52e
movl $0x2, %ecx
testb $0x1, 0x10(%rsp)
jne 0x2a52e
movw $0xffff, %ax            # imm = 0xFFFF
xorl %ebx, %ebx
movq (%rdi), %rcx
movzwl 0x1d4d0(%rcx,%rbx,2), %ebp
cmpw $-0x1, %bp
je 0x2a511
cmpw $-0x1, %ax
je 0x2a513
movzwl %ax, %esi
movzwl %bp, %edx
movq %r14, %rdi
callq 0x2809c
movq (%rsp), %rdi
jmp 0x2a513
movl %eax, %ebp
incq %rbx
movl %ebp, %eax
cmpq $0x4, %rbx
jne 0x2a4e6
jmp 0x2a27c
movb $0x1, %al
movl %eax, 0x8(%rsp)
movl $0x1, %ecx
cmpl $0x1, %ecx
jne 0x29f15
movl 0x8(%rsp), %eax
andb $0x1, %al
addq $0x38, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq