mirror of https://github.com/dnomd343/klotski.git
				
				
			
				 1 changed files with 65 additions and 0 deletions
			
			
		@ -0,0 +1,65 @@ | 
				
			|||
#pragma once | 
				
			|||
 | 
				
			|||
/// Group is a concept in klotski. For any valid cases, moving all its blocks
 | 
				
			|||
/// any finite number of times can generate a limited number of layouts, they
 | 
				
			|||
/// are called a `group`. Of course, there are some special groups whose size
 | 
				
			|||
/// is only 1, that is, only itself. (all blocks can no longer be moved)
 | 
				
			|||
 | 
				
			|||
/// For a case, by definition, it must have a `2x2` block, at least two spaces,
 | 
				
			|||
/// and the others are filled by any number of `1x1`, `1x2` and `2x1`, so their
 | 
				
			|||
/// numbers satisfy the following inequality.
 | 
				
			|||
///
 | 
				
			|||
///   => n_1x1 + (n_1x2 + n_2x1) * 2 + n_2x2 * 4 < (20 - 2)
 | 
				
			|||
///   => n_1x1 + (n_1x2 + n_2x1) * 2 < 14
 | 
				
			|||
///
 | 
				
			|||
/// Through calculation, it can be known that these three independent variables
 | 
				
			|||
/// can get 204 permutations. However, on a 5x4 chessboard, it's never possible
 | 
				
			|||
/// to put seven 2x1 blocks, so there are actually 203 combinations, and they
 | 
				
			|||
/// are numbered from 0 to 202, called `type_id`.
 | 
				
			|||
 | 
				
			|||
/// According to the number of blocks in the layout, you can use the following
 | 
				
			|||
/// formula to get an intermediate value `flag`, and arrange the flags in 203
 | 
				
			|||
/// cases from small to large to get the `type_id` value. Similarly, `type_id`
 | 
				
			|||
/// can also be reversed to get the number of blocks, which are one by one
 | 
				
			|||
/// corresponding.
 | 
				
			|||
///
 | 
				
			|||
///     flag  =>  |       0xxx      |   0xxx  |   xxxx   |
 | 
				
			|||
///   (12-bit)    | (n_1x2 + n_2x1) | (n_2x1) |  (n_1x1) |
 | 
				
			|||
///               |     (0 ~ 7)     | (0 ~ 7) | (0 ~ 14) |
 | 
				
			|||
///
 | 
				
			|||
///     flag  =>  ((n_1x2 + n_2x1) << 8) | (n_2x1 << 4) | (n_1x1)
 | 
				
			|||
///
 | 
				
			|||
/// Using the table lookup method, the `type_id` of any case can be obtained
 | 
				
			|||
/// within O(1), which is encapsulated in `GroupType`.
 | 
				
			|||
 | 
				
			|||
/// Since the `type_id` cannot change when moving, all cases belonging to the
 | 
				
			|||
/// same `type_id` must be divided into different groups (of course there may
 | 
				
			|||
/// be only one). For a group, list the CommonCodes of all its cases, the
 | 
				
			|||
/// smallest of which is called the group's `seed`. List all the groups under
 | 
				
			|||
/// the same `type_id`, and arrange them from large to small, and arrange the
 | 
				
			|||
/// groups of the same size from small to large according to the `seed`, and
 | 
				
			|||
/// start numbering from 0 to get the `group_id`.
 | 
				
			|||
 | 
				
			|||
/// All cases of the same group will have the same `type_id` and `group_id`,
 | 
				
			|||
/// that is to say, for cases with the same two values, there must be a
 | 
				
			|||
/// reachable path for them, otherwise they will never be reachable. Arrange
 | 
				
			|||
/// the CommonCodes of all cases in the group from small to large, and start
 | 
				
			|||
/// numbering from 0 to get `case_id`, which will uniquely determine a legal
 | 
				
			|||
/// layout. Use the following method to express.
 | 
				
			|||
///
 | 
				
			|||
///     {type_id}-{group_id}-{case_id}
 | 
				
			|||
///
 | 
				
			|||
///       Eg1: 1A9BF0C00 -> `169-1-7472`
 | 
				
			|||
///       Eg2: 4FEA13400 -> `164-0-30833`
 | 
				
			|||
///
 | 
				
			|||
/// The range of `type_id` is [0, 203), the maximum `group_id` is 2652 (there
 | 
				
			|||
/// are 2653 groups when `type_id` is 164), the maximum `case_id` is 964655
 | 
				
			|||
/// (there are 964656 cases when `type_id` is 58 and `group_id` is 0).
 | 
				
			|||
/// Therefore, these three numbers meet the following range requirements.
 | 
				
			|||
///
 | 
				
			|||
///     type_id < 203  |  group_id < 2653  |   case_id < 964656
 | 
				
			|||
///     (8-bit ~ 256)  |  (12-bit ~ 4096)  |  (20-bit ~ 1048576)
 | 
				
			|||
///
 | 
				
			|||
/// Typically, these three variables are generally recorded in decimal and
 | 
				
			|||
/// displayed in the form of strings. They can facilitate the relationship
 | 
				
			|||
/// between multiple cases.
 | 
				
			|||
					Loading…
					
					
				
		Reference in new issue