static void CompressTree(GoalMacroNode node, Dictionary <int, GoalMacroNode> map, HashSet <Position> goals) { if (node.GetBoxPositions == null) { node.GetBoxPositions = new List <Position>(); } int hash = node.ComputeHashKey(); GoalMacroNode oldNode; if (map.TryGetValue(hash, out oldNode)) { node = oldNode; } else { map.Add(hash, node); foreach (GoalMacroEntry entry in node.Entries) { entry.ComputeEntrancePosition(); entry.ComputeGoalPosition(); goals.Add(entry.GetGoalPosition); entry.Next.GetBoxPositions = new List <Position>(node.GetBoxPositions); entry.Next.GetBoxPositions.Add(entry.GetGoalPosition); entry.Next.GetBoxPositions.Sort((x, y) => (x.X + 1000 * x.Y).CompareTo(y.X + 1000 * y.Y)); entry.GoalMacros = BuildMacroMove(entry.GetEntrancePosition, entry.GetGoalPosition, node.GetBoxPositions); CompressTree(entry.Next, map, goals); } } }
private GoalMacroNode GetInitialMacroNode(GoalMacroNode node, int hash) { if (node.Hashkey == hash) { return(node); } GoalMacroNode newNode = null; foreach (GoalMacroEntry entry in node.Entries) { newNode = GetInitialMacroNode(entry.Next, hash); if (newNode != null) { return(newNode); } } return(null); }
private void Init(SokobanGameState state, RewardType rewardType, bool useNormalizedPosition, bool useGoalMacro, bool useTunnelMacro, bool useGoalCut, ISPSimulationStrategy simulationStrategy, MersenneTwister rng = null) { this.useNormalizedPosition = useNormalizedPosition; this.state = (SokobanGameState)state; if (simulationStrategy == null) { simulationStrategy = new SokobanRandomStrategy(); } if (rng == null) { rng = new MersenneTwister(); } this.rng = rng; this.rewardType = rewardType; this.simulationStrategy = simulationStrategy; normalizedPlayerPosition = new Position(state.PlayerX, state.PlayerY); availableMoves = null; this.useGoalMacro = useGoalMacro; this.useTunnelMacro = useTunnelMacro; this.useGoalCut = useGoalCut; if (useGoalMacro) { goalMacroTree = GoalMacroWrapper.BuildMacroTree(this); if (goalMacroTree.Roots.Length > 0) { currentGoalMacroNode = GetInitialMacroNode(goalMacroTree.Roots[0], state.GetGoalMacroHash(goalMacroTree.GoalsInRoom)); if (currentGoalMacroNode == null) { this.useGoalMacro = false; } } else { this.useGoalMacro = false; } } }