|  | @ -19,6 +19,11 @@ | 
			
		
	
		
		
			
				
					|  |  | #define TOP_LIMIT(ADDR)    (addr >= ADDR * 3) |  |  | #define TOP_LIMIT(ADDR)    (addr >= ADDR * 3) | 
			
		
	
		
		
			
				
					|  |  | #define BOTTOM_LIMIT(ADDR) (addr <= ADDR * 3) |  |  | #define BOTTOM_LIMIT(ADDR) (addr <= ADDR * 3) | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |  |  |  | #define CHECK_UP(MASK)    !(code >> MOVE_UP & MASK) | 
			
		
	
		
		
			
				
					|  |  |  |  |  | #define CHECK_DOWN(MASK)  !(code >> MOVE_DOWN & MASK) | 
			
		
	
		
		
			
				
					|  |  |  |  |  | #define CHECK_LEFT(MASK)  !(code >> MOVE_LEFT & MASK) | 
			
		
	
		
		
			
				
					|  |  |  |  |  | #define CHECK_RIGHT(MASK) !(code >> MOVE_RIGHT & MASK) | 
			
		
	
		
		
			
				
					|  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  | #define RELEASE(NEXT_CODE, FILTER) { \ |  |  | #define RELEASE(NEXT_CODE, FILTER) { \ | 
			
		
	
		
		
			
				
					|  |  |     cache_t next_case = { \ |  |  |     cache_t next_case = { \ | 
			
		
	
		
		
			
				
					|  |  |         .code = NEXT_CODE, \ |  |  |         .code = NEXT_CODE, \ | 
			
		
	
	
		
		
			
				
					|  | @ -54,16 +59,16 @@ void Core::move_1x1(uint64_t code, int addr) { // try to move target 1x1 block | 
			
		
	
		
		
			
				
					|  |  |     BFS_INIT |  |  |     BFS_INIT | 
			
		
	
		
		
			
				
					|  |  |     while (!BFS_STOP) { // bfs search process
 |  |  |     while (!BFS_STOP) { // bfs search process
 | 
			
		
	
		
		
			
				
					|  |  |         BFS_LOAD |  |  |         BFS_LOAD | 
			
		
	
		
		
			
				
					
					|  |  |         if (ALLOW_UP && TOP_LIMIT(4) && !(code >> MOVE_UP & F_1x1)) { |  |  |         if (ALLOW_UP && TOP_LIMIT(4) && CHECK_UP(F_1x1)) { | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					|  |  |             release_1x1(UP) // 1x1 block move up
 |  |  |             release_1x1(UP) // 1x1 block move up
 | 
			
		
	
		
		
			
				
					|  |  |         } |  |  |         } | 
			
		
	
		
		
			
				
					
					|  |  |         if (ALLOW_DOWN && BOTTOM_LIMIT(15) && !(code >> MOVE_DOWN & F_1x1)) { |  |  |         if (ALLOW_DOWN && BOTTOM_LIMIT(15) && CHECK_DOWN(F_1x1)) { | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					|  |  |             release_1x1(DOWN) // 1x1 block move down
 |  |  |             release_1x1(DOWN) // 1x1 block move down
 | 
			
		
	
		
		
			
				
					|  |  |         } |  |  |         } | 
			
		
	
		
		
			
				
					
					|  |  |         if (ALLOW_LEFT && NOT_COLUMN_0 && !(code >> MOVE_LEFT & F_1x1)) { |  |  |         if (ALLOW_LEFT && NOT_COLUMN_0 && CHECK_LEFT(F_1x1)) { | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					|  |  |             release_1x1(LEFT) // 1x1 block move left
 |  |  |             release_1x1(LEFT) // 1x1 block move left
 | 
			
		
	
		
		
			
				
					|  |  |         } |  |  |         } | 
			
		
	
		
		
			
				
					
					|  |  |         if (ALLOW_RIGHT && NOT_COLUMN_3 && !(code >> MOVE_RIGHT & F_1x1)) { |  |  |         if (ALLOW_RIGHT && NOT_COLUMN_3 && CHECK_RIGHT(F_1x1)) { | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					|  |  |             release_1x1(RIGHT) // 1x1 block move right
 |  |  |             release_1x1(RIGHT) // 1x1 block move right
 | 
			
		
	
		
		
			
				
					|  |  |         } |  |  |         } | 
			
		
	
		
		
			
				
					|  |  |     } |  |  |     } | 
			
		
	
	
		
		
			
				
					|  | @ -73,16 +78,16 @@ void Core::move_1x2(uint64_t code, int addr) { // try to move target 1x2 block | 
			
		
	
		
		
			
				
					|  |  |     BFS_INIT |  |  |     BFS_INIT | 
			
		
	
		
		
			
				
					|  |  |     while (!BFS_STOP) { // bfs search process
 |  |  |     while (!BFS_STOP) { // bfs search process
 | 
			
		
	
		
		
			
				
					|  |  |         BFS_LOAD |  |  |         BFS_LOAD | 
			
		
	
		
		
			
				
					
					|  |  |         if (ALLOW_UP && TOP_LIMIT(4) && !(code >> MOVE_UP & F_1x2)) { |  |  |         if (ALLOW_UP && TOP_LIMIT(4) && CHECK_UP(F_1x2)) { | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					|  |  |             release_1x2(UP) // 1x2 block move up
 |  |  |             release_1x2(UP) // 1x2 block move up
 | 
			
		
	
		
		
			
				
					|  |  |         } |  |  |         } | 
			
		
	
		
		
			
				
					
					|  |  |         if (ALLOW_DOWN && BOTTOM_LIMIT(14) && !(code >> MOVE_DOWN & F_1x2)) { |  |  |         if (ALLOW_DOWN && BOTTOM_LIMIT(14) && CHECK_DOWN(F_1x2)) { | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					|  |  |             release_1x2(DOWN) // 1x2 block move down
 |  |  |             release_1x2(DOWN) // 1x2 block move down
 | 
			
		
	
		
		
			
				
					|  |  |         } |  |  |         } | 
			
		
	
		
		
			
				
					
					|  |  |         if (ALLOW_LEFT && NOT_COLUMN_0 && !(code >> MOVE_LEFT & F_1x1)) { |  |  |         if (ALLOW_LEFT && NOT_COLUMN_0 && CHECK_LEFT(F_1x1)) { | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					|  |  |             release_1x2(LEFT) // 1x2 block move left
 |  |  |             release_1x2(LEFT) // 1x2 block move left
 | 
			
		
	
		
		
			
				
					|  |  |         } |  |  |         } | 
			
		
	
		
		
			
				
					
					|  |  |         if (ALLOW_RIGHT && NOT_COLUMN_2 && !(code >> MOVE_RIGHT & F_1x1_R)) { |  |  |         if (ALLOW_RIGHT && NOT_COLUMN_2 && CHECK_RIGHT(F_1x1_R)) { | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					|  |  |             release_1x2(RIGHT) // 1x2 block move right
 |  |  |             release_1x2(RIGHT) // 1x2 block move right
 | 
			
		
	
		
		
			
				
					|  |  |         } |  |  |         } | 
			
		
	
		
		
			
				
					|  |  |     } |  |  |     } | 
			
		
	
	
		
		
			
				
					|  | @ -92,16 +97,16 @@ void Core::move_2x1(uint64_t code, int addr) { // try to move target 2x1 block | 
			
		
	
		
		
			
				
					|  |  |     BFS_INIT |  |  |     BFS_INIT | 
			
		
	
		
		
			
				
					|  |  |     while (!BFS_STOP) { // bfs search process
 |  |  |     while (!BFS_STOP) { // bfs search process
 | 
			
		
	
		
		
			
				
					|  |  |         BFS_LOAD |  |  |         BFS_LOAD | 
			
		
	
		
		
			
				
					
					|  |  |         if (ALLOW_UP && TOP_LIMIT(4) && !(code >> MOVE_UP & F_1x1)) { |  |  |         if (ALLOW_UP && TOP_LIMIT(4) && CHECK_UP(F_1x1)) { | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					|  |  |             release_2x1(UP) // 2x1 block move up
 |  |  |             release_2x1(UP) // 2x1 block move up
 | 
			
		
	
		
		
			
				
					|  |  |         } |  |  |         } | 
			
		
	
		
		
			
				
					
					|  |  |         if (ALLOW_DOWN && BOTTOM_LIMIT(11) && !(code >> MOVE_DOWN & F_1x1_D)) { |  |  |         if (ALLOW_DOWN && BOTTOM_LIMIT(11) && CHECK_DOWN(F_1x1_D)) { | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					|  |  |             release_2x1(DOWN) // 2x1 block move down
 |  |  |             release_2x1(DOWN) // 2x1 block move down
 | 
			
		
	
		
		
			
				
					|  |  |         } |  |  |         } | 
			
		
	
		
		
			
				
					
					|  |  |         if (ALLOW_LEFT && NOT_COLUMN_0 && !(code >> MOVE_LEFT & F_2x1)) { |  |  |         if (ALLOW_LEFT && NOT_COLUMN_0 && CHECK_LEFT(F_2x1)) { | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					|  |  |             release_2x1(LEFT) // 2x1 block move left
 |  |  |             release_2x1(LEFT) // 2x1 block move left
 | 
			
		
	
		
		
			
				
					|  |  |         } |  |  |         } | 
			
		
	
		
		
			
				
					
					|  |  |         if (ALLOW_RIGHT && NOT_COLUMN_3 && !(code >> MOVE_RIGHT & F_2x1)) { |  |  |         if (ALLOW_RIGHT && NOT_COLUMN_3 && CHECK_RIGHT(F_2x1)) { | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					|  |  |             release_2x1(RIGHT) // 2x1 block move right
 |  |  |             release_2x1(RIGHT) // 2x1 block move right
 | 
			
		
	
		
		
			
				
					|  |  |         } |  |  |         } | 
			
		
	
		
		
			
				
					|  |  |     } |  |  |     } | 
			
		
	
	
		
		
			
				
					|  | @ -111,16 +116,16 @@ void Core::move_2x2(uint64_t code, int addr) { // try to move target 2x2 block | 
			
		
	
		
		
			
				
					|  |  |     BFS_INIT |  |  |     BFS_INIT | 
			
		
	
		
		
			
				
					|  |  |     while (!BFS_STOP) { // bfs search process
 |  |  |     while (!BFS_STOP) { // bfs search process
 | 
			
		
	
		
		
			
				
					|  |  |         BFS_LOAD |  |  |         BFS_LOAD | 
			
		
	
		
		
			
				
					
					|  |  |         if (ALLOW_UP && TOP_LIMIT(4) && !(code >> MOVE_UP & F_1x2)) { |  |  |         if (ALLOW_UP && TOP_LIMIT(4) && CHECK_UP(F_1x2)) { | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					|  |  |             release_2x2(UP) // 2x2 block move up
 |  |  |             release_2x2(UP) // 2x2 block move up
 | 
			
		
	
		
		
			
				
					|  |  |         } |  |  |         } | 
			
		
	
		
		
			
				
					
					|  |  |         if (ALLOW_DOWN && BOTTOM_LIMIT(10) && !(code >> MOVE_DOWN & F_1x2_D)) { |  |  |         if (ALLOW_DOWN && BOTTOM_LIMIT(10) && CHECK_DOWN(F_1x2_D)) { | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					|  |  |             release_2x2(DOWN) // 2x2 block move down
 |  |  |             release_2x2(DOWN) // 2x2 block move down
 | 
			
		
	
		
		
			
				
					|  |  |         } |  |  |         } | 
			
		
	
		
		
			
				
					
					|  |  |         if (ALLOW_LEFT && NOT_COLUMN_0 && !(code >> MOVE_LEFT & F_2x1)) { |  |  |         if (ALLOW_LEFT && NOT_COLUMN_0 && CHECK_LEFT(F_2x1)) { | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					|  |  |             release_2x2(LEFT) // 2x2 block move left
 |  |  |             release_2x2(LEFT) // 2x2 block move left
 | 
			
		
	
		
		
			
				
					|  |  |         } |  |  |         } | 
			
		
	
		
		
			
				
					
					|  |  |         if (ALLOW_RIGHT && NOT_COLUMN_2 && !(code >> MOVE_RIGHT & F_2x1_R)) { |  |  |         if (ALLOW_RIGHT && NOT_COLUMN_2 && CHECK_RIGHT(F_2x1_R)) { | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					|  |  |             release_2x2(RIGHT) // 2x2 block move right
 |  |  |             release_2x2(RIGHT) // 2x2 block move right
 | 
			
		
	
		
		
			
				
					|  |  |         } |  |  |         } | 
			
		
	
		
		
			
				
					|  |  |     } |  |  |     } | 
			
		
	
	
		
		
			
				
					|  | 
 |