Example #1
0
        /// <summary>
        /// Sets the estimated cost, or h, for this square puzzle state.
        /// This heuristic uses a modified version of Nilsson's sequence score.
        /// If the "space" node is not in the correct position, then add 1.
        /// Check each node and if its neighbors are not correct, then score two per non-corect neighbor.
        /// Multiply this by 3.
        /// Add the manhatten distance for each node, except the "space" node to the total.
        /// </summary>
        /// <param name="goal">Access to the square puzzle state that is the goal for calculating the heuristic.</param>
        public void SetEstimatedCost(INode goal)
        {
            SquarePuzzle g = (SquarePuzzle)goal;

            int[] pos =
            {
                1, -1, 0, 0,                                    //x
                0,  0, 1, -1                                    //y
            };
            int[] plus = { 1, -1, 3, -3 };
            // Uses Nilsson's sequence score.
            for (int i = 0; i < Grid.Length; i++)
            {
                for (int j = 0; j < Grid[i].Length; j++)
                {
                    SquareNode node = Grid[i][j];
                    //Any nodes next to it that are in the "correct" spot get a +2
                    List <SquareNode> neighbors = Neighbors(node);
                    for (int k = 0; k < neighbors.Count; k++)
                    {
                        for (int z = 0; z < 4; z++)
                        {
                            //todo should only check 4x1 instead of 4x4.
                            if (neighbors[k].Position.X == node.Position.X + pos[z] &&
                                neighbors[k].Position.Y == node.Position.Y + pos[z + 4])
                            {
                                if (neighbors[k].Number != node.Number + plus[z])
                                {
                                    EstimatedCost += 2;
                                }
                            }
                        }
                    }
                }
            }
            //If the goal "space" node is not "space" then add 1.
            if (!Grid[Grid.Length - 1][Grid.Length - 1].IsSpace)
            {
                EstimatedCost += 1;
            }

            EstimatedCost *= 3;

            for (int i = 0; i < Grid.Length; i++)
            {
                for (int j = 0; j < Grid[i].Length; j++)
                {
                    SquareNode node     = Grid[i][j];
                    SquareNode goalNode = GetNodeByNumber(g, node.Number);
                    //If the node isn't where it should be then add its manhattan distance to its goal position.
                    if (!node.IsSpace &&
                        (goalNode.Position.X != node.Position.X ||
                         goalNode.Position.Y != node.Position.Y))
                    {
                        EstimatedCost += Math.Abs(node.Position.X - goalNode.Position.X) +
                                         Math.Abs(node.Position.Y - goalNode.Position.Y);
                    }
                }
            }
        }
Example #2
0
        /// <summary>
        /// Swaps the two nodes in the grid provided.
        /// Is used when generating children.
        /// Copy the parent and swap for the next move.
        /// </summary>
        private static void Swap(SquareNode[][] grid, Point p1, Point p2)
        {
            grid[p1.X][p1.Y].Position = p2;
            grid[p2.X][p2.Y].Position = p1;
            SquareNode temp = grid[p2.X][p2.Y];

            grid[p2.X][p2.Y] = grid[p1.X][p1.Y];
            grid[p1.X][p1.Y] = temp;
        }
Example #3
0
        /// <summary>
        /// Gets the space node of this square puzzle.
        /// </summary>
        /// <returns></returns>
        public SquareNode GetSpace()
        {
            SquareNode space = null;

            for (int i = 0; i < Grid.Length; i++)
            {
                for (int j = 0; j < Grid[i].Length; j++)
                {
                    if (Grid[i][j].IsSpace)
                    {
                        space = Grid[i][j];
                        goto found;                         // found it so break out of the two for loops
                    }
                }
            }
            throw new NoSpaceException(this);
found:
            return(space);
        }
Example #4
0
        /// <summary>
        /// Returns up to all four neighbors of the node that is passed.
        /// </summary>
        /// <param name="node">Node to get its neighbors.</param>
        /// <returns>Returns up to all four neighbors of the node that is passed.</returns>
        public List <SquareNode> Neighbors(SquareNode node)
        {
            int[] n = { 1, -1, 0, 0,                            //x
                        0,  0, 1, -1 };                         //y
            var   p         = node.Position;
            var   neighbors = new List <SquareNode>();

            for (int i = 0; i < 4; i++)
            {
                int x = p.X + n[i];
                int y = p.Y + n[i + 4];
                if (x >= 0 &&
                    x < Grid.Length &&
                    y >= 0 &&
                    y < Grid.Length)
                {
                    neighbors.Add(Grid[x][y]);
                }
            }
            return(neighbors);
        }