// File: /workspace/github_cpp_makefile_star2_O2/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 $0x88, %rsp
movq %rdi, %rbp
movq (%rdi), %rax
movslq 0x4(%rax), %rax
imulq $0xc8, %rax, %rcx
xorl %r12d, %r12d
movl $0x9c400, %eax          # imm = 0x9C400
xorl %edx, %edx
movq %rcx, 0x18(%rsp)
divq %rcx
movzwl %ax, %eax
movl %esi, 0xc(%rsp)
cmpl %esi, %eax
jbe 0x22716
movq %rbp, %rdi
callq 0x22754
testb %al, %al
je 0x226f2
movl 0xc(%rsp), %edx
movl %edx, %eax
incl %eax
movq 0x18(%rsp), %rsi
movq %rsi, %rcx
imulq %rax, %rcx
leaq 0x4e30(,%rcx,2), %rcx
addq %rbp, %rcx
movq %rcx, 0x38(%rsp)
movzwl %dx, %ecx
imulq %rsi, %rcx
leaq 0x4e30(,%rcx,2), %rcx
addq %rbp, %rcx
movq %rcx, 0x20(%rsp)
movq (%rbp), %rcx
pushq $0x1
popq %r8
movzwl %ax, %eax
movl %eax, 0x28(%rsp)
movq %rcx, %rdx
xorl %esi, %esi
movslq 0x4(%rdx), %rax
cmpq %rax, %rsi
jge 0x22707
imulq $0x64, %rsi, %rax
movq %rax, 0x58(%rsp)
movq %rsi, 0x48(%rsp)
imulq $0x4b0, %rsi, %rax      # imm = 0x4B0
movq %rax, 0x50(%rsp)
xorl %r9d, %r9d
movslq (%rdx), %rax
cmpq %rax, %r9
jge 0x226c4
movq 0x58(%rsp), %rax
addq %r9, %rax
movq 0x4e28(%rbp), %rsi
movzwl %ax, %r13d
movl %r13d, %edi
movzwl (%rsi,%rdi,2), %r15d
movl %r15d, %esi
shrl $0x4, %esi
movl %r15d, %r12d
shrl $0x8, %r12d
orl %esi, %r12d
andw %r15w, %r12w
movq %r9, 0x60(%rsp)
je 0x226b4
addq 0x50(%rsp), %rdx
imulq $0xc, %r9, %rsi
cmpb $0x0, 0xc(%rsi,%rdx)
js 0x226b4
xorl %edx, %edx
movw $0x64, %cx
divw %cx
movzwl %ax, %eax
movzwl %dx, %ecx
imulq $0x4b0, %rax, %rax      # imm = 0x4B0
movq %rax, 0x70(%rsp)
imulq $0xc, %rcx, %rax
movq %rax, 0x68(%rsp)
xorl %edx, %edx
cmpq $0x2, %rdx
je 0x226b0
movzwl %r12w, %eax
movl $0x111, %esi            # imm = 0x111
movl %edx, %ecx
shll %cl, %esi
movl %esi, 0x2c(%rsp)
testl %eax, %esi
je 0x226a8
testq %rdx, %rdx
movl $0xdddd, %ecx           # imm = 0xDDDD
movl $0xeeee, %eax           # imm = 0xEEEE
cmovel %eax, %ecx
movl %ecx, 0x30(%rsp)
xorl %esi, %esi
xorl %edi, %edi
movq %rdx, 0x40(%rsp)
cmpl $0x3, %edi
je 0x226a8
movl %r8d, %r14d
movl %esi, %ecx
shll %cl, %r14d
movl %edx, %ecx
shll %cl, %r14d
movzwl %r15w, %eax
testl %eax, %r14d
je 0x2269e
cmpw $0x0, 0xc(%rsp)
jne 0x225a8
movq (%rbp), %rax
addq 0x70(%rsp), %rax
addq 0x68(%rsp), %rax
movzbl 0x14(%rdx,%rax), %eax
cmpl %eax, %edi
je 0x2269e
movl %edi, 0x10(%rsp)
movl %esi, 0x14(%rsp)
movl %r14d, %ebx
orl 0x30(%rsp), %ebx
movl %r15d, 0x34(%rsp)
movq %r13, %r15
movq 0x38(%rsp), %r13
movq %r13, %rdi
movq 0x20(%rsp), %rsi
movq 0x18(%rsp), %rdx
callq 0x3280
movq %r13, 0x4e28(%rbp)
movq %r15, %r13
movl 0x34(%rsp), %r15d
andl %r15d, %ebx
movzwl %bx, %edx
movq %rbp, %rdi
movl %r13d, %esi
callq 0x21e36
testb %al, %al
je 0x22625
movq %rbp, %rdi
movl 0x28(%rsp), %esi
callq 0x223d6
testl %eax, %eax
je 0x22625
cmpl $0x1, %eax
pushq $0x1
popq %r8
movq 0x40(%rsp), %rdx
movl 0x14(%rsp), %esi
movl 0x10(%rsp), %edi
jne 0x2269e
jmp 0x226d1
movq 0x20(%rsp), %rax
movq %rax, 0x4e28(%rbp)
notl %r14d
andl %r14d, %r15d
movzwl %r15w, %edx
movq %rbp, %rdi
movl %r13d, %esi
callq 0x21e36
xorl %r12d, %r12d
testb %al, %al
je 0x226f2
movq %rbp, %rdi
callq 0x22754
testb %al, %al
je 0x226f2
movq 0x4e28(%rbp), %rax
movzwl (%rax,%r13,2), %r15d
movl %r15d, %eax
shrl $0x4, %eax
movl %r15d, %r12d
shrl $0x8, %r12d
orl %eax, %r12d
andl %r15d, %r12d
movl %r12d, %eax
andl 0x2c(%rsp), %eax
testw $0xffff, %ax            # imm = 0xFFFF
pushq $0x1
popq %r8
movq 0x40(%rsp), %rdx
movl 0x14(%rsp), %esi
movl 0x10(%rsp), %edi
je 0x226a8
incl %edi
addl $0x4, %esi
jmp 0x22562
incq %rdx
jmp 0x22522
movq (%rbp), %rcx
movq 0x60(%rsp), %r9
incq %r9
movq %rcx, %rdx
jmp 0x224a2
movq 0x48(%rsp), %rsi
incq %rsi
jmp 0x22478
movq 0x20(%rsp), %rdi
movq %rdi, 0x4e28(%rbp)
movq 0x38(%rsp), %rsi
movq 0x18(%rsp), %rdx
movl %r8d, %ebx
callq 0x3280
movl %ebx, %r12d
movl %r12d, %eax
addq $0x88, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
xorl %r12d, %r12d
cmpw $0x0, 0xc(%rsp)
setne %r12b
jmp 0x226f2
leaq 0x96b1(%rip), %rdi      # 0x2bdce
callq 0x3590
movq (%rbp), %rsi
leaq 0x78(%rsp), %rbx
movq %rbx, %rdi
callq 0x1d85a
cmpb $0x0, 0xf(%rbx)
movq %rbx, %rdi
jns 0x22741
movq 0x78(%rsp), %rdi
callq 0x3590
movq %rbx, %rdi
callq 0x23ab8
callq 0x3180
nop