// File: /workspace/github_cpp_makefile_star2_O2/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 $0x68, %rsp
leaq 0xa1230(%rdi), %r12
pushq $0xc
popq %rbx
movq %r12, 0x18(%rsp)
movq %rdi, 0x8(%rsp)
movq 0x8(%rsp), %rax
movq (%rax), %rsi
movq 0x8(%rsp), %rax
movq 0x4e28(%rax), %rdx
movq %r12, %rdi
callq 0x219c8
movq 0x8(%rsp), %rdi
movq (%rdi), %rdx
xorl %r15d, %r15d
movq %rbx, %r13
xorl %ebp, %ebp
movslq 0x4(%rdx), %rax
cmpq %rax, %rbp
jge 0x236df
movq %r15, 0x28(%rsp)
movq %r13, 0x20(%rsp)
xorl %esi, %esi
movq %rbp, 0x30(%rsp)
movslq (%rdx), %rax
cmpq %rax, %rsi
jge 0x236bf
movq 0x4e28(%rdi), %rax
movzwl %r15w, %ebx
movl %ebx, %ecx
movzwl (%rax,%rcx,2), %r14d
movb (%rdx,%r13), %al
testb %al, %al
jle 0x23664
movl %r14d, %ecx
andl $0x1, %ecx
jne 0x23664
movl %ebx, %ecx
shll $0x4, %ecx
cmpw $-0x1, (%r12,%rcx)
je 0x23664
movq %rsi, 0x38(%rsp)
movq %r12, %rdi
movq %rdx, %r12
movsbl 0x4(%rdx,%r13), %edx
addl %r15d, %edx
movl %r15d, %esi
movl $0xffff, %eax           # imm = 0xFFFF
andl %eax, %esi
andl %eax, %edx
movq %rdi, %rbp
callq 0x21b98
testb %al, %al
je 0x23aa3
movb (%r12,%r13), %al
movq 0x8(%rsp), %rdi
movq %r12, %rdx
movq %rbp, %r12
movq 0x30(%rsp), %rbp
movq 0x38(%rsp), %rsi
testb %al, %al
jle 0x236ad
andl $0x8, %r14d
jne 0x236ad
shll $0x4, %ebx
cmpw $-0x1, 0x6(%r12,%rbx)
je 0x236ad
movsbl 0x7(%rdx,%r13), %eax
imull $0x64, %eax, %edx
addl %r15d, %edx
movq %rsi, %rbx
movl %r15d, %esi
movl $0xffff, %eax           # imm = 0xFFFF
andl %eax, %esi
andl %eax, %edx
movq %r12, %rdi
callq 0x21b98
movq %rbx, %rsi
movq 0x8(%rsp), %rdi
testb %al, %al
je 0x23aa3
incq %rsi
movq (%rdi), %rdx
addq $0xc, %r13
incq %r15
jmp 0x235e0
incq %rbp
movq 0x20(%rsp), %r13
addq $0x4b0, %r13            # imm = 0x4B0
movq 0x28(%rsp), %r15
addq $0x64, %r15
pushq $0xc
popq %rbx
jmp 0x235c2
cmpb $0x1, 0x1d4cc(%rdx)
jne 0x2387a
xorl %r14d, %r14d
pushq $0x10
popq %rcx
movq %rcx, 0x40(%rsp)
movl $0x0, 0x10(%rsp)
cltq
cmpq %rax, %r14
jge 0x23a26
imulq $0x64, %r14, %rax
movq %rax, 0x48(%rsp)
movq 0x40(%rsp), %r15
xorl %r13d, %r13d
movq %r14, 0x50(%rsp)
movslq (%rdx), %rax
cmpq %rax, %r13
jge 0x23866
imulq $0x4b0, %r14, %rax      # imm = 0x4B0
addq %rdx, %rax
imulq $0xc, %r13, %rcx
cmpb $0x0, 0xc(%rcx,%rax)
js 0x23852
movq 0x48(%rsp), %rax
movq %r13, 0x58(%rsp)
leaq (%rax,%r13), %r8
movq 0x4e28(%rdi), %rax
movzwl %r8w, %ecx
movzwl (%rax,%rcx,2), %eax
movzwl %ax, %ecx
movl %ecx, 0x30(%rsp)
movq %r15, 0x60(%rsp)
addq %r15, %rdx
leaq 0x8688(%rip), %r12      # 0x2be00
xorl %r13d, %r13d
movw %ax, 0x14(%rsp)
movq %rdx, 0x28(%rsp)
movq %r8, 0x20(%rsp)
movzwl %r8w, %esi
cmpq $0x4, %r13
je 0x23819
movl $0x110, %ebx            # imm = 0x110
movl %r13d, %ecx
shll %cl, %ebx
testl %ebx, 0x30(%rsp)
je 0x2380d
movl %eax, 0x38(%rsp)
movsbl (%rdx,%r13), %r15d
imulw (%r12), %r15w
addl %r8d, %r15d
movq 0x18(%rsp), %r14
movq %r14, %rdi
callq 0x21c36
movl %eax, %ebp
movl $0xffff, %eax           # imm = 0xFFFF
andl %eax, %r15d
movq %r14, %rdi
movl %r15d, %esi
callq 0x21c36
cmpw %ax, %bp
jne 0x237e8
movl $0xffff, %ebx           # imm = 0xFFFF
jmp 0x237ea
notl %ebx
cmpw $0x50, %bp
movl $0xffff, %ecx           # imm = 0xFFFF
cmovbl %ecx, %ebx
cmpw $0x50, %ax
cmovbl %ecx, %ebx
movl 0x38(%rsp), %eax
andl %ebx, %eax
movq 0x28(%rsp), %rdx
movq 0x20(%rsp), %r8
incq %r13
addq $0x2, %r12
jmp 0x2378a
cmpw 0x14(%rsp), %ax
movq 0x18(%rsp), %r12
pushq $0xc
popq %rbx
movq 0x50(%rsp), %r14
movq 0x60(%rsp), %r15
movq 0x58(%rsp), %r13
je 0x23852
movzwl %ax, %edx
movq 0x8(%rsp), %rdi
callq 0x22c90
movb $0x1, %cl
movl %ecx, 0x10(%rsp)
testb %al, %al
je 0x23aa3
incq %r13
movq 0x8(%rsp), %rdi
movq (%rdi), %rdx
addq $0xc, %r15
jmp 0x23720
incq %r14
movl 0x4(%rdx), %eax
addq $0x4b0, 0x40(%rsp)      # imm = 0x4B0
jmp 0x236ff
movl $0x0, 0x10(%rsp)
cmpw $0x0, 0xc8332(%rdi)
je 0x23a16
movzwl 0xc8330(%rdi), %ebp
movw $0xffff, %bx            # imm = 0xFFFF
movl %ebp, %r15d
movw $0xffff, %r13w          # imm = 0xFFFF
movl %ebx, %eax
movl %ebp, %ebx
movzwl %bp, %esi
movzwl %ax, %edx
movq 0x18(%rsp), %r12
movq %r12, %rdi
callq 0x21c4c
cmpw $-0x1, %ax
je 0x23a11
movl %eax, %ebp
movl %r15d, %r14d
movzwl %r15w, %r15d
movzwl %r13w, %edx
movq %r12, %rdi
movl %r15d, %esi
callq 0x21c4c
cmpw $-0x1, %ax
je 0x23970
movl %eax, %r13d
movzwl %ax, %esi
movq %r12, %rdi
movl %r15d, %edx
callq 0x21c4c
cmpw $-0x1, %ax
je 0x23975
movl %eax, %r15d
cmpw %ax, %bp
jne 0x238a3
xorl %r15d, %r15d
movl %ebp, %eax
movq 0x18(%rsp), %r13
movl %eax, %r12d
movq %r15, %r14
movq 0x8(%rsp), %rax
movq (%rax), %rax
incq %r15
movw %r12w, 0x1fbe8(%rax,%r14,2)
movzwl %r12w, %esi
movzwl %bx, %edx
movq %r13, %rdi
callq 0x21c4c
movl %r12d, %ebx
cmpw %bp, %ax
jne 0x2390f
xorl %ebx, %ebx
movq 0x8(%rsp), %rdi
cmpq %rbx, %r14
je 0x23890
movq (%rdi), %rax
movzwl 0x1fbea(%rax,%rbx,2), %edx
movzwl %bp, %esi
movq %r13, %rdi
callq 0x21b98
movq 0x8(%rsp), %rdi
incq %rbx
jmp 0x23947
movl %r13d, %ecx
jmp 0x2397b
movl %r14d, %ecx
movl %r13d, %r14d
movq 0x8(%rsp), %r15
movq (%r15), %rsi
movzwl %r14w, %ebp
movzwl %cx, %r13d
movq 0x18(%rsp), %rbx
movq %rbx, %rdi
movl %ebp, %edx
movl %r13d, %ecx
leaq 0x16(%rsp), %r8
leaq 0x7(%rsp), %r9
callq 0x21cf8
movq 0x4e28(%r15), %rcx
movzwl 0x16(%rsp), %eax
movzwl (%rcx,%rax,2), %edx
movb 0x7(%rsp), %cl
testb %cl, %cl
pushq $0x1
popq %rsi
pushq $0x8
popq %rdi
cmovnel %edi, %esi
testl %edx, %esi
je 0x239fc
addl $0xa, 0xc8334(%r15)
testb %cl, %cl
movl $0xfffe, %ecx           # imm = 0xFFFE
movl $0xfff7, %esi           # imm = 0xFFF7
cmovnel %esi, %ecx
andl %ecx, %edx
movzwl %ax, %esi
movq %r15, %rdi
callq 0x22c90
movb $0x1, %cl
movl %ecx, 0x10(%rsp)
testb %al, %al
je 0x23aa3
movq %rbx, %rdi
movl %ebp, %esi
movl %r13d, %edx
callq 0x21b98
movq %r15, %rdi
jmp 0x23890
movq 0x8(%rsp), %rdi
testb $0x1, 0x10(%rsp)
pushq $0xc
popq %rbx
jne 0x23596
jmp 0x23a76
testb $0x1, 0x10(%rsp)
jne 0x23596
movw $0xffff, %ax            # imm = 0xFFFF
xorl %ebx, %ebx
cmpq $0x4, %rbx
je 0x23882
movq (%rdi), %rcx
movzwl 0x1d4d0(%rcx,%rbx,2), %ebp
cmpw $-0x1, %bp
je 0x23a6d
cmpw $-0x1, %ax
je 0x23a6f
movzwl %ax, %esi
movzwl %bp, %edx
movq %r12, %rdi
callq 0x21b98
movq 0x8(%rsp), %rdi
jmp 0x23a6f
movl %eax, %ebp
incq %rbx
movl %ebp, %eax
jmp 0x23a37
movzwl 0xc8332(%rdi), %eax
testw %ax, %ax
je 0x23ab4
movzwl 0xc8330(%rdi), %ecx
movl %ecx, %edx
movzwl %dx, %edx
shll $0x4, %edx
movzwl 0xa(%r12,%rdx), %edx
decl %eax
cmpw %cx, %dx
jne 0x23a8b
testw %ax, %ax
je 0x23ab4
xorl %eax, %eax
addq $0x68, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movb $0x1, %al
jmp 0x23aa5