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); } }
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; } }