/// <summary>
 /// Strong Constructor. Start with the dead map including all walls.
 /// </summary>
 /// <param name="goalMap"></param>
 /// <param name="wallMap"></param>
 public DeadMapState(SolverNode currentNode, Bitmap goalMap, Bitmap wallMap, DeadMapAnalysis deadMapAnalysis)
     : this(goalMap, wallMap, deadMapAnalysis)
 {
     this.crateMap = currentNode.CrateMap;
     this.moveMap = currentNode.MoveMap;
     this.dynamicNode = currentNode;
 }
Exemple #2
0
        private SolverNode Assemble(
            SolverNode parent,
            StagingSolverNode flat,
            ImmutableDictionary <int, StagingSolverNode> all,
            ImmutableDictionary <int, ImmutableArray <StagingSolverNode> > parents)
        {
            var n = new SolverNode(parent,
                                   new VectorInt2(flat.PlayerBeforeX, flat.PlayerBeforeY),
                                   new VectorInt2(flat.PushX, flat.PushY),
                                   flat.CrateMap,
                                   flat.MoveMap,
                                   flat.SolverNodeId
                                   );

            n.Status = (SolverNodeStatus)flat.Status;

            if (parents.TryGetValue(flat.SolverNodeId, out var kids))
            {
                foreach (var kid in kids)
                {
                    n.Add(Assemble(n, kid, all, parents));
                }
            }



            return(n);
        }
Exemple #3
0
            public SolverNode?FindMatch(SolverNode node)
            {
                var i = block.BinarySearch(node, SolverNode.ComparerInstanceFull);

                if (i < 0)
                {
                    return(null);
                }
                return(block[i]);
            }
        public void Add(SolverNode node)
        {
            try
            {
                locker.EnterWriteLock();
                inner.Add(node);

            }
            finally
            {
                locker.ExitWriteLock();
            }
        }
        public override SolverNode FindMatch(SolverNode node)
        {
            try
            {
                locker.EnterReadLock();
                return base.FindMatch(node);

            }
            finally
            {
                locker.ExitReadLock();
            }
        }
        public override void Add(SolverNode node)
        {
            try
            {
                locker.EnterWriteLock();
                base.AddInnerBuffer(node);

            }
            finally
            {
                locker.ExitWriteLock();
            }
        }
        private IEnumerable <SolverNode> Generate(int count, int width, int height)
        {
            Random r = new Random();

            for (var x = 0; x < count; x++)
            {
                var n = new SolverNode(null,
                                       new VectorInt2(), new VectorInt2(),
                                       new Bitmap(width, height), new Bitmap(width, height)
                                       );
                for (var y = 0; y < width * height / 4; y++)
                {
                    n.CrateMap[r.Next(0, width), r.Next(0, height)] = true;
                    n.MoveMap[r.Next(0, width), r.Next(0, height)]  = true;
                }

                yield return(n);
            }
        }
Exemple #8
0
        // Better memory usage, does not creat an array of all nodes
        public void WriteTree(BinaryWriter bw, SolverNode root)
        {
            var count = root.CountRecursive();

            WriteHeader(bw, root.MoveMap.Size, count);

            int cc = 0;

            foreach (var node in root.Recurse())
            {
                Write(bw, node);
                cc++;
            }

            if (cc != count)
            {
                throw new Exception($"Invalid Counts: Count: {count} vs {cc} vs {root.Recurse().Count()}");
            }
        }
        public void SingleNode()
        {
            var d = Puzzle.Builder.DefaultTestPuzzle();

            var n = new SolverNode(null, d.Player.Position, VectorInt2.Left, d.ToMap(d.Definition.AllCrates), d.ToMap(d.Definition.AllFloors));

            var mem    = new MemoryStream();
            var writer = new BinaryNodeSerializer();

            using (var sw = new BinaryWriter(mem, Encoding.Unicode, true))
            {
                writer.Write(sw, n);
            }


            mem.Seek(0, SeekOrigin.Begin);



            using (var sr = new BinaryReader(mem))
            {
                var temp = writer.Read(sr);

                Assert.Equal(n.SolverNodeId, temp.SolverNodeId);
                Assert.Equal(0, temp.ParentId);
                Assert.Equal(n.PlayerBefore.X, temp.PlayerBeforeX);
                Assert.Equal(n.PlayerBefore.Y, temp.PlayerBeforeY);
                Assert.Equal(n.Push.X, temp.PushX);
                Assert.Equal(n.Push.Y, temp.PushY);
                Assert.Equal(n.Status, (SolverNodeStatus)temp.Status);

                var c = n.CrateMap is BitmapByteSeq bs ? bs : new BitmapByteSeq(n.CrateMap);
                Assert.Equal(c.GetArray(), temp.Crate);

                var m = n.MoveMap is BitmapByteSeq ms ? ms : new BitmapByteSeq(n.MoveMap);
                Assert.Equal(m.GetArray(), temp.Move);
            }
        }
Exemple #10
0
        public void Write(BinaryWriter sw, SolverNode n)
        {
            sw.Write(n.SolverNodeId);
            sw.Write(n.Parent?.SolverNodeId ?? 0);
            sw.Write(n.PlayerBefore.X);
            sw.Write(n.PlayerBefore.Y);
            sw.Write(n.Push.X);
            sw.Write(n.Push.Y);
            sw.Write((byte)n.Status);
            sw.Write(n.GetHashCode());

            var c  = n.CrateMap is BitmapByteSeq bs ? bs : new BitmapByteSeq(n.CrateMap);
            var cc = c.GetArray();

            sw.Write(cc.Length);
            sw.Write(cc);

            var m  = n.MoveMap is BitmapByteSeq ms ? ms : new BitmapByteSeq(n.MoveMap);
            var mm = m.GetArray();

            sw.Write(mm.Length);
            sw.Write(mm);
        }
 int IndexOf(List<SolverNode> list, SolverNode node)
 {
     for (int cc=0; cc<list.Count; cc++)
     {
         if (object.ReferenceEquals(list[cc], node)) return cc;
     }
     return -1;
 }
 public NodeListVisualisationElement(NodeListVisualisation parent, SolverNode node)
 {
     this.node = node;
     this.owner = parent;
 }
        private void RecursiveSolve(SolverNode node, List<Matrix> solutions)
        {
            List<Cell> emptyCells = ListEmptyCells(node.MatrixState);

            if (node.MatrixState.HasSolution && !node.MatrixState.IsResolved)
            {
                foreach (Cell emptyCell in emptyCells)
                {
                    CalculatePossibilities(emptyCell, node.MatrixState);
                    if (emptyCell.Possibilities.Count == 1)
                    {
                        int foundedValue = emptyCell.Possibilities[0];
                        emptyCell.Value = foundedValue;
                        node.MatrixState.LoadValue(emptyCell.Coordinates, emptyCell.Value);
                        if (ValueAdded != null)
                            ValueAdded(this, new ValueChangedEventArgs(node.MatrixState));
                        RecursiveSolve(node, solutions);
                        if (solutions.Count == solutions.Capacity)
                            break;
                        if (!node.MatrixState.HasSolution)
                        {
                            node.Dispose();
                            node = null;
                            break;
                        }
                    }

                }
            }

            if (emptyCells.Count == 0 && !node.MatrixState.IsResolved)
            {
                node.MatrixState.IsResolved = true;
                if (!solutions.Contains(node.MatrixState, Matrix.Comparer) && solutions.Count < solutions.Capacity)
                    solutions.Add(node.MatrixState);


            }
            else
            {
                
                if (node != null && node.ChildNodes.Count == 0 && !node.MatrixState.IsResolved && node.MatrixState.HasSolution)
                {
                    
                    
                    List<Cell> orderedEmptyCells = (from emptyCell in emptyCells orderby emptyCell.Possibilities.Count select emptyCell).ToList();
                    if (orderedEmptyCells.Count > 0)
                    {
                        
                        Cell lessPossibilitiesCell = orderedEmptyCells[0];
                        if (lessPossibilitiesCell.Possibilities.Count > 0)
                        {
                            foreach (int possibility in lessPossibilitiesCell.Possibilities)
                            {
                                Matrix possibleState = new Matrix(node.MatrixState);
                                possibleState.LoadValue(lessPossibilitiesCell.Coordinates, possibility);

                                if (ValueAdded != null)
                                    ValueAdded(this, new ValueChangedEventArgs(possibleState));
                                node.ChildNodes.Add(new SolverNode(possibleState));

                            }
                            int noSolutionCount = 0;
                            foreach (SolverNode childNode in node.ChildNodes)
                            {
                                RecursiveSolve(childNode, solutions);

                                if (solutions.Count == solutions.Capacity)
                                    break;
                                if (!node.MatrixState.HasSolution)
                                {
                                    node.Dispose();
                                    node = null;
                                    break;
                                }
                                if (!childNode.MatrixState.HasSolution)
                                {
                                    noSolutionCount++;
                                }
                            }
                            if (node.ChildNodes.Count > 0 && node.ChildNodes.Count == noSolutionCount && !node.MatrixState.IsResolved)
                            {
                                node.MatrixState.HasSolution = false;
                                if (ValueRemoved != null)
                                    ValueRemoved(this, new ValueChangedEventArgs(node.MatrixState));
                 
                            }
                        }
                        else
                        {
                            node.MatrixState.HasSolution = false;
                            if (ValueRemoved != null)
                                ValueRemoved(this, new ValueChangedEventArgs(node.MatrixState));
                 
                        }
                    }
                    else
                    {
                        node.MatrixState.HasSolution = false;
                        if (ValueRemoved != null)
                            ValueRemoved(this, new ValueChangedEventArgs(node.MatrixState));
                    }
                }
            }

        }
        /// <summary>
        /// Get the logical postiion for a node
        /// </summary>
        /// <param name="node"></param>
        /// <returns></returns>
        public VectorInt GetLogicalPosition(SolverNode node)
        {
            int idx = IndexOf(nodes, node);
            if (idx < 0) return VectorInt.Null;

            return new VectorInt(idx % maxCellWidth, idx / maxCellWidth);
        }
 protected Pen GetPen(SolverNode node)
 {
     if (node != null)
     {
         if (node.IsStateEvaluated) return new Pen(Color.Blue);
         if (node.IsChildrenEvaluated) return new Pen(Color.Orange);
     }
     return new Pen(Color.Gray);
 }
Exemple #16
0
 public ReuseTreeSolverQueue(SolverNode root)
 {
     this.root = root;
 }
        /// <summary>
        /// Check if two node are a match
        /// </summary>
        /// <param name="lhs"></param>
        /// <param name="rhs"></param>
        /// <returns></returns>
        private bool ChainMatch(SolverNode lhs, SolverNode rhs)
        {
            if (lhs == null) return false;
            if (rhs == null) return false;

            // Question: Are the cratemaps equal enough? Or do we need the move map too?
            return (lhs.CrateMap == rhs.CrateMap && lhs.MoveMap == rhs.MoveMap && lhs.MoveMap != null);
        }
 /// <summary>
 /// Retrive a display element for the corrosponding domain node
 /// </summary>
 /// <param name="node"></param>
 /// <returns></returns>
 public RootPathElement this[SolverNode node]
 {
     get { return elements.Find(delegate(RootPathElement item) { return item.Node == node; }); }
 }
        /// <summary>
        /// Register a new node for stats
        /// </summary>
        /// <param name="node"></param>
        public void NewNode(SolverNode node)
        {
            if (node == null) return;

            if (node.IsForward)
            {
                if (BestNodesFwd.Count == 0 || node.Weighting > BestNodesFwd.Last.Value.Weighting)
                {
                    InsertSorted(BestNodesFwd, node);
                }
            }
            else
            {
                if (BestNodesRev.Count == 0 || node.Weighting > BestNodesRev.Last.Value.Weighting)
                {
                    InsertSorted(BestNodesRev, node);
                }
            }
        }
        private void InsertSorted(LinkedList<SolverNode>  list, SolverNode node)
        {
            lock(list)
            {
                if (list.Count == 0)
                {
                    list.AddFirst(node);
                    return;
                }

                LinkedListNode<SolverNode> current = list.First;
                while (current != null && current.Value.Weighting >= node.Weighting)
                {
                    current = current.Next;
                }

                if (current == null)
                {
                    if (list.Count < MaxBestNodes)
                    {
                        list.AddLast(node);
                        return;
                    }
                    return;
                }

                // Add
                list.AddBefore(current, node);

                // Check max length
                if (list.Count > MaxBestNodes)
                {
                    list.RemoveLast();
                }
            }
        }
 public RootPathElement(RootPathVisualisation owner, SolverNode node)
 {
     this.owner = owner;
     this.node = node;
 }
        public SolverNode FindMatch(SolverNode node)
        {
            try
            {
                locker.EnterReadLock();
                return inner.FindMatch(node);

            }
            finally
            {
                locker.ExitReadLock();
            }
        }
        protected Brush GetBrush(SolverNode node)
        {
            if (node != null)
            {
                switch (node.Status)
                {
                    case (SolverNodeStates.None):
                        // Try something else
                        if (node.Weighting != 0)
                        {
                            int green = (int)(node.Weighting * 50);
                            return new SolidBrush(Color.FromArgb(0, green % 255, 0));
                        }
                        return new SolidBrush(Color.Cornsilk);

                    case (SolverNodeStates.Duplicate): return new SolidBrush(Color.DarkGray);
                    case (SolverNodeStates.Solution): return new SolidBrush(Color.Cyan);
                    case (SolverNodeStates.SolutionPath): return new SolidBrush(Color.LightCyan);
                    case (SolverNodeStates.Dead): return new SolidBrush(Color.Black);
                    case (SolverNodeStates.DeadChildren): return new SolidBrush(Color.DarkRed);
                }
            }
            return new SolidBrush(Color.Purple);
        }
        /// <summary>
        /// Select a SPECIFIC node and display its details
        /// </summary>
        /// <param name="solverNode"></param>
        private void BindNode(SolverNode solverNode)
        {
            if (solverNode == null) return;

            SokobanMap build = BuildCurrentMap(solverNode);
            if (build != null)
            {
                BitmapViewer.Layer puzzleLayer = new BitmapViewer.Layer();
                puzzleLayer.Name = "Puzzle";
                puzzleLayer.Map = build;
                puzzleLayer.Order = 0;
                puzzleLayer.IsVisible = true;
                bitmapViewerNodeMaps.SetLayer(puzzleLayer).IsVisible = true;
            }

            if (solverNode.MoveMap != null)
            {
                SolverBitmap move = new SolverBitmap("MoveMap", solverNode.MoveMap);
                bitmapViewerNodeMaps.SetLayer(move, new SolidBrush(Color.FromArgb(120, Color.Green))).IsVisible = true;
            }

            if (solverNode.DeadMap != null)
            {
                bitmapViewerNodeMaps.SetLayer(solverNode.DeadMap, new SolidBrush(Color.FromArgb(120, Color.Black))).IsVisible = true;
            }

            // Build details
            SolverLabelList txt = solverNode.GetDisplayData();

            ReportXHTML reportCurrent = new ReportXHTML("Node Details");
            reportCurrent.SetCSSInline(FileManager.GetContent("$html\\style.css"));
            reportCurrent.Add(txt.ToHTML());
            if (build != null)
            {
                reportCurrent.Add(string.Format("<code><pre>{0}</pre></code>", build.ToString()));
            }
            webBrowserNodeCurrent.DocumentText = reportCurrent.ToString();

            bitmapViewerNodeMaps.Render();

            RootPathVisualisation localVis = new RootPathVisualisation(new SizeInt(16, 16), controller);
            localVis.RenderCanvas =
                new RectangleInt(0, 0, visualisationContainerLocalNodes.Width - 30,
                                 visualisationContainerLocalNodes.Height - 30);
            localVis.Init(solverNode);
            visualisationContainerLocalNodes.ClearImage();
            visualisationContainerLocalNodes.Visualisation = localVis;
            visualisationContainerLocalNodes.Render();
        }
        /// <summary>
        /// Check in the forward solver if a reverse node is found. Ie look for a cross-over, hence solution.
        /// </summary>
        /// <param name="reverseNode"></param>
        /// <returns></returns>
        public bool CheckChainForward(SolverNode reverseNode)
        {
            if (stats != null)
            {
                stats.NewNode(reverseNode);
            }

            if (strategy == null) return false;

            SolverNode match = strategy.CheckDuplicate(reverseNode);
            if (match != null)
            {
                debugReport.Append("Found a forward chain {0}<->{1}", match.NodeID, reverseNode.NodeID);
                match.Status = SolverNodeStates.SolutionChain;
                reverseNode.Status = SolverNodeStates.SolutionChain;
                state = States.CompleteSolution;

                // Set the link property
                reverseNode.ChainSolutionLink = match;
                match.ChainSolutionLink = reverseNode;
                return true;
            }
            return false;
        }
        private SokobanMap BuildCurrentMap(SolverNode node)
        {
            SokobanMap result = new SokobanMap();
            result.Init(node.CrateMap.Size);

            for (int cx = 0; cx < result.Size.Width; cx++)
                for (int cy = 0; cy < result.Size.Height; cy++)
                {
                    if (controller.StaticAnalysis.WallMap[cx, cy]) result[cx, cy] = CellStates.Wall;
                    if (controller.StaticAnalysis.FloorMap[cx, cy]) result[cx, cy] = CellStates.Floor;
                    if (controller.StaticAnalysis.GoalMap[cx, cy])
                        result.SetState(new VectorInt(cx, cy), Cell.Goal);
                    if (node.CrateMap[cx, cy]) result.SetState(new VectorInt(cx, cy), Cell.Crate);
                    result.SetState(node.PlayerPosition, Cell.Player);
                }

            return result;
        }
Exemple #27
0
 public SolverTree(Matrix mainMatrix)
 {
     Root = new SolverNode(mainMatrix);
 }
        /// <summary>
        /// Initialise the elements
        /// </summary>
        /// <param name="current"></param>
        public void Init(SolverNode current)
        {
            elements = new List<RootPathElement>();
            bands = new List<List<RootPathElement>>();

            int maxDepth = 0;
            int currentDepth = 10;
            List<RootPathElement> currentBand;

            for (int cc = 0; cc < currentDepth + 2; cc++)
            {
                bands.Add(new List<RootPathElement>());
            }

            while (currentDepth >= maxDepth && current != null)
            {
                // Add
                RootPathElement newElement = new RootPathElement(this, current);
                newElement.OnPath = true;
                elements.Add(newElement);
                bands[currentDepth].Add(newElement);

                // Add all children
                if (current.TreeNode.HasChildren)
                {
                    foreach (SolverNode child in current.TreeNode.ChildrenData)
                    {
                        if (!Exists(child))
                        {
                            RootPathElement childElement = new RootPathElement(this, child);
                            elements.Add(childElement);
                            bands[currentDepth + 1].Add(childElement);
                        }
                    }
                }
                if (current.TreeNode.Parent != null)
                {
                    current = current.TreeNode.Parent.Data;
                }
                else
                {
                    current = null;
                }
                currentDepth--;
            }

            foreach (List<RootPathElement> band in bands)
            {
                // Insert path back in the middle
                RootPathElement path = band.Find(delegate(RootPathElement element) { return element.OnPath; });
                if (path != null)
                {
                    band.Remove(path);
                    band.Insert(band.Count/2, path);
                }
            }
        }
        protected Brush GetBrush(SolverNode node)
        {
            if (node != null)
            {
                switch (node.Status)
                {
                    case (SolverNodeStates.None):

                        float weighting = node.Weighting;
                        if (weighting < 0)
                        {
                            return new SolidBrush(Color.DarkGray);
                        }
                        if (weighting == 0)
                        {
                            new SolidBrush(Color.Cornsilk);
                        }
                        if (owner.controller.Stats.WeightingMax.ValueTotal > 0)
                        {
                            int min = 50;
                            int max = 250;
                            int value = Convert.ToInt32(weighting / owner.controller.Stats.WeightingMax.ValueTotal * (float)max);
                            return new SolidBrush(Color.FromArgb(50, value, 50));
                        }
                        return new SolidBrush(Color.Cornsilk);

                    case (SolverNodeStates.Duplicate): return new SolidBrush(Color.Brown);
                    case (SolverNodeStates.Solution): return new SolidBrush(Color.Red);
                    case (SolverNodeStates.SolutionPath): return new SolidBrush(Color.Red);
                    case (SolverNodeStates.Dead): return new SolidBrush(Color.Pink);
                    case (SolverNodeStates.DeadChildren): return new SolidBrush(Color.Pink);
                }
            }
            return new SolidBrush(Color.Purple);
        }
 private bool Exists(SolverNode current)
 {
     return this[current] != null;
 }
        public SolverNode Init(Puzzle puzzle, ISolverQueue queue)
        {
            var solution = puzzle.ToMap(puzzle.Definition.AllGoals);  // START with a solution
            var walls = puzzle.ToMap(puzzle.Definition.Wall);
            // The is only one start, but MANY end soutions. Hence a single root is not a valid representation
            // We use a placeholder node (not an actualy move to hold solutions)
            var root = new SingleThreadedReverseSolver.SyntheticReverseNode()
            {
                CrateMap = puzzle.ToMap(puzzle.Definition.AllGoals),
                MoveMap = new Bitmap(puzzle.Width, puzzle.Height)
            };

            foreach (var crateBefore in solution.TruePositions())
            {
                foreach (var dir in VectorInt2.Directions)
                {
                    // ss
                    var posPlayer = crateBefore + dir;
                    var posPlayerAfter = posPlayer + dir;
                    var crateAfter = crateBefore + dir;

                    // Remember: In reverse mode goals are crates, and crate may be floor
                    if ((puzzle[posPlayer] == puzzle.Definition.Floor
                        || puzzle[posPlayer] == puzzle.Definition.Player
                        || puzzle[posPlayer] == puzzle.Definition.Crate
                        )
                        &&
                        (puzzle[posPlayerAfter] == puzzle.Definition.Floor
                        || puzzle[posPlayerAfter] == puzzle.Definition.Player
                        || puzzle[posPlayer] == puzzle.Definition.Crate
                        )
                        )
                    {

                            var crate = new Bitmap(solution);
                            crate[crateBefore] = false;
                            crate[crateAfter] = true;

                            var node = new SolverNode()
                            {
                                CrateBefore = crateBefore,
                                CrateAfter = crateAfter,

                                PlayerBefore = posPlayer,
                                PlayerAfter = posPlayerAfter,

                                CrateMap = crate,
                                MoveMap = FloodFill.Fill(walls.BitwiseOR(crate), posPlayerAfter)
                            };

                            if (node.MoveMap.Count > 0)
                            {
                                root.Add(node);
                                queue.Enqueue(node);
                            }

                    }
                }
            }
            return root;
        }
 string BestNodeToString(SolverNode node)
 {
     if (node.IsChildrenEvaluated)
     {
         return string.Format("<a href=\"app://node/{0}\"><b>{1:0.00}</b></a>", node.NodeID, node.Weighting);
     }
     return string.Format("<a href=\"app://node/{0}\">{1:0.00}</a>", node.NodeID, node.Weighting);
 }
        private bool CheckValidSolutions(SolverCommandResult state, SolverNode posibleSolution)
        {
            var b = state.StaticMaps.WallMap.BitwiseOR(state.StaticMaps.CrateStart);
            var f = state.Command.Puzzle.Player.Position;

            var path = posibleSolution.PathToRoot();
            path.Reverse();
            var start = path[0];
            var t = start.PlayerAfter;
            var first = PathFinder.Find(b, f, t);
            return first != null;
        }
        public bool Evaluate(SolverCommandResult state, ISolverQueue queue, ISolverNodeLookup myPool, ISolverNodeLookup solutionPool, SolverNode node)
        {
            if (node.HasChildren) throw new InvalidOperationException();

            node.Status = SolverNodeStatus.Evaluting;

            var solution = false;
            var toEnqueue = new List<SolverNode>();

            foreach (var move in node.MoveMap.TruePositions())
            {
                foreach (var dir in VectorInt2.Directions)
                {
                    var p = move;
                    var pc = p + dir;
                    var pp = p - dir;
                    if (node.CrateMap[pc]) // crate to push
                    {
                        if (state.StaticMaps.FloorMap[pp] && !node.CrateMap[p])
                        {
                            if (!CheckDeadReverse(state, pp))
                            {
                                var newKid = new SolverNode
                                {
                                    PlayerBefore = p,
                                    PlayerAfter = pp,

                                    CrateBefore = pc,
                                    CrateAfter = p,

                                    CrateMap = new Bitmap(node.CrateMap),
                                    Evaluator = this,
                                };
                                newKid.CrateMap[pc] = false;
                                newKid.CrateMap[p] = true;

                                var boundry = state.StaticMaps.WallMap.BitwiseOR(newKid.CrateMap);
                                newKid.MoveMap = FloodFill.Fill(boundry, pp);

                                newKid.Goals = newKid.CrateMap.BitwiseAND(state.StaticMaps.GoalMap).Count();

                                // Optimisation: PreCalc hash
                                newKid.EnsureHash();

                                // Cycle Check: Does this node exist already?
                                var dup = myPool.FindMatch(newKid);
                                if (dup != null)
                                {
                                    // NOTE: newKid is NOT added as a ChildNode (which means less memory usage)

                                    // Duplicate
                                    newKid.Status = SolverNodeStatus.Duplicate;
                                    state.Statistics.Duplicates++;

                                    if (IsDebugMode)
                                    {
                                        node.AddDuplicate(dup);
                                    }
                                }
                                else
                                {

                                    SolverNode match = null;
                                    if (solutionPool != null) match = solutionPool.FindMatch(newKid);

                                    if (match != null)
                                    {
                                        // Add to tree / itterator
                                        node.Add(newKid);

                                        // Solution
                                        if (state.SolutionsWithReverse == null) state.SolutionsWithReverse = new List<SolutionChain>();
                                        var pair = new SolutionChain()
                                        {
                                            ForwardNode = match,
                                            ReverseNode = newKid,
                                            FoundUsing = this
                                        };
                                        state.SolutionsWithReverse.Add(pair);
                                        solution = true;
                                        state.Command.Debug.Raise(this, SolverDebug.Solution, pair);

                                        foreach (var n in newKid.PathToRoot().Union(match.PathToRoot()))
                                        {
                                            n.Status = SolverNodeStatus.SolutionPath;
                                        }
                                        newKid.Status = SolverNodeStatus.Solution;
                                        match.Status = SolverNodeStatus.Solution;
                                        if (state.Command.ExitConditions.StopOnSolution)
                                        {
                                            return true;
                                        }
                                    }
                                    else
                                    {
                                        // Add to tree / itterator
                                        node.Add(newKid);

                                        if (DeadMapAnalysis.DynamicCheck(state.StaticMaps, node))
                                        {
                                            newKid.Status = SolverNodeStatus.Dead;
                                        }
                                        else
                                        {
                                            toEnqueue.Add(newKid);
                                            if (newKid.CrateMap.BitwiseAND(state.StaticMaps.CrateStart).Equals(newKid.CrateMap))
                                            {
                                                // Possible Solution: Did we start in a valid position
                                                if (CheckValidSolutions(state, newKid))
                                                {
                                                    state.Solutions.Add(newKid);
                                                    state.Command.Debug.Raise(this, SolverDebug.Solution, newKid);
                                                    solution = true;

                                                    foreach (var n in newKid.PathToRoot())
                                                    {
                                                        n.Status = SolverNodeStatus.SolutionPath;
                                                    }
                                                    newKid.Status = SolverNodeStatus.Solution;
                                                }
                                                else
                                                {
                                                    newKid.Status = SolverNodeStatus.InvalidSolution;
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }

            node.Status = node.HasChildren ? SolverNodeStatus.Evaluted : SolverNodeStatus.Dead;
            if (node.Status == SolverNodeStatus.Dead  && node.Parent != null)
            {
                var p = (SolverNode)node.Parent;
                p.CheckDead();
            }

            queue.Enqueue(toEnqueue);
            myPool.Add(toEnqueue);

            return solution;
        }
Exemple #35
0
        public void Enqueue(SolverNode node)
        {
            Statistics.TotalNodes++;

            inner.Enqueue(node);
        }