// File: /workspace/github_cpp_makefile_star2_O1/Alcaro[P]bridges/solver.cpp
// Function: (anonymous namespace)::solver<((anonymous namespace)::op_t)1>::solve_rec(unsigned short, unsigned short)
int solve_rec(uint16_t layer, uint16_t maxlayer)
	{
//static int n=0;if(layer>n){n=layer;printf("MAXDEPTH=%i\n",n);}
//printf("LAYER=%i\n",layer);
		add_difficulty(3*layer*layer);
		
		size_t layerbufsize = sizeof(uint16_t)*100*map.height;
		
		uint16_t maxlayer2 = sizeof(possibilities_buf)/layerbufsize;
		if (op != op_hint && op != op_difficulty) maxlayer = maxlayer2; // discard the argument and hope inliner deletes it
		if (layer < maxlayer && layer < maxlayer2)
		{
			if (!do_isolation_rule()) return false;
			
			//if still unsure, guess
			for (int y=0;y<map.height;y++)
			for (int x=0;x<map.width;x++)
			{
				uint16_t index = y*100+x;
//printf("EEE=%.3i\n",index);
				//gamemap::island& here = map.map[y][x];
				uint16_t flags = possibilities[index];
				uint16_t multidir_flags = (flags & (flags>>4 | flags>>8));
				if (!multidir_flags) continue; // no guess possible? skip this tile
				if (map.map[y][x].population < 0) continue; // don't guess on ocean tiles
				
				//right and up (ignore left/down, they'd only find duplicates)
				for (int dir=0;dir<2;dir++)
				{
//printf("%.4X:%.4X\n",flags,multidir_flags & (0x0111<<dir));
					//if multiple bridge numbers are allowed in this direction...
					if (multidir_flags & (0x0111<<dir))
					{
						int set_mask = (dir ? 0xDDDD : 0xEEEE);
						for (int n=0;n<=2;n++)
						{
							int dirbit = (0x0001<<(n*4)<<dir);
							if (flags & dirbit)
							{
//printf("GUESS:BEGIN(%.3i:%.4X->%.4X)\n",index,flags,(flags & (set_mask | dirbit)));
								//if looking for another solution, only make contrary assumptions
								// (but only for first layer, deeper ones can do whatever)
								if (op==op_another && layer==0 && map.get(index).bridges[dir] == n)
								{
//puts("GUESS:NOTSAME");
									continue;
								}
								
								int newflags = (flags & (set_mask | dirbit));
								memcpy(possibilities_buf + (layer+1)*layerbufsize, possibilities_buf + layer*layerbufsize, layerbufsize);
								possibilities = possibilities_buf + (layer+1)*layerbufsize;
								
								int ret = set_state(index, newflags);
								if (ret) ret = solve_rec(layer+1, maxlayer);
								if (ret == 1)
								{
//puts("GUESS:GOOD");
									//if that's a valid solution, return it
									//otherwise, mark the map unsolvable
									possibilities = possibilities_buf + layer*layerbufsize;
									memcpy(possibilities_buf + layer*layerbufsize, possibilities_buf + (layer+1)*layerbufsize, layerbufsize);
									return true;
								}
								if (ret == 0)
								{
//puts("GUESS:BAD");
									//if that can't be a valid solution, mark it as such
									possibilities = possibilities_buf + layer*layerbufsize;
									
									//it's possible that both yes and no are impossible
									if (!set_state(index, flags & ~dirbit)) return false;
									
									if (!do_isolation_rule()) return false;
									flags = possibilities[index];
									multidir_flags = (flags & (flags>>4 | flags>>8));
									if (!(multidir_flags & (0x0111<<dir))) break;
								}
							}
						}
					}
				}
			}
		}
		else if (layer < maxlayer2)
		{
			return -1;
		}
		else
		{
#ifndef STDOUT_ERROR
			puts("Out of memory");
			puts(map.serialize());
#endif
			abort();
			return -1;
		}
		
		if (op==op_another && layer==0) return false;
		return true;
	}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x98, %rsp
movq %rdi, %r14
movq (%rdi), %rax
movslq 0x4(%rax), %rax
imulq $0xc8, %rax, %rcx
xorl %ebx, %ebx
movl $0x9c400, %eax          # imm = 0x9C400
xorl %edx, %edx
movq %rcx, 0x28(%rsp)
divq %rcx
movzwl %ax, %eax
movl %esi, 0xc(%rsp)
cmpl %esi, %eax
jbe 0x28e81
movq %r14, %rdi
callq 0x28ec4
testb %al, %al
je 0x28e6d
movq (%r14), %rax
cmpl $0x0, 0x4(%rax)
jle 0x28e5c
movl 0xc(%rsp), %edx
movl %edx, %eax
incl %eax
movq 0x28(%rsp), %rsi
movq %rsi, %rcx
imulq %rax, %rcx
leaq (%r14,%rcx,2), %rcx
addq $0x4e30, %rcx           # imm = 0x4E30
movq %rcx, 0x58(%rsp)
movzwl %dx, %ecx
imulq %rsi, %rcx
leaq (%r14,%rcx,2), %rcx
addq $0x4e30, %rcx           # imm = 0x4E30
movq %rcx, 0x38(%rsp)
movzwl %ax, %eax
movl %eax, 0x44(%rsp)
xorl %ecx, %ecx
movq %r14, 0x10(%rsp)
movq (%r14), %rax
movl $0x5, %r13d
cmpl $0x0, (%rax)
jle 0x28e34
imulq $0x64, %rcx, %rdx
movq %rdx, 0x68(%rsp)
movq %rcx, 0x50(%rsp)
imulq $0x4b0, %rcx, %rcx      # imm = 0x4B0
movq %rcx, 0x60(%rsp)
xorl %edi, %edi
movq 0x68(%rsp), %rcx
addq %rdi, %rcx
movq 0x4e28(%r14), %rdx
movzwl %cx, %r8d
movq %r8, 0x30(%rsp)
movl %r8d, %esi
movzwl (%rdx,%rsi,2), %r15d
movl %r15d, %edx
shrl $0x4, %edx
movl %r15d, %esi
shrl $0x8, %esi
orl %edx, %esi
movl $0x7, %r13d
andw %r15w, %si
movl %esi, 0x1c(%rsp)
movq %rdi, 0x70(%rsp)
je 0x28df6
addq 0x60(%rsp), %rax
leaq (%rdi,%rdi,2), %rdx
cmpb $0x0, 0xc(%rax,%rdx,4)
js 0x28df6
movzwl %cx, %ecx
imulq $0x28f5c29, %rcx, %rax  # imm = 0x28F5C29
shrq $0x20, %rax
movq %rax, 0x78(%rsp)
imull $0x64, %eax, %eax
subl %eax, %ecx
movq %rcx, 0x80(%rsp)
xorl %edx, %edx
movzwl 0x1c(%rsp), %eax
movl $0x111, %esi            # imm = 0x111
movl %edx, %ecx
shll %cl, %esi
movl %esi, 0x40(%rsp)
testl %eax, %esi
je 0x28dd3
testq %rdx, %rdx
movl $0xdddd, %ecx           # imm = 0xDDDD
movl $0xeeee, %eax           # imm = 0xEEEE
cmovel %eax, %ecx
movl %ecx, 0x48(%rsp)
xorl %ebp, %ebp
movl %ebx, %esi
xorl %r12d, %r12d
movq %rdx, 0x20(%rsp)
movl $0x1, %ebx
movl %ebp, %ecx
shll %cl, %ebx
movl %edx, %ecx
shll %cl, %ebx
movzwl %r15w, %eax
testl %eax, %ebx
je 0x28cc1
cmpw $0x0, 0xc(%rsp)
jne 0x28c63
imulq $0x4b0, 0x78(%rsp), %rax # imm = 0x4B0
movq 0x10(%rsp), %rcx
addq (%rcx), %rax
movq 0x80(%rsp), %rcx
leaq (%rcx,%rcx,2), %rcx
leaq (%rax,%rcx,4), %rax
movzbl 0x14(%rdx,%rax), %eax
movl $0xd, %r13d
cmpl %eax, %r12d
je 0x28cc4
movl %esi, 0x4c(%rsp)
movl %ebx, %r13d
orl 0x48(%rsp), %r13d
movl %r15d, %r14d
movq 0x58(%rsp), %r15
movq %r15, %rdi
movq 0x38(%rsp), %rsi
movq 0x28(%rsp), %rdx
callq 0x3280
movq 0x10(%rsp), %rax
movq %r15, 0x4e28(%rax)
movl %r14d, %r15d
andl %r14d, %r13d
movzwl %r13w, %edx
movq %rax, %r13
movq %rax, %rdi
movq 0x30(%rsp), %rsi
callq 0x28484
testb %al, %al
je 0x28ccb
movq %r13, %rdi
movl 0x44(%rsp), %esi
callq 0x28a84
jmp 0x28cce
xorl %r13d, %r13d
movl %esi, %ebx
jmp 0x28d9e
movzbl %al, %eax
testl %eax, %eax
movl 0x4c(%rsp), %r14d
je 0x28d0b
cmpl $0x1, %eax
jne 0x28d93
movq 0x38(%rsp), %rdi
movq %rdi, 0x4e28(%r13)
movq 0x58(%rsp), %rsi
movq 0x28(%rsp), %rdx
callq 0x3280
movl $0x1, %r13d
movl $0x1, %ebx
jmp 0x28d99
movq 0x38(%rsp), %rax
movq %rax, 0x4e28(%r13)
notl %ebx
andl %r15d, %ebx
movzwl %bx, %edx
movq %r13, %rdi
movq 0x30(%rsp), %rsi
callq 0x28484
xorl %ebx, %ebx
movq %r13, %rdi
movl $0x1, %r13d
testb %al, %al
je 0x28d99
callq 0x28ec4
testb %al, %al
movq 0x20(%rsp), %rdx
je 0x28d9e
movq 0x10(%rsp), %rax
movq 0x4e28(%rax), %rax
movq 0x30(%rsp), %rcx
movzwl (%rax,%rcx,2), %r15d
movl %r15d, %eax
shrl $0x4, %eax
movl %r15d, %ecx
shrl $0x8, %ecx
orl %eax, %ecx
andl %r15d, %ecx
movl %ecx, 0x1c(%rsp)
movl %ecx, %eax
andl 0x40(%rsp), %eax
testl $0xffff, %eax           # imm = 0xFFFF
movl $0x0, %r13d
movl $0xb, %eax
cmovel %eax, %r13d
movl %r14d, %ebx
jmp 0x28d9e
xorl %r13d, %r13d
movl %r14d, %ebx
movq 0x20(%rsp), %rdx
cmpl $0xd, %r13d
je 0x28da9
testl %r13d, %r13d
jne 0x28dc1
incl %r12d
addl $0x4, %ebp
movl %ebx, %esi
cmpl $0x3, %r12d
jne 0x28c11
movl $0xb, %r13d
cmpl $0xb, %r13d
movl $0x0, %eax
cmovel %eax, %r13d
testl %r13d, %r13d
jne 0x28de9
leaq 0x1(%rdx), %rax
testq %rdx, %rdx
movq %rax, %rdx
je 0x28bd7
movl $0x8, %r13d
cmpl $0x8, %r13d
movl $0x0, %eax
cmovel %eax, %r13d
cmpl $0x7, %r13d
je 0x28e01
testl %r13d, %r13d
jne 0x28e2a
movq 0x70(%rsp), %rdi
incq %rdi
movq 0x10(%rsp), %r14
movq (%r14), %rax
movslq (%rax), %rcx
cmpq %rcx, %rdi
jl 0x28b5a
movq 0x50(%rsp), %rcx
movl $0x5, %r13d
jmp 0x28e34
movq 0x10(%rsp), %r14
movq 0x50(%rsp), %rcx
cmpl $0x5, %r13d
jne 0x28e53
incq %rcx
movq (%r14), %rax
movslq 0x4(%rax), %rax
cmpq %rax, %rcx
jl 0x28b2c
movl $0x2, %r13d
cmpl $0x2, %r13d
sete %al
jmp 0x28e5e
movb $0x1, %al
testb %al, %al
je 0x28e6d
xorl %ebx, %ebx
cmpw $0x0, 0xc(%rsp)
setne %bl
movl %ebx, %eax
addq $0x98, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x9f16(%rip), %rdi      # 0x32d9e
callq 0x3590
movq (%r14), %rsi
leaq 0x88(%rsp), %rbx
movq %rbx, %rdi
callq 0x236d6
cmpb $0x0, 0xf(%rbx)
movq %rbx, %rdi
jns 0x28eb1
movq 0x88(%rsp), %rdi
callq 0x3590
movq %rbx, %rdi
callq 0x2a54c
callq 0x3180
nop