// File: /workspace/github_cpp_makefile_star2_O3/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 $0x48, %rsp
leaq 0xa1230(%rdi), %rbx
movq %rdi, 0x10(%rsp)
movq (%rdi), %rsi
movq 0x4e28(%rdi), %rdx
movq %rbx, %rdi
callq 0x284a6
movq 0x10(%rsp), %rdi
movq (%rdi), %rsi
cmpl $0x0, 0x4(%rsi)
jle 0x2a62a
movl (%rsi), %eax
movl $0xc, %r13d
xorl %ebp, %ebp
xorl %edx, %edx
testl %eax, %eax
jle 0x2a426
movq %rdx, 0x18(%rsp)
movq %r13, 0x30(%rsp)
movq %rbp, 0x28(%rsp)
xorl %r12d, %r12d
movq 0x4e28(%rdi), %rax
movzwl %bp, %r14d
movl %r14d, %ecx
movzwl (%rax,%rcx,2), %r15d
movb (%rsi,%r13), %al
testb %al, %al
jle 0x2a3bc
movl %r15d, %ecx
andl $0x1, %ecx
jne 0x2a3bc
movl %r14d, %ecx
shll $0x4, %ecx
cmpw $-0x1, (%rbx,%rcx)
je 0x2a3bc
movsbl 0x4(%rsi,%r13), %edx
addl %ebp, %edx
movq %rsi, 0x38(%rsp)
movl %ebp, %esi
movl $0xffff, %eax           # imm = 0xFFFF
andl %eax, %esi
andl %eax, %edx
movq %rbx, %rdi
callq 0x28692
testb %al, %al
je 0x2a867
movq 0x38(%rsp), %rsi
movb (%rsi,%r13), %al
movq 0x10(%rsp), %rdi
testb %al, %al
jle 0x2a3fe
andl $0x8, %r15d
jne 0x2a3fe
shll $0x4, %r14d
cmpw $-0x1, 0x6(%rbx,%r14)
je 0x2a3fe
movsbl 0x7(%rsi,%r13), %eax
imull $0x64, %eax, %edx
addl %ebp, %edx
movl %ebp, %esi
movl $0xffff, %eax           # imm = 0xFFFF
andl %eax, %esi
andl %eax, %edx
movq %rbx, %rdi
callq 0x28692
movq 0x10(%rsp), %rdi
testb %al, %al
je 0x2a867
incq %r12
movq (%rdi), %rsi
movslq (%rsi), %rax
incq %rbp
addq $0xc, %r13
cmpq %rax, %r12
jl 0x2a356
movq 0x30(%rsp), %r13
movq 0x28(%rsp), %rbp
movq 0x18(%rsp), %rdx
incq %rdx
movslq 0x4(%rsi), %rcx
addq $0x64, %rbp
addq $0x4b0, %r13            # imm = 0x4B0
cmpq %rcx, %rdx
jl 0x2a33c
cmpb $0x0, 0x1d4cc(%rsi)
je 0x2a821
testl %ecx, %ecx
jle 0x2a82e
movl (%rsi), %r8d
movq $0x0, 0x28(%rsp)
movl $0x0, 0x18(%rsp)
testl %r8d, %r8d
jle 0x2a603
imulq $0x64, 0x28(%rsp), %rax
movq %rax, 0x40(%rsp)
xorl %ebp, %ebp
imulq $0x4b0, 0x28(%rsp), %rcx # imm = 0x4B0
addq %rsi, %rcx
leaq (,%rbp,2), %rax
addq %rbp, %rax
cmpb $0x0, 0xc(%rcx,%rax,4)
js 0x2a5f4
movl %r8d, 0x30(%rsp)
movq %rsi, 0x38(%rsp)
movq 0x40(%rsp), %rdx
addq %rbp, %rdx
leaq 0xc(%rcx,%rax,4), %rsi
movq 0x4e28(%rdi), %rax
movzwl %dx, %ecx
movzwl (%rax,%rcx,2), %r8d
movzwl %r8w, %r9d
xorl %ecx, %ecx
movl %r8d, %r13d
movl $0x110, %r10d           # imm = 0x110
shll %cl, %r10d
testl %r9d, %r10d
je 0x2a5ac
movsbl 0x4(%rsi,%rcx), %r11d
leaq 0x89c0(%rip), %rax      # 0x32eb0
imulw (%rax,%rcx,2), %r11w
addl %edx, %r11d
movl %edx, %r12d
movl %r12d, %r15d
movzwl %r12w, %r14d
movl %r14d, %eax
shll $0x4, %eax
movzwl 0x8(%rbx,%rax), %r12d
cmpw %r12w, %r14w
jne 0x2a4fc
cmpw %dx, %r15w
je 0x2a537
movl %edx, %r12d
movzwl %r12w, %eax
shll $0x4, %eax
movzwl 0x8(%rbx,%rax), %r12d
movw %r15w, 0x8(%rbx,%rax)
cmpw %r15w, %r12w
jne 0x2a51e
shll $0x4, %r14d
movzwl 0xe(%rbx,%r14), %r14d
movl %r11d, %r12d
movl %r12d, %eax
movzwl %r12w, %r15d
movl %r15d, %r12d
shll $0x4, %r12d
movzwl 0x8(%rbx,%r12), %r12d
cmpw %r12w, %r15w
jne 0x2a544
cmpw %r11w, %ax
je 0x2a57e
movzwl %r11w, %r12d
shll $0x4, %r12d
movzwl 0x8(%rbx,%r12), %r11d
movw %ax, 0x8(%rbx,%r12)
cmpw %ax, %r11w
jne 0x2a564
shll $0x4, %r15d
movzwl 0xe(%rbx,%r15), %eax
cmpw %ax, %r14w
notl %r10d
movl $0xffff, %edi           # imm = 0xFFFF
cmovel %edi, %r10d
cmpw $0x50, %r14w
cmovbl %edi, %r10d
cmpw $0x50, %ax
cmovbl %edi, %r10d
andl %r10d, %r13d
incq %rcx
cmpq $0x4, %rcx
jne 0x2a4d1
cmpw %r8w, %r13w
movq 0x10(%rsp), %rdi
movq 0x38(%rsp), %rsi
movl 0x30(%rsp), %r8d
je 0x2a5f4
movzwl %dx, %esi
movzwl %r13w, %edx
movq %rdi, %r14
callq 0x2996a
testb %al, %al
je 0x2a867
movq (%r14), %rsi
movl (%rsi), %r8d
movb $0x1, %al
movl %eax, 0x18(%rsp)
movq %r14, %rdi
incq %rbp
movslq %r8d, %rax
cmpq %rax, %rbp
jl 0x2a480
movq 0x28(%rsp), %rdx
incq %rdx
movslq 0x4(%rsi), %rax
movq %rdx, 0x28(%rsp)
cmpq %rax, %rdx
jl 0x2a46a
testb $0x1, 0x18(%rsp)
jne 0x2a30c
jmp 0x2a63b
movl $0x0, 0x18(%rsp)
cmpb $0x0, 0x1d4cc(%rsi)
je 0x2a67c
movw $0xffff, %ax            # imm = 0xFFFF
xorl %r14d, %r14d
movq (%rdi), %rcx
movzwl 0x1d4d0(%rcx,%r14,2), %ebp
cmpw $-0x1, %bp
je 0x2a66f
cmpw $-0x1, %ax
je 0x2a671
movzwl %ax, %esi
movzwl %bp, %edx
movq %rbx, %rdi
callq 0x28692
movq 0x10(%rsp), %rdi
jmp 0x2a671
movl %eax, %ebp
incq %r14
movl %ebp, %eax
cmpq $0x4, %r14
jne 0x2a642
cmpw $0x0, 0xc8332(%rdi)
je 0x2a814
movzwl 0xc8330(%rdi), %ebp
movw $0xffff, %r12w          # imm = 0xFFFF
movl %ebp, %r15d
movw $0xffff, %r13w          # imm = 0xFFFF
movl %r12d, %eax
movl %ebp, %r12d
movzwl %bp, %esi
movzwl %ax, %edx
movq %rbx, %rdi
callq 0x2877a
cmpw $-0x1, %ax
je 0x2a80f
movl %eax, %ebp
movl %r15d, %r14d
movzwl %r15w, %r15d
movzwl %r13w, %edx
movq %rbx, %rdi
movl %r15d, %esi
callq 0x2877a
cmpw $-0x1, %ax
je 0x2a76f
movl %eax, %r13d
movzwl %ax, %esi
movq %rbx, %rdi
movl %r15d, %edx
callq 0x2877a
cmpw $-0x1, %ax
je 0x2a774
movl %eax, %r15d
cmpw %ax, %bp
jne 0x2a69e
xorl %r15d, %r15d
movl %ebp, %eax
movl %eax, %r13d
movq %r15, %r14
movq 0x10(%rsp), %rax
movq (%rax), %rax
incq %r15
movw %r13w, 0x1fbe8(%rax,%r14,2)
movzwl %r13w, %esi
movzwl %r12w, %edx
movq %rbx, %rdi
callq 0x2877a
movl %r13d, %r12d
cmpw %bp, %ax
jne 0x2a702
cmpq $0x1, %r15
movq 0x10(%rsp), %rdi
je 0x2a68a
xorl %r15d, %r15d
movq (%rdi), %rax
movzwl 0x1fbea(%rax,%r15,2), %edx
movzwl %bp, %esi
movq %rbx, %rdi
callq 0x28692
movq 0x10(%rsp), %rdi
incq %r15
cmpq %r15, %r14
jne 0x2a746
jmp 0x2a68a
movl %r13d, %ecx
jmp 0x2a77a
movl %r14d, %ecx
movl %r13d, %r14d
movq 0x10(%rsp), %r15
movq (%r15), %rsi
movzwl %r14w, %ebp
movzwl %cx, %r13d
movq %rbx, %rdi
movl %ebp, %edx
movl %r13d, %ecx
leaq 0x26(%rsp), %r8
leaq 0xf(%rsp), %r9
callq 0x2887a
movq 0x4e28(%r15), %rcx
movzwl 0x26(%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 0x2a7f8
movq %r15, %rdi
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
callq 0x2996a
movb $0x1, %cl
movl %ecx, 0x18(%rsp)
testb %al, %al
je 0x2a867
movq %rbx, %rdi
movl %ebp, %esi
movl %r13d, %edx
callq 0x28692
movq 0x10(%rsp), %rdi
jmp 0x2a68a
movq 0x10(%rsp), %rdi
testb $0x1, 0x18(%rsp)
jne 0x2a30c
jmp 0x2a83b
movl $0x0, 0x18(%rsp)
jmp 0x2a67c
movl $0x0, 0x18(%rsp)
jmp 0x2a63b
movzwl 0xc8332(%rdi), %eax
testw %ax, %ax
je 0x2a878
movzwl 0xc8330(%rdi), %ecx
movl %ecx, %edx
movzwl %dx, %edx
shll $0x4, %edx
movzwl 0xa(%rbx,%rdx), %edx
decl %eax
cmpw %cx, %dx
jne 0x2a850
testw %ax, %ax
je 0x2a878
xorl %eax, %eax
addq $0x48, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movb $0x1, %al
jmp 0x2a869