示例#1
0
        public static List <Node> SolveSA(out Score score)
        {
            Stopwatch sw = Stopwatch.StartNew();

            Random random = new Random(DateTime.Now.Second);

            Int64 numberOfNodes    = -1;
            Int32 numberOfDiamonds = 0;

            List <Node> path = new List <Node>();

            List <Node> Goals = new List <Node>(goals);

            Node startingNode = nodeGrid[initialLocation.X, initialLocation.Y];

            while (Goals.Count > 0)
            {
                Node closestGoal = Goals[0];

                Int32 distanceToGoal = GetManhattanDistance(startingNode.Position, closestGoal.Position);

                for (int i = 1; i < Goals.Count; i++)
                {
                    Int32 distanceToClosestGoalCandidate = GetManhattanDistance(startingNode.Position, Goals[i].Position);
                    if (distanceToClosestGoalCandidate < distanceToGoal)
                    {
                        distanceToGoal = distanceToClosestGoalCandidate;
                        closestGoal    = Goals[i];
                    }
                }

                Stack <Node> stack   = new Stack <Node>();
                List <Node>  visited = new List <Node>();

                Node currentNode = startingNode;

                currentNode.SetHCost(closestGoal.Position);

                currentNode.Visited = true;
                visited.Add(currentNode);

                stack.Push(currentNode);

                Boolean GoalReached = false;

                while (stack.Count > 0)
                {
                    currentNode = stack.Peek();
                    path.Add(currentNode);

                    numberOfNodes = Math.Max(numberOfNodes, visited.Count);

                    if (currentNode == closestGoal)
                    {
                        GoalReached = true;
                        break;
                    }

                    if (Goals.Contains(currentNode))
                    {
                        numberOfDiamonds++;
                        Goals.Remove(currentNode);
                    }

                    List <Node> neighbours = GetNodeWalkableNeighbours(currentNode.Position, true);
                    if (neighbours.Count > 0)
                    {
                        while (true)
                        {
                            Node neighbour = neighbours.OrderBy(x => Guid.NewGuid()).FirstOrDefault();
                            neighbour.SetHCost(closestGoal.Position);
                            if (neighbour.hCost < currentNode.hCost || (neighbour.hCost > currentNode.hCost && Convert.ToDecimal(random.NextDouble()) < SATemperature))
                            {
                                neighbour.Visited = true;
                                stack.Push(neighbour);
                                path.Add(neighbour);
                                visited.Add(neighbour);
                                break;
                            }
                        }
                    }
                    else
                    {
                        currentNode = stack.Pop();
                    }
                }

                if (GoalReached)
                {
                    numberOfDiamonds++;
                    startingNode = closestGoal;
                    foreach (Node v in visited)
                    {
                        v.Visited = false;
                    }
                }

                Goals.Remove(closestGoal);
            }


            score = new Score("SA", numberOfNodes, numberOfDiamonds, numberOfDiamonds == goals.Count, sw.Elapsed);

            return(path);
        }
示例#2
0
        // Game Solver
        // Algorithms
        public static List <Node> SolveAStar(out Score score)
        {
            Stopwatch sw               = Stopwatch.StartNew();
            Int64     numberOfNodes    = -1;
            Int32     numberOfDiamonds = 0;

            List <Node> Goals = new List <Node>(goals), path = new List <Node>();
            Node        startingNode = nodeGrid[initialLocation.X, initialLocation.Y];

            while (Goals.Count > 0)
            {
                Node closestGoal = Goals[0];

                Int32 distanceToGoal = GetManhattanDistance(startingNode.Position, closestGoal.Position);

                for (int i = 1; i < Goals.Count; i++)
                {
                    Int32 distanceToClosestGoalCandidate = GetManhattanDistance(startingNode.Position, Goals[i].Position);
                    if (distanceToClosestGoalCandidate < distanceToGoal)
                    {
                        distanceToGoal = distanceToClosestGoalCandidate;
                        closestGoal    = Goals[i];
                    }
                }

                List <Node>    openSet   = new List <Node>();
                HashSet <Node> closedSet = new HashSet <Node>();

                openSet.Add(startingNode);
                Node currentNode;

                Boolean GoalReached = false;

                while (openSet.Count > 0)
                {
                    numberOfNodes = Math.Max(numberOfNodes, openSet.Count);

                    currentNode = openSet[0];

                    for (int i = 1; i < openSet.Count; i++)
                    {
                        if (openSet[i].fCost < currentNode.fCost || (openSet[i].fCost == currentNode.fCost && openSet[i].hCost < currentNode.hCost))
                        {
                            currentNode = openSet[i];
                        }
                    }

                    openSet.Remove(currentNode);
                    closedSet.Add(currentNode);

                    if (currentNode == closestGoal)
                    {
                        List <Node> pathToClosestGoal = new List <Node>();
                        GoalReached = true;
                        while (currentNode != startingNode)
                        {
                            pathToClosestGoal.Add(currentNode);
                            currentNode = currentNode.ParentNode;
                        }
                        pathToClosestGoal.Reverse();
                        path.AddRange(pathToClosestGoal);
                        break;
                    }

                    List <Node> neighbours = GetNodeWalkableNeighbours(currentNode.Position);

                    foreach (Node neighbour in neighbours)
                    {
                        if (closedSet.Contains(neighbour))
                        {
                            continue;
                        }

                        if (currentNode.gCost + 1 < neighbour.gCost || !openSet.Contains(neighbour))
                        {
                            neighbour.gCost      = currentNode.gCost + 1;
                            neighbour.ParentNode = currentNode;

                            if (!openSet.Contains(neighbour))
                            {
                                neighbour.SetHCost(closestGoal.Position);
                                openSet.Add(neighbour);
                            }
                        }
                    }
                }

                if (GoalReached)
                {
                    numberOfDiamonds++;
                    startingNode = closestGoal;
                    for (int i = 0; i < mapXSize; i++)
                    {
                        for (int j = 0; j < mapYSize; j++)
                        {
                            nodeGrid[i, j].SetGCost(startingNode.Position);
                        }
                    }
                }
                Goals.Remove(closestGoal);
            }

            sw.Stop();

            score = new Score("A*", numberOfNodes, numberOfDiamonds, numberOfDiamonds == goals.Count, sw.Elapsed);

            return(path);
        }
示例#3
0
        public static List <List <Node> > SolveIDDFS(out Score score)
        {
            Stopwatch sw                   = Stopwatch.StartNew();
            Int64     numberOfNodes        = -1;
            Int32     numberOfDiamonds     = 0;
            Boolean   collectedAllDiamonds = false;

            List <List <Node> > path = new List <List <Node> >();

            for (int currentDepth = 0; currentDepth < IDDFSMaxDepth && !collectedAllDiamonds; currentDepth++)
            {
                List <Node> Goals = goals;

                List <Node> currentDepthPath = new List <Node>();

                List <Node>  visited = new List <Node>();
                Stack <Node> stack   = new Stack <Node>();

                Node CurrentNode = nodeGrid[initialLocation.X, initialLocation.Y];

                CurrentNode.Visited = true;

                stack.Push(CurrentNode);
                visited.Add(CurrentNode);

                while (stack.Count > 0)
                {
                    CurrentNode = stack.Pop();
                    currentDepthPath.Add(CurrentNode);

                    if (Goals.Contains(CurrentNode))
                    {
                        Goals.Remove(CurrentNode);
                        numberOfDiamonds++;
                        if (Goals.Count == 0)
                        {
                            break;
                        }
                    }

                    List <Node> neighbours = GetNodeWalkableNeighbours(CurrentNode.Position, true);
                    foreach (Node neighbour in neighbours)
                    {
                        if (GetManhattanDistance(initialLocation, neighbour.Position) <= currentDepth)
                        {
                            neighbour.Visited = true;
                            stack.Push(neighbour);
                            currentDepthPath.Add(neighbour);
                            visited.Add(neighbour);
                        }
                    }
                }

                foreach (Node v in visited)
                {
                    v.Visited = false;
                }

                Node StartingNode = currentDepthPath[0];
                currentDepthPath.RemoveAt(0);
                currentDepthPath.Add(StartingNode);

                // Last iteration
                //path = currentDepthPath;
                // All iterations
                path.Add(currentDepthPath);

                numberOfNodes        = Math.Max(numberOfNodes, visited.Count);
                collectedAllDiamonds = Goals.Count == 0;
            }

            sw.Stop();

            score = new Score("IDDFS", numberOfNodes, numberOfDiamonds, collectedAllDiamonds, sw.Elapsed);

            return(path);
        }
示例#4
0
        public static void Update(GameTime gameTime, Game1 game, GameState gameState)
        {
            if (prevGameTime == null)
            {
                prevGameTime = new GameTime(gameTime.TotalGameTime, gameTime.ElapsedGameTime);
            }

            if (nodeGrid.Length == 0)
            {
                LoadMap();
            }

            switch (gameState)
            {
            case GameState.MANUAL_MODE:
                if (!gameOver)
                {
                    if (!humanStopWatch.IsRunning)
                    {
                        humanStopWatch.Start();
                    }
                    ManualMode(gameTime);
                }
                else if (gameOver && humanStopWatch.IsRunning)
                {
                    humanStopWatch.Stop();
                    Score humanScore = new Score("Human", humanPathNumberOfNodes, collectedDiamonds, collectedDiamonds == goals.Count, humanStopWatch.Elapsed);
                    Scores.Add(humanScore);
                    HumanScores.Add(humanScore);
                    humanStopWatch.Reset();
                }
                break;

            case GameState.ASTAR_MODE:
                if (path == null)
                {
                    Score score;
                    path = SolveAStar(out score);
                    ComputerScores.Add(score);
                    Scores.Add(score);
                }
                if (!gameOver)
                {
                    MovePlayerFromPath(gameTime);
                }
                break;

            case GameState.IDDFS_MODE:
                if (multiPath == null)
                {
                    Score score;
                    multiPath = SolveIDDFS(out score);
                    ComputerScores.Add(score);
                    Scores.Add(score);
                }
                if (!gameOver)
                {
                    MovePlayerFrom2DPath(gameTime);
                }
                break;

            case GameState.CSP_MODE:
                if (path == null)
                {
                    Score score;
                    path = SolveCSP(out score);
                    ComputerScores.Add(score);
                    Scores.Add(score);
                }
                if (!gameOver)
                {
                    MovePlayerFromPath(gameTime);
                }
                break;

            case GameState.SA_MODE:
                if (path == null)
                {
                    Score score;
                    path = SolveSA(out score);
                    ComputerScores.Add(score);
                    Scores.Add(score);
                    SAScores.Add(score);
                }
                if (!gameOver)
                {
                    MovePlayerFromPath(gameTime);
                }
                break;
            }

            if (gameOver)
            {
                Resources.backgroundMusicInstance.Stop();
            }

            MouseState mouseState = Mouse.GetState();

            if (mouseState.X < backButtonPosition.X || mouseState.Y < backButtonPosition.Y || mouseState.X > backButtonPosition.X + Resources.buttonBackground.Width || mouseState.Y > backButtonPosition.Y + Resources.buttonBackground.Height)
            {
                backHover = false;
            }
            else
            {
                backHover = true;
                if (mouseState.LeftButton == ButtonState.Released && prevMouseState.LeftButton == ButtonState.Pressed)
                {
                    game.gameState = GameState.MAIN_MENU;
                    Resources.backgroundMusicInstance.Stop();
                    if (humanStopWatch.IsRunning)
                    {
                        humanStopWatch.Stop();
                        Score humanScore = new Score("Human", humanPathNumberOfNodes, collectedDiamonds, collectedDiamonds == goals.Count, humanStopWatch.Elapsed);
                        Scores.Add(humanScore);
                        HumanScores.Add(humanScore);
                        humanStopWatch.Reset();
                    }
                    Reset();
                }
            }

            if (game.gameState != GameState.MAIN_MENU && game.gameState != GameState.SCORES)
            {
                prevMouseState = mouseState;
            }
        }