mirror of https://github.com/dnomd343/klotski.git
dnomd343
2 years ago
10 changed files with 319 additions and 293 deletions
@ -0,0 +1,9 @@ |
|||||
|
#ifndef _CASE_H_ |
||||
|
#define _CASE_H_ |
||||
|
|
||||
|
#include <cstdint> |
||||
|
#include <vector> |
||||
|
|
||||
|
void find_all_case(std::vector<uint64_t> *all_case); |
||||
|
|
||||
|
#endif |
@ -0,0 +1,31 @@ |
|||||
|
#include "common.h" |
||||
|
|
||||
|
//inline int binary_num(uint32_t binary, int length) { // get number of non-zero bit
|
||||
|
int binary_num(uint32_t binary, int length) { // get number of non-zero bit
|
||||
|
int num = 0; |
||||
|
for (int i = 0; i < length; ++i) { |
||||
|
num += int((binary >> i) & 0x1); |
||||
|
} |
||||
|
return num; |
||||
|
} |
||||
|
|
||||
|
//inline void binary_reverse(uint32_t &range) { // reverse binary every 2 bits
|
||||
|
void binary_reverse(uint32_t &range) { // reverse binary every 2 bits
|
||||
|
range = ((range << 16) & 0xFFFF0000) | ((range >> 16) & 0x0000FFFF); |
||||
|
range = ((range << 8) & 0xFF00FF00) | ((range >> 8) & 0x00FF00FF); |
||||
|
range = ((range << 4) & 0xF0F0F0F0) | ((range >> 4) & 0x0F0F0F0F); |
||||
|
range = ((range << 2) & 0xCCCCCCCC) | ((range >> 2) & 0x33333333); |
||||
|
} |
||||
|
|
||||
|
//inline void binary_to_str(uint64_t binary, char *string) {
|
||||
|
void binary_to_str(uint64_t binary, char *string) { |
||||
|
for (int i = 0; i < 9; ++i, ++string) { // only read low 9 * 4 bits
|
||||
|
*string = int8_t(binary >> (8 - i) * 4 & 0xF); |
||||
|
if (*string < 10) { |
||||
|
*string += 48; // 0 -> 48
|
||||
|
} else { |
||||
|
*string += 55; // A -> 65
|
||||
|
} |
||||
|
} |
||||
|
string[9] = 0x0; // string ending
|
||||
|
} |
@ -0,0 +1,10 @@ |
|||||
|
#ifndef _COMMON_H_ |
||||
|
#define _COMMON_H_ |
||||
|
|
||||
|
#include <cstdint> |
||||
|
|
||||
|
void binary_reverse(uint32_t &range); |
||||
|
int binary_num(uint32_t binary, int length); |
||||
|
void binary_to_str(uint64_t binary, char *string); |
||||
|
|
||||
|
#endif |
Binary file not shown.
@ -0,0 +1,55 @@ |
|||||
|
#include "common.h" |
||||
|
#include "klotski.h" |
||||
|
|
||||
|
uint64_t compact_code(uint64_t code) { |
||||
|
int block_num = 0; |
||||
|
uint64_t ret = 0; |
||||
|
uint32_t range = 0; |
||||
|
for (int addr = 0; code; ++addr, code >>= 3) { |
||||
|
switch (code & 0x7) { |
||||
|
case B_space: |
||||
|
range <<= 2; |
||||
|
break; |
||||
|
case B_1x2: |
||||
|
(range <<= 2) |= 0x1; |
||||
|
break; |
||||
|
case B_2x1: |
||||
|
(range <<= 2) |= 0x2; |
||||
|
break; |
||||
|
case B_1x1: |
||||
|
(range <<= 2) |= 0x3; |
||||
|
break; |
||||
|
case B_2x2: |
||||
|
ret |= uint64_t(addr) << 32; |
||||
|
default: |
||||
|
continue; |
||||
|
} |
||||
|
++block_num; |
||||
|
} |
||||
|
return ret | range << (16 - block_num) * 2; |
||||
|
} |
||||
|
|
||||
|
uint64_t extract_code(uint64_t code) { |
||||
|
uint64_t ret = C_2x2 << (code >> 32) * 3; |
||||
|
auto range = uint32_t(code); |
||||
|
binary_reverse(range); |
||||
|
for (int addr = 0; range; range >>= 2) { |
||||
|
while (0x7 & ret >> addr) { |
||||
|
addr += 3; |
||||
|
} |
||||
|
switch (range & 0x3) { |
||||
|
case 0x1: |
||||
|
ret |= C_1x2 << addr; |
||||
|
break; |
||||
|
case 0x2: |
||||
|
ret |= C_2x1 << addr; |
||||
|
break; |
||||
|
case 0x3: |
||||
|
ret |= C_1x1 << addr; |
||||
|
break; |
||||
|
case 0x0: |
||||
|
addr += 3; |
||||
|
} |
||||
|
} |
||||
|
return ret; |
||||
|
} |
@ -0,0 +1,73 @@ |
|||||
|
#ifndef _KLOTSKI_H_ |
||||
|
#define _KLOTSKI_H_ |
||||
|
|
||||
|
#include <cstdint> |
||||
|
|
||||
|
#define B_space 0x0 |
||||
|
#define B_fill 0x7 |
||||
|
#define B_1x2 0x1 |
||||
|
#define B_2x1 0x2 |
||||
|
#define B_1x1 0x3 |
||||
|
#define B_2x2 0x4 |
||||
|
|
||||
|
#define C_1x1 int64_t(0x3) |
||||
|
#define C_1x2 int64_t(0x39) |
||||
|
#define C_2x1 int64_t(0x7002) |
||||
|
#define C_2x2 int64_t(0x3F03C) |
||||
|
|
||||
|
#define F_1x1 int64_t(0x7) |
||||
|
#define F_1x2 int64_t(0x3F) |
||||
|
#define F_2x1 int64_t(0x7007) |
||||
|
#define F_2x2 int64_t(0x3F03F) |
||||
|
|
||||
|
uint64_t compact_code(uint64_t code); |
||||
|
uint64_t extract_code(uint64_t code); |
||||
|
|
||||
|
#endif |
||||
|
|
||||
|
/*
|
||||
|
|
||||
|
uint64_t -> 0000 + [xxx] * 20 |
||||
|
|
||||
|
2x2 2x1 1x2 1x1 |
||||
|
# # # # # # |
||||
|
# # # |
||||
|
|
||||
|
00 01 02 03 |
||||
|
04 05 06 07 |
||||
|
08 09 10 11 |
||||
|
12 13 14 15 |
||||
|
16 17 18 19 |
||||
|
|
||||
|
x1 (%4) => 0 1 2 3 |
||||
|
x3 (%4) => 0 3 2 1 |
||||
|
|
||||
|
*/ |
||||
|
|
||||
|
/*
|
||||
|
====================================================== |
||||
|
|
||||
|
1x1 -> 011 000 000 000 -> 0000 0000 0011 -> 0x3 |
||||
|
|
||||
|
1x2 -> 001 111 000 000 -> 0000 0011 1001 -> 0x39 |
||||
|
|
||||
|
2x1 -> 010 000 000 000 -> 0000 0000 0010 -> 0x7002 |
||||
|
111 000 000 000 -> 0000 0000 0111 |
||||
|
|
||||
|
2x2 -> 100 111 000 000 -> 0000 0011 1100 -> 0x3F03C |
||||
|
111 111 000 000 -> 0000 0011 1111 |
||||
|
|
||||
|
====================================================== |
||||
|
|
||||
|
1x1 -> 111 000 000 000 -> 0000 0000 0111 -> 0x7 |
||||
|
|
||||
|
1x2 -> 111 111 000 000 -> 0000 0011 1111 -> 0x3F |
||||
|
|
||||
|
2x1 -> 111 000 000 000 -> 0000 0000 0111 -> 0x7007 |
||||
|
111 000 000 000 -> 0000 0000 0111 |
||||
|
|
||||
|
2x2 -> 111 111 000 000 -> 0000 0011 1111 -> 0x3F03F |
||||
|
111 111 000 000 -> 0000 0011 1111 |
||||
|
|
||||
|
====================================================== |
||||
|
*/ |
@ -0,0 +1,84 @@ |
|||||
|
#include "case.h" |
||||
|
#include "klotski.h" |
||||
|
#include <cstdio> |
||||
|
#include <cstdint> |
||||
|
#include <vector> |
||||
|
|
||||
|
void graph_output(uint64_t code) { |
||||
|
for (int i = 0; i < 20; ++i) { |
||||
|
switch (code & 0x7) { |
||||
|
case B_1x1: |
||||
|
printf("# "); |
||||
|
break; |
||||
|
case B_1x2: |
||||
|
printf("& "); |
||||
|
break; |
||||
|
case B_2x1: |
||||
|
printf("$ "); |
||||
|
break; |
||||
|
case B_2x2: |
||||
|
printf("@ "); |
||||
|
break; |
||||
|
case B_fill: |
||||
|
printf("* "); |
||||
|
break; |
||||
|
case B_space: |
||||
|
printf(". "); |
||||
|
break; |
||||
|
default: |
||||
|
printf("? "); |
||||
|
} |
||||
|
if ((i & 0x3) == 0x3) { |
||||
|
printf("\n"); |
||||
|
} |
||||
|
code >>= 3; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
int main() { |
||||
|
printf("Klotski engine\n"); |
||||
|
|
||||
|
// printf("%lx\n", compact_code(0x0E58FC85FFEBC4DB));
|
||||
|
// printf("%lx\n", compact_code(0x0603EDF5CAFFF5E2));
|
||||
|
|
||||
|
// graph_output(extract_code(0x4FEA13400));
|
||||
|
// printf("\n");
|
||||
|
// graph_output(extract_code(0x1A9BF0C00));
|
||||
|
// printf("\n");
|
||||
|
|
||||
|
std::vector<uint64_t> all_case; |
||||
|
find_all_case(&all_case); |
||||
|
printf("count -> %lu\n", all_case.size()); |
||||
|
|
||||
|
for (auto code : all_case) { |
||||
|
if (code != compact_code(extract_code(code))) { |
||||
|
printf("error -> %lx\n", code); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
return 0; |
||||
|
|
||||
|
// 0x4FEA13400
|
||||
|
// # # # @ | 011 011 011 010 => 0100 1101 1011 -> 4DB
|
||||
|
// * * & @ | 100 111 010 111 => 1110 1011 1100 -> EBC
|
||||
|
// * * & $ | 111 111 111 010 => 0101 1111 1111 -> 5FF
|
||||
|
// . + + $ | 000 001 111 111 => 1111 1100 1000 -> FC8
|
||||
|
// . # ~ ~ | 000 011 001 111 => 1110 0101 1000 -> E58
|
||||
|
// 0x0E58FC85FFEBC4DB
|
||||
|
|
||||
|
graph_output(0x0E58FC85FFEBC4DB); |
||||
|
printf("\n"); |
||||
|
|
||||
|
// 0x1A9BF0C00
|
||||
|
// @ * * @ | 010 100 111 010 => 0101 1110 0010 -> 5E2
|
||||
|
// @ * * @ | 111 111 111 111 => 1111 1111 1111 -> FFF
|
||||
|
// $ ~ ~ $ | 010 001 111 010 => 0101 1100 1010 -> 5CA
|
||||
|
// $ # # $ | 111 011 011 111 => 1110 1101 1111 -> EDF
|
||||
|
// # . . # | 011 000 000 011 => 0110 0000 0011 -> 603
|
||||
|
// 0x0603EDF5CAFFF5E2
|
||||
|
|
||||
|
graph_output(0x0603EDF5CAFFF5E2); |
||||
|
printf("\n"); |
||||
|
|
||||
|
return 0; |
||||
|
} |
@ -1,195 +0,0 @@ |
|||||
#include <cstdio> |
|
||||
#include <cstdint> |
|
||||
|
|
||||
#define B_space 0x0 |
|
||||
#define B_fill 0x7 |
|
||||
#define B_1x2 0x1 |
|
||||
#define B_2x1 0x2 |
|
||||
#define B_1x1 0x3 |
|
||||
#define B_2x2 0x4 |
|
||||
|
|
||||
#define C_1x1 int64_t(0x3) |
|
||||
#define C_1x2 int64_t(0x39) |
|
||||
#define C_2x1 int64_t(0x7002) |
|
||||
#define C_2x2 int64_t(0x3F03C) |
|
||||
|
|
||||
#define F_1x1 int64_t(0x7) |
|
||||
#define F_1x2 int64_t(0x3F) |
|
||||
#define F_2x1 int64_t(0x7007) |
|
||||
#define F_2x2 int64_t(0x3F03F) |
|
||||
|
|
||||
/*
|
|
||||
|
|
||||
uint64_t -> 0000 + [xxx] * 20 |
|
||||
|
|
||||
2x2 2x1 1x2 1x1 |
|
||||
# # # # # # |
|
||||
# # # |
|
||||
|
|
||||
00 01 02 03 |
|
||||
04 05 06 07 |
|
||||
08 09 10 11 |
|
||||
12 13 14 15 |
|
||||
16 17 18 19 |
|
||||
|
|
||||
x1 (%4) => 0 1 2 3 |
|
||||
x3 (%4) => 0 3 2 1 |
|
||||
|
|
||||
*/ |
|
||||
|
|
||||
/*
|
|
||||
====================================================== |
|
||||
|
|
||||
1x1 -> 011 000 000 000 -> 0000 0000 0011 -> 0x3 |
|
||||
|
|
||||
1x2 -> 001 111 000 000 -> 0000 0011 1001 -> 0x39 |
|
||||
|
|
||||
2x1 -> 010 000 000 000 -> 0000 0000 0010 -> 0x7002 |
|
||||
111 000 000 000 -> 0000 0000 0111 |
|
||||
|
|
||||
2x2 -> 100 111 000 000 -> 0000 0011 1100 -> 0x3F03C |
|
||||
111 111 000 000 -> 0000 0011 1111 |
|
||||
|
|
||||
====================================================== |
|
||||
|
|
||||
1x1 -> 111 000 000 000 -> 0000 0000 0111 -> 0x7 |
|
||||
|
|
||||
1x2 -> 111 111 000 000 -> 0000 0011 1111 -> 0x3F |
|
||||
|
|
||||
2x1 -> 111 000 000 000 -> 0000 0000 0111 -> 0x7007 |
|
||||
111 000 000 000 -> 0000 0000 0111 |
|
||||
|
|
||||
2x2 -> 111 111 000 000 -> 0000 0011 1111 -> 0x3F03F |
|
||||
111 111 000 000 -> 0000 0011 1111 |
|
||||
|
|
||||
====================================================== |
|
||||
*/ |
|
||||
|
|
||||
void graph_output(uint64_t code) { |
|
||||
for (int i = 0; i < 20; ++i) { |
|
||||
switch (code & 0x7) { |
|
||||
case B_1x1: |
|
||||
printf("# "); |
|
||||
break; |
|
||||
case B_1x2: |
|
||||
printf("& "); |
|
||||
break; |
|
||||
case B_2x1: |
|
||||
printf("$ "); |
|
||||
break; |
|
||||
case B_2x2: |
|
||||
printf("@ "); |
|
||||
break; |
|
||||
case B_fill: |
|
||||
printf("* "); |
|
||||
break; |
|
||||
case B_space: |
|
||||
printf(". "); |
|
||||
break; |
|
||||
default: |
|
||||
printf("? "); |
|
||||
} |
|
||||
if ((i & 0x3) == 0x3) { |
|
||||
printf("\n"); |
|
||||
} |
|
||||
code >>= 3; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
uint64_t compact_code(uint64_t code) { |
|
||||
int block_num = 0; |
|
||||
uint64_t ret = 0; |
|
||||
uint32_t range = 0; |
|
||||
for (int addr = 0; code; ++addr, code >>= 3) { |
|
||||
switch (code & 0x7) { |
|
||||
case B_space: |
|
||||
range <<= 2; |
|
||||
break; |
|
||||
case B_1x2: |
|
||||
(range <<= 2) |= 0x1; |
|
||||
break; |
|
||||
case B_2x1: |
|
||||
(range <<= 2) |= 0x2; |
|
||||
break; |
|
||||
case B_1x1: |
|
||||
(range <<= 2) |= 0x3; |
|
||||
break; |
|
||||
case B_2x2: |
|
||||
ret |= uint64_t(addr) << 32; |
|
||||
default: |
|
||||
continue; |
|
||||
} |
|
||||
++block_num; |
|
||||
} |
|
||||
return ret | range << (16 - block_num) * 2; |
|
||||
} |
|
||||
|
|
||||
inline void binary_reverse(uint32_t &range) { // reverse binary every 2 bits
|
|
||||
range = ((range << 16) & 0xFFFF0000) | ((range >> 16) & 0x0000FFFF); |
|
||||
range = ((range << 8) & 0xFF00FF00) | ((range >> 8) & 0x00FF00FF); |
|
||||
range = ((range << 4) & 0xF0F0F0F0) | ((range >> 4) & 0x0F0F0F0F); |
|
||||
range = ((range << 2) & 0xCCCCCCCC) | ((range >> 2) & 0x33333333); |
|
||||
} |
|
||||
|
|
||||
uint64_t extract_code(uint64_t code) { |
|
||||
uint64_t ret = C_2x2 << (code >> 32) * 3; |
|
||||
auto range = uint32_t(code); |
|
||||
binary_reverse(range); |
|
||||
for (int addr = 0; range; range >>= 2) { |
|
||||
while (0x7 & ret >> addr) { |
|
||||
addr += 3; |
|
||||
} |
|
||||
switch (range & 0x3) { |
|
||||
case 0x1: |
|
||||
ret |= C_1x2 << addr; |
|
||||
break; |
|
||||
case 0x2: |
|
||||
ret |= C_2x1 << addr; |
|
||||
break; |
|
||||
case 0x3: |
|
||||
ret |= C_1x1 << addr; |
|
||||
break; |
|
||||
case 0x0: |
|
||||
addr += 3; |
|
||||
} |
|
||||
} |
|
||||
return ret; |
|
||||
} |
|
||||
|
|
||||
int main() { |
|
||||
printf("Klotski engine\n"); |
|
||||
|
|
||||
// printf("%lx\n", compact_code(0x0E58FC85FFEBC4DB));
|
|
||||
// printf("%lx\n", compact_code(0x0603EDF5CAFFF5E2));
|
|
||||
|
|
||||
graph_output(extract_code(0x4FEA13400)); |
|
||||
printf("\n"); |
|
||||
graph_output(extract_code(0x1A9BF0C00)); |
|
||||
printf("\n"); |
|
||||
|
|
||||
return 0; |
|
||||
|
|
||||
// 0x4FEA13400
|
|
||||
// # # # @ | 011 011 011 010 => 0100 1101 1011 -> 4DB
|
|
||||
// * * & @ | 100 111 010 111 => 1110 1011 1100 -> EBC
|
|
||||
// * * & $ | 111 111 111 010 => 0101 1111 1111 -> 5FF
|
|
||||
// . + + $ | 000 001 111 111 => 1111 1100 1000 -> FC8
|
|
||||
// . # ~ ~ | 000 011 001 111 => 1110 0101 1000 -> E58
|
|
||||
// 0x0E58FC85FFEBC4DB
|
|
||||
|
|
||||
graph_output(0x0E58FC85FFEBC4DB); |
|
||||
printf("\n"); |
|
||||
|
|
||||
// 0x1A9BF0C00
|
|
||||
// @ * * @ | 010 100 111 010 => 0101 1110 0010 -> 5E2
|
|
||||
// @ * * @ | 111 111 111 111 => 1111 1111 1111 -> FFF
|
|
||||
// $ ~ ~ $ | 010 001 111 010 => 0101 1100 1010 -> 5CA
|
|
||||
// $ # # $ | 111 011 011 111 => 1110 1101 1111 -> EDF
|
|
||||
// # . . # | 011 000 000 011 => 0110 0000 0011 -> 603
|
|
||||
// 0x0603EDF5CAFFF5E2
|
|
||||
|
|
||||
graph_output(0x0603EDF5CAFFF5E2); |
|
||||
printf("\n"); |
|
||||
|
|
||||
return 0; |
|
||||
} |
|
Loading…
Reference in new issue