Пример #1
0
        public void ProcessRecord(string boardName)
        {
            var doodadPlacements = this.content.Load<IEnumerable<DoodadPlacement>>(boardName);
            var sortedDoodadPlacements = doodadPlacements.OrderBy(placement => placement.Row).ThenBy(placement => placement.Column).ToList();
            List<MovementNode> solutions = new List<MovementNode>();
            MovementNode root = new MovementNode(null, false, false, StreamUtilities.Compress(sortedDoodadPlacements), MovementType.Start, 0, 0);
            Queue<MovementNode> nodeStack = new Queue<MovementNode>();
            Dictionary<string, bool> visitedNodes = new Dictionary<string, bool>();
            nodeStack.Enqueue(root);
            visitedNodes[root.State] = true;

            MovementNode bestSolution = null;

            while (nodeStack.Count > 0)
            {
                MovementNode currentNode = nodeStack.Dequeue();

                if (currentNode.IsWinningMove || currentNode.IsLosingMove)
                {
                    if (currentNode.IsWinningMove)
                    {
                        solutions.Add(currentNode);
                        if (bestSolution == null || bestSolution.Depth < currentNode.Depth)
                        {
                            bestSolution = currentNode;
                        }
                    }

                    continue;
                }

                if (bestSolution != null && currentNode.Depth >= bestSolution.Depth)
                {
                    continue;
                }

                this.RotateBoard(nodeStack, visitedNodes, currentNode, MovementType.Clockwise, MathHelper.PiOver2);
                this.RotateBoard(nodeStack, visitedNodes, currentNode, MovementType.CounterClockwise, -MathHelper.PiOver2);
            }

            solutions.Sort(new MovementNodeComparer());

            Console.WriteLine("{0} Solutions:", solutions.Count);
            foreach (MovementNode solution in solutions)
            {
                List<MovementType> movementTypes = new List<MovementType>();
                MovementNode ancestor = solution;
                while (ancestor != null)
                {
                    movementTypes.Add(ancestor.MovementType);
                    ancestor = ancestor.Parent;
                }

                movementTypes.Reverse();
                StringBuilder builder = new StringBuilder(string.Format("\t{0} moves: ", solution.Depth));
                builder.Append(string.Format("\t{0}", this.ToAbbreviation(movementTypes.Skip(1).FirstOrDefault())));
                var remainingMoves = movementTypes.Skip(2);
                foreach (MovementType movementType in remainingMoves)
                {
                    builder.Append(string.Format(", {0}", this.ToAbbreviation(movementType)));
                }

                Console.WriteLine(builder);
            }
        }
Пример #2
0
        private void RotateBoard(
            Queue<MovementNode> nodeStack,
            Dictionary<string, bool> visitedNodes, 
            MovementNode currentNode, 
            MovementType movementType, 
            float rotation)
        {
            var doodads = this.RestoreLevel(currentNode.State);
            this.boardPacker.Pack(doodads, currentNode.Rotation + rotation);
            foreach (IDoodad doodad in doodads)
            {
                doodad.Update(doodads);
            }

            var childNode = new MovementNode(
                currentNode,
                this.IsWinningBoard(doodads),
                this.IsLosingBoard(doodads),
                this.ToLevelDefinition(doodads),
                movementType,
                currentNode.Rotation + rotation,
                currentNode.Depth + 1);

            if (!visitedNodes.ContainsKey(childNode.State))
            {
                nodeStack.Enqueue(childNode);
                visitedNodes[childNode.State] = true;
            }
        }