Advertisement
Guest User

State.java

a guest
May 15th, 2021
64
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 10.08 KB | None | 0 0
  1. //  Sokoban state space explorer.
  2. //  Discussion: https://dxdy.ru/topic144781.html
  3.  
  4. import java.util.*;
  5.  
  6. public class State implements Comparable <State> {
  7.    
  8.     private static int activeCellsNumber, arraySize;
  9.     private static short [] netrepValues;
  10.     private static int   [] netrepIndices, lastEqual1, lastEqual2;
  11.     private static SortedSet <int []> flagsCollection;
  12.     private static List <State> stateList;
  13.    
  14.     private short porterCell, move, moveCount, pushCount;
  15.     private int [] cellFlags;
  16.     private State previousState;
  17.    
  18.     public static void init (CellsAdjacency cellsAdjacency) {
  19.        
  20.         activeCellsNumber = cellsAdjacency .getActiveCellsNumber ();
  21.         arraySize = (activeCellsNumber >> 5) + (0 == (activeCellsNumber & 31) ? 0 : 1);
  22.         netrepValues  = cellsAdjacency .getValues ();
  23.         netrepIndices = cellsAdjacency .getIndices ();
  24.         lastEqual1 = null;
  25.         lastEqual2 = null;
  26.         flagsCollection = new TreeSet   <> (new ArrayComparator ());
  27.         stateList       = new ArrayList <> ();
  28.     }
  29.    
  30.     public State (short porterCell, short [] stateCells) {
  31.         int k, cell;
  32.        
  33.         this .porterCell = porterCell;
  34.         move = -1;
  35.         moveCount = 0;
  36.         pushCount = 0;
  37.         cellFlags = new int [arraySize];
  38.        
  39.         for (k = 0; stateCells .length > k; ++k) {
  40.             cell = stateCells [k];
  41.             cellFlags [cell >> 5] |= 1 << (cell & 31);
  42.         }
  43.         if (flagsCollection .isEmpty ()) {
  44.             flagsCollection .add (cellFlags);
  45.         } else {
  46.             cellFlags = checkMasksCollection (cellFlags);
  47.         }
  48.         previousState = null;
  49.     }
  50.    
  51.     public State previousState () {
  52.         return previousState;
  53.     }
  54.    
  55.     public short move () {
  56.         return move;
  57.     }
  58.    
  59.     public boolean isSamePlacementAs (State state) {
  60.         return cellFlags == state .cellFlags;
  61.     }
  62.    
  63.     public static int placementCount () {
  64.         return flagsCollection .size ();
  65.     }
  66.    
  67.     public short moveCount () {
  68.         return moveCount;
  69.     }
  70.    
  71.     public short pushCount () {
  72.         return pushCount;
  73.     }
  74.    
  75.     public short [] stateCells () {
  76.         int k, value, mask;
  77.         short cell;
  78.         ArrayList <Short> cellsList = new ArrayList <> ();
  79.         short [] result;
  80.        
  81.         cell = 0;
  82.         for (k = 0; arraySize > k; ++k) {
  83.             value = cellFlags [k];
  84.             for (mask = 1; 0 != mask; mask <<= 1, ++cell) {
  85.                 if (0 != (value & mask)) {
  86.                     cellsList .add (cell);
  87.                 }
  88.             }
  89.         }
  90.         cellsList .add (porterCell);
  91.        
  92.         value = cellsList .size ();
  93.         result = new short [value];
  94.        
  95.         for (k = 0; value > k; ++k) {
  96.             result [k] = cellsList .get (k);
  97.         }
  98.        
  99.         return result;
  100.     }
  101.    
  102.     private State (short porterCell, short move, short moveCount, short pushCount, int [] cellFlags, State previousState) {
  103.         this .porterCell    = porterCell;
  104.         this .move          = move;
  105.         this .moveCount     = moveCount;
  106.         this .pushCount     = pushCount;
  107.         this .cellFlags     = cellFlags;
  108.         this .previousState = previousState;
  109.     }
  110.    
  111.     public State [] expandForth () {
  112.         int positionIndex, indexLimit;
  113.         int maskAdress_1, cllFlgMask_1, flagsValue_1;
  114.         int maskAdress_2, cllFlgMask_2, flagsValue_2;
  115.         short move, cell_1, cell_2;
  116.         int [] newCellFlags;
  117.        
  118.         stateList .clear ();
  119.         positionIndex = netrepIndices [porterCell];
  120.         indexLimit    = netrepIndices [porterCell + 1];
  121.        
  122.         while (indexLimit > positionIndex) {
  123.             move   = netrepValues [positionIndex];
  124.             ++positionIndex;
  125.             cell_1 = netrepValues [positionIndex];
  126.             if (activeCellsNumber <= cell_1) {
  127.                 positionIndex += 3;
  128.                 stateList .add (new State (
  129.                         cell_1, move,
  130.                         (short) (moveCount + 1), pushCount, cellFlags, this));
  131.                 continue;
  132.             }
  133.             maskAdress_1 = cell_1 >> 5;
  134.             cllFlgMask_1 = 1 << (cell_1 & 31);
  135.             flagsValue_1 = cellFlags [maskAdress_1];
  136.             if (0 == (flagsValue_1 & cllFlgMask_1)) {
  137.                 positionIndex += 3;
  138.                 stateList .add (new State (
  139.                         cell_1, move,
  140.                         (short) (moveCount + 1), pushCount, cellFlags, this));
  141.                 continue;
  142.             }
  143.             ++positionIndex;
  144.             cell_2 = netrepValues [positionIndex];
  145.             positionIndex += 2;
  146.             if (0 > cell_2) {
  147.                 continue;
  148.             }
  149.             maskAdress_2 = cell_2 >> 5;
  150.             cllFlgMask_2   = 1 << (cell_2 & 31);
  151.             if (maskAdress_1 == maskAdress_2) {
  152.                 if (0 != (flagsValue_1 & cllFlgMask_2)) {
  153.                     continue;
  154.                 }
  155.                 newCellFlags = Arrays .copyOf (cellFlags, arraySize);
  156.                 newCellFlags [maskAdress_1] = flagsValue_1 ^ cllFlgMask_1 ^ cllFlgMask_2;
  157.             } else {
  158.                 flagsValue_2 = cellFlags [maskAdress_2];
  159.                 if (0 != (flagsValue_2 & cllFlgMask_2)) {
  160.                     continue;
  161.                 }
  162.                 newCellFlags = Arrays .copyOf (cellFlags, arraySize);
  163.                 newCellFlags [maskAdress_1] = flagsValue_1 ^ cllFlgMask_1;
  164.                 newCellFlags [maskAdress_2] = flagsValue_2 ^ cllFlgMask_2;
  165.             }
  166.             stateList .add (new State (
  167.                     cell_1, move,
  168.                     (short) (moveCount + 1),
  169.                     (short) (pushCount + 1), checkMasksCollection (newCellFlags), this));
  170.         }
  171.        
  172.         return stateList .toArray (new State [stateList .size ()]);
  173.     }
  174.    
  175.     public State [] expandBack () {
  176.         int positionIndex, indexLimit;
  177.         int maskAdress_1, cllFlgMask_1, flagsValue_1;
  178.         int maskAdress_2, cllFlgMask_2, flagsValue_2;
  179.         int maskAdress_3, cllFlgMask_3;
  180.         short move, cell_1, cell_2;
  181.         int [] newCellFlags;
  182.        
  183.         stateList .clear ();
  184.         positionIndex = netrepIndices [porterCell];
  185.         indexLimit    = netrepIndices [porterCell + 1];
  186.        
  187.         while (indexLimit > positionIndex) {
  188.             move   = netrepValues [positionIndex];
  189.             ++positionIndex;
  190.             cell_1 = netrepValues [positionIndex];
  191.             maskAdress_1 = -1;
  192.             flagsValue_1 = 0;
  193.             if (activeCellsNumber > cell_1) {
  194.                 maskAdress_1 = cell_1 >> 5;
  195.                 cllFlgMask_1 = 1 << (cell_1 & 31);
  196.                 flagsValue_1 = cellFlags [maskAdress_1];
  197.                 if (0 != (flagsValue_1 & cllFlgMask_1)) {
  198.                     positionIndex += 3;
  199.                     continue;
  200.                 }
  201.             }
  202.             stateList .add (new State (
  203.                     cell_1, move,
  204.                     (short) (moveCount + 1), pushCount, cellFlags, this));
  205.             positionIndex += 2;
  206.             cell_2 = netrepValues [positionIndex];
  207.             ++positionIndex;
  208.             if (0 > cell_2) {
  209.                 continue;
  210.             }
  211.             maskAdress_2 = cell_2 >> 5;
  212.             cllFlgMask_2 = 1 << (cell_2 & 31);
  213.             if (maskAdress_1 == maskAdress_2) {
  214.                 flagsValue_2 = flagsValue_1;
  215.             } else {
  216.                 flagsValue_2 = cellFlags [maskAdress_2];
  217.             }
  218.             if (0 == (flagsValue_2 & cllFlgMask_2)) {
  219.                 continue;
  220.             }
  221.             newCellFlags = Arrays .copyOf (cellFlags, arraySize);
  222.             maskAdress_3 = porterCell >> 5;
  223.             cllFlgMask_3 = 1 << (porterCell & 31);
  224.             if (maskAdress_2 == maskAdress_3) {
  225.                 newCellFlags [maskAdress_2] = flagsValue_2 ^ cllFlgMask_2 ^ cllFlgMask_3;
  226.             } else {
  227.                 newCellFlags [maskAdress_2] = flagsValue_2 ^ cllFlgMask_2;
  228.                 newCellFlags [maskAdress_3] ^=               cllFlgMask_3;
  229.             }
  230.             stateList .add (new State (
  231.                     cell_1, (short) (-move - 1),
  232.                     (short) (moveCount + 1),
  233.                     (short) (pushCount + 1), checkMasksCollection (newCellFlags), this));
  234.         }
  235.        
  236.         return stateList .toArray (new State [stateList .size ()]);
  237.     }
  238.    
  239.     @Override
  240.     public int compareTo (State state) {
  241.         int k, value1, value2;
  242.        
  243.         if (cellFlags != state .cellFlags) {
  244.             for (k = 0; arraySize > k; ++k) {
  245.                 value1 =        cellFlags [k];
  246.                 value2 = state .cellFlags [k];
  247.                 if (value1 > value2) {
  248.                     return 1;
  249.                 }
  250.                 if (value1 < value2) {
  251.                     return -1;
  252.                 }
  253.             }
  254.         }
  255.         if (porterCell > state .porterCell) {
  256.             return 1;
  257.         }
  258.         if (porterCell < state .porterCell) {
  259.             return -1;
  260.         }
  261.         return 0;
  262.     }
  263.    
  264.     private static int [] checkMasksCollection (int [] newMask) {
  265.        
  266.         if (flagsCollection .contains (newMask)) {
  267.             if (newMask == lastEqual1) {
  268.                 return lastEqual2;
  269.             }
  270.             return lastEqual1;
  271.         }
  272.         flagsCollection .add (newMask);
  273.         return newMask;
  274.     }
  275.    
  276.     private static class ArrayComparator implements Comparator <int []> {
  277.  
  278.         @Override
  279.         public int compare (int [] array1, int [] array2) {
  280.             int k, value1, value2;
  281.            
  282.             for (k = 0; arraySize > k; ++k) {
  283.                 value1 = array1 [k];
  284.                 value2 = array2 [k];
  285.                 if (value1 > value2) {
  286.                     return 1;
  287.                 }
  288.                 if (value1 < value2) {
  289.                     return -1;
  290.                 }
  291.             }
  292.             lastEqual1 = array1;
  293.             lastEqual2 = array2;
  294.             return 0;
  295.         }
  296.     }
  297. }
  298.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement