| 
						
						
							
								
							
						
						
					 | 
				
				 | 
				
					@ -6,8 +6,8 @@ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					using klotski::mover::S2Mover; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					using klotski::codec::RawCode; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					#define APPLY_MASK(code, addr, mask) \ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    (((code) >> ((addr) * 3)) & (uint64_t)(mask)) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					#define CAPTURE(code, addr) \ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    (((code) >> ((addr) * 3)) & (uint64_t)(0b111)) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					#define UNSET_1x1(code, addr) \ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    ((code) & ~((uint64_t)0b111 << ((addr) * 3))) | 
				
			
			
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
				 | 
				
					@ -33,30 +33,31 @@ using klotski::codec::RawCode; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					#define SET_2x2(code, addr) \ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    ((code) | ((uint64_t)0b111'111'000'000'111'100 << ((addr) * 3))) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					void S2Mover::two_space_a(uint64_t code, int offset) const { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					template <int N> | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					void S2Mover::two_space_a(uint64_t code) const { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    // ---------------- case up ----------------
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    do { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        if (offset >= 4) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            const uint8_t up_c = APPLY_MASK(code, offset - 4, 0b111); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        if (N >= 4) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            const uint8_t up_c = CAPTURE(code, N - 4); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            if (up_c == BLOCK_1x2) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                release_(SET_1x2(UNSET_1x2(code, offset - 4), offset)); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                release_(SET_1x2(UNSET_1x2(code, N - 4), N)); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                break; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            if (up_c == BLOCK_1x1) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                const auto tmp = UNSET_1x1(code, offset - 4); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                release_(SET_1x1(tmp, offset)); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                release_(SET_1x1(tmp, offset + 1)); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                const auto tmp = UNSET_1x1(code, N - 4); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                release_(SET_1x1(tmp, N)); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                release_(SET_1x1(tmp, N + 1)); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                // -> check right
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            } else if (up_c == BLOCK_fill) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                if (offset >= 8) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    const uint8_t up_a = APPLY_MASK(code, offset - 8, 0b111); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                if (N >= 8) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    const uint8_t up_a = CAPTURE(code, N - 8); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    if (up_a == BLOCK_2x2) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                        release_(SET_2x2(UNSET_2x2(code, offset - 8), offset - 4)); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                        release_(SET_2x2(UNSET_2x2(code, N - 8), N - 4)); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                        break; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    if (up_a == BLOCK_2x1) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                        release_(SET_2x1(UNSET_2x1(code, offset - 8), offset - 4)); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                        release_(SET_2x1(UNSET_2x1(code, N - 8), N - 4)); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                        // -> check right
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                } | 
				
			
			
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
				 | 
				
					@ -65,18 +66,18 @@ void S2Mover::two_space_a(uint64_t code, int offset) const { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                std::unreachable(); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            const uint8_t up_d = APPLY_MASK(code, offset - 3, 0b111); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            const uint8_t up_d = CAPTURE(code, N - 3); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            if (up_d == BLOCK_1x1) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                const auto tmp = UNSET_1x1(code, offset - 3); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                release_(SET_1x1(tmp, offset + 1)); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                release_(SET_1x1(tmp, offset)); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                const auto tmp = UNSET_1x1(code, N - 3); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                release_(SET_1x1(tmp, N + 1)); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                release_(SET_1x1(tmp, N)); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                break; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            if (up_d == BLOCK_fill) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                if (offset >= 8) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    const uint8_t up_b = APPLY_MASK(code, offset - 7, 0b111); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                if (N >= 8) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    const uint8_t up_b = CAPTURE(code, N - 7); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    if (up_b == BLOCK_2x1) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                        release_(SET_2x1(UNSET_2x1(code, offset - 7), offset - 3)); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                        release_(SET_2x1(UNSET_2x1(code, N - 7), N - 3)); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                        break; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                } | 
				
			
			
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
				 | 
				
					@ -87,93 +88,80 @@ void S2Mover::two_space_a(uint64_t code, int offset) const { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    // ---------------- case down ----------------
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    do { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        if (offset < 16) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            const uint8_t down_a = APPLY_MASK(code, offset + 4, 0b111); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            if (down_a == BLOCK_1x2) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                release_(SET_1x2(UNSET_1x2(code, offset + 4), offset)); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                break; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            if (down_a == BLOCK_2x2) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                release_(SET_2x2(UNSET_2x2(code, offset + 4), offset)); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                break; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            if (down_a == BLOCK_2x1) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                release_(SET_2x1(UNSET_2x1(code, offset + 4), offset)); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            } else if (down_a == BLOCK_1x1) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                const auto tmp = UNSET_1x1(code, offset + 4); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                release_(SET_1x1(tmp, offset)); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                release_(SET_1x1(tmp, offset + 1)); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            const uint8_t down_b = APPLY_MASK(code, offset + 5, 0b111); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            if (down_b == BLOCK_1x1) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                const auto tmp = UNSET_1x1(code, offset + 5); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                release_(SET_1x1(tmp, offset + 1)); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                release_(SET_1x1(tmp, offset)); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        if constexpr(N < 16) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            if (const uint8_t block = CAPTURE(code, N + 4); block == BLOCK_1x1) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                const auto tmp = UNSET_1x1(code, N + 4); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                release_(SET_1x1(tmp, N)); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                release_(SET_1x1(tmp, N + 1)); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            } else if (block == BLOCK_1x2) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                release_(SET_1x2(UNSET_1x2(code, N + 4), N)); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                break; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            } else if constexpr(N < 12) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                if (block == BLOCK_2x1) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    release_(SET_2x1(UNSET_2x1(code, N + 4), N)); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                } else if (block == BLOCK_2x2) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    release_(SET_2x2(UNSET_2x2(code, N + 4), N)); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    break; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            if (down_b == BLOCK_2x1) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                release_(SET_2x1(UNSET_2x1(code, offset + 5), offset + 1)); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                break; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            if (const uint8_t block = CAPTURE(code, N + 5); block == BLOCK_1x1) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                const auto tmp = UNSET_1x1(code, N + 5); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                release_(SET_1x1(tmp, N + 1)); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                release_(SET_1x1(tmp, N)); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            } else if constexpr(N < 12) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                if (block == BLOCK_2x1) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    release_(SET_2x1(UNSET_2x1(code, N + 5), N + 1)); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    } while (false); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    // ---------------- case left ----------------
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    do { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        if ((offset % 4) != 0) { // 1x1
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            if (APPLY_MASK(code, offset - 1, 0b111) == 0b011) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                release_(SET_1x1(UNSET_1x1(code, offset - 1), offset)); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                release_(SET_1x1(UNSET_1x1(code, offset - 1), offset + 1)); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                break; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        if ((offset % 4) == 2) { // 1x2
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            if (APPLY_MASK(code, offset - 2, 0b111'111) == 0b111'001) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                release_(SET_1x2(UNSET_1x2(code, offset - 2), offset - 1)); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                release_(SET_1x2(UNSET_1x2(code, offset - 2), offset)); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                break; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    if constexpr(N % 4 != 0) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        if (CAPTURE(code, N - 1) == BLOCK_1x1) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            release_(SET_1x1(UNSET_1x1(code, N - 1), N)); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            release_(SET_1x1(UNSET_1x1(code, N - 1), N + 1)); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        } else if constexpr(N % 4 == 2) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            if (CAPTURE(code, N - 2) == BLOCK_1x2) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                release_(SET_1x2(UNSET_1x2(code, N - 2), N - 1)); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                release_(SET_1x2(UNSET_1x2(code, N - 2), N)); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    } while (false); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    // ---------------- case right ----------------
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    do { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        if ((offset % 4) != 2) { // 1x1
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            if (APPLY_MASK(code, offset + 2, 0b111) == 0b011) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                release_(SET_1x1(UNSET_1x1(code, offset + 2), offset + 1)); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                release_(SET_1x1(UNSET_1x1(code, offset + 2), offset)); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                break; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        if ((offset % 4) == 0) { // 1x2
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            if (APPLY_MASK(code, offset + 2, 0b111'111) == 0b111'001) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                release_(SET_1x2(UNSET_1x2(code, offset + 2), offset + 1)); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                release_(SET_1x2(UNSET_1x2(code, offset + 2), offset)); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                break; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    if constexpr(N % 4 != 2) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        const uint8_t block = CAPTURE(code, N + 2); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        if (block == BLOCK_1x1) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            release_(SET_1x1(UNSET_1x1(code, N + 2), N + 1)); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            release_(SET_1x1(UNSET_1x1(code, N + 2), N)); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        } else if constexpr(N % 4 == 0) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            if (block == BLOCK_1x2) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                release_(SET_1x2(UNSET_1x2(code, N + 2), N + 1)); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                release_(SET_1x2(UNSET_1x2(code, N + 2), N)); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    } while (false); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					} | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					void S2Mover::two_space_b(uint64_t code, int offset) const { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					template <int N> | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					void S2Mover::two_space_b(uint64_t code) const { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    // ---------------- case up ----------------
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    do { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        if (offset >= 4) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            if (APPLY_MASK(code, offset - 4, 0b111) == 0b011) { // 1x1
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                release_(SET_1x1(UNSET_1x1(code, offset - 4), offset)); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                release_(SET_1x1(UNSET_1x1(code, offset - 4), offset + 4)); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        if (N >= 4) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            if (CAPTURE(code, N - 4) == BLOCK_1x1) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                release_(SET_1x1(UNSET_1x1(code, N - 4), N)); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                release_(SET_1x1(UNSET_1x1(code, N - 4), N + 4)); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                break; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        if (offset >= 8) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            if (APPLY_MASK(code, offset - 8, 0b111'000'000'000'111) == 0b111'000'000'000'010) { // 2x1
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                release_(SET_2x1(UNSET_2x1(code, offset - 8), offset - 4)); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                release_(SET_2x1(UNSET_2x1(code, offset - 8), offset)); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        if (N >= 8) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            if (CAPTURE(code, N - 8) == BLOCK_2x1) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                release_(SET_2x1(UNSET_2x1(code, N - 8), N - 4)); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                release_(SET_2x1(UNSET_2x1(code, N - 8), N)); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                break; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        } | 
				
			
			
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
				 | 
				
					@ -182,17 +170,17 @@ void S2Mover::two_space_b(uint64_t code, int offset) const { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    // ---------------- case down ----------------
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    do { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        if (offset < 12) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            if (APPLY_MASK(code, offset + 8, 0b111) == 0b011) { // 1x1
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                release_(SET_1x1(UNSET_1x1(code, offset + 8), offset + 4)); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                release_(SET_1x1(UNSET_1x1(code, offset + 8), offset)); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        if (N < 12) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            if (CAPTURE(code, N + 8) == BLOCK_1x1) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                release_(SET_1x1(UNSET_1x1(code, N + 8), N + 4)); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                release_(SET_1x1(UNSET_1x1(code, N + 8), N)); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                break; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        if (offset < 8) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            if (APPLY_MASK(code, offset + 8, 0b111'000'000'000'111) == 0b111'000'000'000'010) { // 2x1
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                release_(SET_2x1(UNSET_2x1(code, offset + 8), offset + 4)); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                release_(SET_2x1(UNSET_2x1(code, offset + 8), offset)); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        if (N < 8) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            if (CAPTURE(code, N + 8) == BLOCK_2x1) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                release_(SET_2x1(UNSET_2x1(code, N + 8), N + 4)); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                release_(SET_2x1(UNSET_2x1(code, N + 8), N)); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                break; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        } | 
				
			
			
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
				 | 
				
					@ -201,26 +189,26 @@ void S2Mover::two_space_b(uint64_t code, int offset) const { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    // ---------------- case left ----------------
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    do { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        if ((offset % 4) != 0) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            const uint8_t left_b = APPLY_MASK(code, offset - 1, 0b111); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        if ((N % 4) != 0) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            const uint8_t left_b = CAPTURE(code, N - 1); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            if (left_b == BLOCK_2x1) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                release_(SET_2x1(UNSET_2x1(code, offset - 1), offset)); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                release_(SET_2x1(UNSET_2x1(code, N - 1), N)); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                break; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            if (left_b == BLOCK_1x1) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                const auto tmp = UNSET_1x1(code, offset - 1); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                release_(SET_1x1(tmp, offset)); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                release_(SET_1x1(tmp, offset + 4)); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                const auto tmp = UNSET_1x1(code, N - 1); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                release_(SET_1x1(tmp, N)); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                release_(SET_1x1(tmp, N + 4)); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                // -> check down
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            } else if (left_b == BLOCK_fill) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                if ((offset % 4) >= 2) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    const uint8_t left_d = APPLY_MASK(code, offset - 2, 0b111); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                if ((N % 4) >= 2) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    const uint8_t left_d = CAPTURE(code, N - 2); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    if (left_d == BLOCK_2x2) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                        release_(SET_2x2(UNSET_2x2(code, offset - 2), offset - 1)); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                        release_(SET_2x2(UNSET_2x2(code, N - 2), N - 1)); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                        break; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    if (left_d == BLOCK_1x2) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                        release_(SET_1x2(UNSET_1x2(code, offset - 2), offset - 1)); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                        release_(SET_1x2(UNSET_1x2(code, N - 2), N - 1)); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                        // -> check down
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                } | 
				
			
			
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
				 | 
				
					@ -229,18 +217,18 @@ void S2Mover::two_space_b(uint64_t code, int offset) const { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                std::unreachable(); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            const uint8_t left_d = APPLY_MASK(code, offset + 3, 0b111); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            const uint8_t left_d = CAPTURE(code, N + 3); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            if (left_d == BLOCK_1x1) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                const auto tmp = UNSET_1x1(code, offset + 3); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                release_(SET_1x1(tmp, offset + 4)); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                release_(SET_1x1(tmp, offset)); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                const auto tmp = UNSET_1x1(code, N + 3); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                release_(SET_1x1(tmp, N + 4)); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                release_(SET_1x1(tmp, N)); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                break; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            if (left_d == BLOCK_fill) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                if ((offset % 4) >= 2) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    const uint8_t left_c = APPLY_MASK(code, offset + 2, 0b111); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                if ((N % 4) >= 2) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    const uint8_t left_c = CAPTURE(code, N + 2); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    if (left_c == BLOCK_1x2) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                        release_(SET_1x2(UNSET_1x2(code, offset + 2), offset + 3)); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                        release_(SET_1x2(UNSET_1x2(code, N + 2), N + 3)); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                        break; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                } | 
				
			
			
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
				 | 
				
					@ -251,33 +239,33 @@ void S2Mover::two_space_b(uint64_t code, int offset) const { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    // ---------------- case right ----------------
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    do { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        if ((offset % 4) != 3) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            const uint8_t right_a = APPLY_MASK(code, offset + 1, 0b111); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        if ((N % 4) != 3) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            const uint8_t right_a = CAPTURE(code, N + 1); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            if (right_a == BLOCK_2x1) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                release_(SET_2x1(UNSET_2x1(code, offset + 1), offset)); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                release_(SET_2x1(UNSET_2x1(code, N + 1), N)); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                break; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            if (right_a == BLOCK_2x2) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                release_(SET_2x2(UNSET_2x2(code, offset + 1), offset)); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                release_(SET_2x2(UNSET_2x2(code, N + 1), N)); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                break; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            if (right_a == BLOCK_1x2) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                release_(SET_1x2(UNSET_1x2(code, offset + 1), offset)); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                release_(SET_1x2(UNSET_1x2(code, N + 1), N)); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            } else if (right_a == BLOCK_1x1) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                const auto tmp = UNSET_1x1(code, offset + 1); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                release_(SET_1x1(tmp, offset)); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                release_(SET_1x1(tmp, offset + 4)); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                const auto tmp = UNSET_1x1(code, N + 1); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                release_(SET_1x1(tmp, N)); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                release_(SET_1x1(tmp, N + 4)); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            const uint8_t right_c = APPLY_MASK(code, offset + 5, 0b111); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            const uint8_t right_c = CAPTURE(code, N + 5); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            if (right_c == BLOCK_1x1) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                const auto tmp = UNSET_1x1(code, offset + 5); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                release_(SET_1x1(tmp, offset + 4)); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                release_(SET_1x1(tmp, offset)); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                const auto tmp = UNSET_1x1(code, N + 5); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                release_(SET_1x1(tmp, N + 4)); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                release_(SET_1x1(tmp, N)); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                break; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            if (right_c == BLOCK_1x2) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                release_(SET_1x2(UNSET_1x2(code, offset + 5), offset + 4)); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                release_(SET_1x2(UNSET_1x2(code, N + 5), N + 4)); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                break; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        } | 
				
			
			
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
				 | 
				
					@ -287,17 +275,17 @@ void S2Mover::two_space_b(uint64_t code, int offset) const { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					template <int N> | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					void S2Mover::one_space(uint64_t code) const { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    if constexpr(N >= 4) { // case up
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        if (APPLY_MASK(code, N - 4, 0b111) == BLOCK_1x1) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        if (CAPTURE(code, N - 4) == BLOCK_1x1) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            release_(SET_1x1(UNSET_1x1(code, N - 4), N)); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        } else if constexpr(N >= 8) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            if (APPLY_MASK(code, N - 8, 0b111) == BLOCK_2x1) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            if (CAPTURE(code, N - 8) == BLOCK_2x1) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                release_(SET_2x1(UNSET_2x1(code, N - 8), N - 4)); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    if constexpr(N < 16) { // case down
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        const uint8_t block = APPLY_MASK(code, N + 4, 0b111); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        const uint8_t block = CAPTURE(code, N + 4); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        if (block == BLOCK_1x1) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            release_(SET_1x1(UNSET_1x1(code, N + 4), N)); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        } else if constexpr(N < 12) { | 
				
			
			
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
				 | 
				
					@ -308,17 +296,17 @@ void S2Mover::one_space(uint64_t code) const { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    if constexpr(N % 4 != 0) { // case left
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        if (APPLY_MASK(code, N - 1, 0b111) == BLOCK_1x1) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        if (CAPTURE(code, N - 1) == BLOCK_1x1) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            release_(SET_1x1(UNSET_1x1(code, N - 1), N)); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        } else if constexpr(N % 4 >= 2) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            if (APPLY_MASK(code, N - 2, 0b111) == BLOCK_1x2) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            if (CAPTURE(code, N - 2) == BLOCK_1x2) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                release_(SET_1x2(UNSET_1x2(code, N - 2), N - 1)); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    if constexpr(N % 4 != 3) { // case right
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        const uint8_t block = APPLY_MASK(code, N + 1, 0b111); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        const uint8_t block = CAPTURE(code, N + 1); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        if (block == BLOCK_1x1) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            release_(SET_1x1(UNSET_1x1(code, N + 1), N)); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        } else if constexpr(N % 4 <= 1) { | 
				
			
			
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
				 | 
				
					@ -329,29 +317,51 @@ void S2Mover::one_space(uint64_t code) const { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					} | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					void S2Mover::one_space_(uint64_t code, int offset) const { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					void S2Mover::two_space_a_(uint64_t code, int offset) const { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    switch (offset) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    case 0: two_space_a<0>(code); break; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    case 1: two_space_a<1>(code); break; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    case 2: two_space_a<2>(code); break; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    case 4: two_space_a<4>(code); break; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    case 5: two_space_a<5>(code); break; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    case 6: two_space_a<6>(code); break; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    case 8: two_space_a<8>(code); break; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    case 9: two_space_a<9>(code); break; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    case 10: two_space_a<10>(code); break; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    case 12: two_space_a<12>(code); break; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    case 13: two_space_a<13>(code); break; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    case 14: two_space_a<14>(code); break; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    case 16: two_space_a<16>(code); break; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    case 17: two_space_a<17>(code); break; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    case 18: two_space_a<18>(code); break; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    default: std::unreachable(); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					} | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					void S2Mover::two_space_b_(uint64_t code, int offset) const { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    switch (offset) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    // case 0: return one_space<0>(code);
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    // case 1: return one_space<1>(code);
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    // case 2: return one_space<2>(code);
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    // case 3: return one_space<3>(code);
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    // case 4: return one_space<4>(code);
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    // case 5: return one_space<5>(code);
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    // case 6: return one_space<6>(code);
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    // case 7: return one_space<7>(code);
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    // case 8: return one_space<8>(code);
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    // case 9: return one_space<9>(code);
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    // case 10: return one_space<10>(code);
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    // case 11: return one_space<11>(code);
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    // case 12: return one_space<12>(code);
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    // case 13: return one_space<13>(code);
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    // case 14: return one_space<14>(code);
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    // case 15: return one_space<15>(code);
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    // case 16: return one_space<16>(code);
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    // case 17: return one_space<17>(code);
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    // case 18: return one_space<18>(code);
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    // case 19: return one_space<19>(code);
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    case 0: two_space_b<0>(code); break; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    case 1: two_space_b<1>(code); break; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    case 2: two_space_b<2>(code); break; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    case 3: two_space_b<3>(code); break; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    case 4: two_space_b<4>(code); break; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    case 5: two_space_b<5>(code); break; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    case 6: two_space_b<6>(code); break; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    case 7: two_space_b<7>(code); break; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    case 8: two_space_b<8>(code); break; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    case 9: two_space_b<9>(code); break; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    case 10: two_space_b<10>(code); break; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    case 11: two_space_b<11>(code); break; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    case 12: two_space_b<12>(code); break; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    case 13: two_space_b<13>(code); break; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    case 14: two_space_b<14>(code); break; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    case 15: two_space_b<15>(code); break; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    default: std::unreachable(); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					} | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					void S2Mover::one_space_(uint64_t code, int offset) const { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    switch (offset) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    case 0: one_space<0>(code); break; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    case 1: one_space<1>(code); break; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    case 2: one_space<2>(code); break; | 
				
			
			
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
				 | 
				
					@ -372,32 +382,11 @@ void S2Mover::one_space_(uint64_t code, int offset) const { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    case 17: one_space<17>(code); break; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    case 18: one_space<18>(code); break; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    case 19: one_space<19>(code); break; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    default: std::unreachable(); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					} | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					void S2Mover::next_cases(uint64_t code) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    // std::cout << RawCode::unsafe_create(code) << std::endl;
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    // constexpr int space_1 = 17, space_2 = 18;
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    // constexpr int space_1 = 1, space_2 = 2;
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    // constexpr int space_1 = 18, space_2 = 19;
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    // constexpr int space_1 = 16, space_2 = 17;
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    // two_space_a(code, space_1);
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    // constexpr int space_1 = 12, space_2 = 16;
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    // constexpr int space_1 = 0, space_2 = 4;
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    // constexpr int space_1 = 15, space_2 = 19;
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    // constexpr int space_1 = 12, space_2 = 16;
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    // two_space_b(code, space_1);
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    // constexpr int space = 12;
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    // constexpr int space = 4;
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    // constexpr int space = 19;
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    // constexpr int space = 16;
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    // one_space(code, space);
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    int space_1 = -1; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    int space_2 = -1; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    for (int addr = 0; addr < 20; ++addr) { | 
				
			
			
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
				 | 
				
					@ -409,13 +398,11 @@ void S2Mover::next_cases(uint64_t code) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            space_2 = addr; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    // std::cout << space_1 << std::endl;
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    // std::cout << space_2 << std::endl;
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    if (space_1 + 1 == space_2 && space_1 % 4 != 3) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        two_space_a(code, space_1); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        two_space_a_(code, space_1); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    } else if (space_1 + 4 == space_2) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        two_space_b(code, space_1); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        two_space_b_(code, space_1); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    } else { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        one_space_(code, space_1); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        one_space_(code, space_2); | 
				
			
			
		
	
	
		
			
				
					| 
						
							
								
							
						
						
						
					 | 
				
				 | 
				
					
  |