public static PillPath NearestPill(Node currentNode, GameState gs)
        {
            Node bestNode = null;

            Node.PathInfo bestPath = null;
            foreach (Node node in gs.Map.Nodes)
            {
                if (node.Walkable)
                {
                    if (node.Type == Node.NodeType.Pill || node.Type == Node.NodeType.PowerPill)
                    {
                        if (bestPath == null)
                        {
                            bestNode = node;
                            bestPath = gs.Pacman.Node.ShortestPath[node.X, node.Y];
                            continue;
                        }
                        Node.PathInfo curPath = currentNode.ShortestPath[node.X, node.Y];
                        if (curPath != null && curPath.Distance < bestPath.Distance)
                        {
                            bestNode = node;
                            bestPath = curPath;
                        }
                    }
                }
            }
            return(new PillPath(bestNode, bestPath));
        }
Пример #2
0
        public static Node.PathInfo NearestPill(Node currentNode, GameState gs, Direction initialDir, Node.NodeType type)
        {
            Node bestNode = null;

            Node.PathInfo bestPath = null;
            foreach (Node node in gs.Map.Nodes)
            {
                if (node.Walkable)
                {
                    if (node.Type == type)
                    {
                        if (bestPath == null)
                        {
                            bestNode = node;
                            bestPath = gs.Pacman.Node.ShortestPath[node.X, node.Y, (int)initialDir];
                            continue;
                        }
                        Node.PathInfo curPath = currentNode.ShortestPath[node.X, node.Y, (int)initialDir];
                        if (curPath != null && curPath.Distance < bestPath.Distance)
                        {
                            bestNode = node;
                            bestPath = curPath;
                        }
                    }
                }
            }
            return(bestPath);
        }
Пример #3
0
        public List <Node> GetRoute(int startX, int startY, int endX, int endY)
        {
            Node.PathInfo pathInfo = Nodes[startX, startY].ShortestPath[endX, endY, (int)Direction.None];
            if (pathInfo == null)
            {
                //Console.WriteLine("No path from " + startX + "," + startY + " to " + endX + "," + endY);
                return(null);
            }
            List <Node> path    = new List <Node>();
            Node        curNode = Nodes[startX, startY];

            while (!(curNode.X == endX && curNode.Y == endY))
            {
                curNode = curNode.GetNode(curNode.ShortestPath[endX, endY, (int)Direction.None].Direction);
                path.Add(curNode);
            }
            return(path);
        }
Пример #4
0
        public static int GetNumberOfJunctionsInPath(Node startNode, Node endNode, Direction initialDir)
        {
            Node.PathInfo pathInfo = startNode.ShortestPath[endNode.X, endNode.Y, (int)initialDir];
            if (pathInfo == null)
            {
                return(0);
            }
            int nJunctions = 0;

            while (pathInfo.ParentNode != startNode)
            {
                if (pathInfo.ParentNode.PossibleDirections.Count > 2)
                {
                    nJunctions++;
                }
                pathInfo = startNode.ShortestPath[pathInfo.ParentNode.X, pathInfo.ParentNode.Y, (int)initialDir];
            }
            return(nJunctions);
        }
 public PillPath(Node target, Node.PathInfo pathInfo)
 {
     this.Target   = target;
     this.PathInfo = pathInfo;
 }
        private void runPac(Direction direction, Node nextNode)
        {
            if (!nextNode.Walkable)
            {
                PacDanger[(int)direction]      = -1.0f;
                PacDangerLimit[(int)direction] = -1;
                return;
            }
            // calculate different routes
            List <PredictPacman> pacmans = new List <PredictPacman>();

            pacmans.Add(new PredictPacman(nextNode, direction, null));
            for (int i = 1; i < dangerMaps.Length; i++)
            {
                List <PredictPacman> newPacmans = new List <PredictPacman>();
                foreach (PredictPacman p in pacmans)
                {
                    // no need to check further when danger is certain death
                    if (p.Danger == 1.0f)
                    {
                        continue;
                    }
                    // if reached powerpill then just keep score
                    if (p.Node.Type == Node.NodeType.PowerPill)
                    {
                        //newPacmans.Add(p);
                        continue;
                    }
                    // future prediction
                    foreach (Node possibleNode in p.Node.GhostPossibles[(int)p.Direction])
                    {
                        if (dangerMaps[i].Danger[possibleNode.X, possibleNode.Y] > p.Danger)
                        {
                            p.Danger = dangerMaps[i].Danger[possibleNode.X, possibleNode.Y];
                        }
                        if (possibleNode == p.Node.Up)
                        {
                            newPacmans.Add(new PredictPacman(possibleNode, Direction.Up, p));
                        }
                        else if (possibleNode == p.Node.Down)
                        {
                            newPacmans.Add(new PredictPacman(possibleNode, Direction.Down, p));
                        }
                        else if (possibleNode == p.Node.Left)
                        {
                            newPacmans.Add(new PredictPacman(possibleNode, Direction.Left, p));
                        }
                        else if (possibleNode == p.Node.Right)
                        {
                            newPacmans.Add(new PredictPacman(possibleNode, Direction.Right, p));
                        }
                    }
                }
                pacmans = newPacmans;
            }
            // find least dangerous
            float danger      = 1.0f;
            int   dangerLimit = 0;

            foreach (PredictPacman p in pacmans)
            {
                //Console.Write(p.Danger + ",");
                if (p.Danger < danger)
                {
                    danger = p.Danger;
                }
                if (p.DangerLimitIteration > dangerLimit)
                {
                    dangerLimit = p.DangerLimitIteration;
                }
            }
            // distance danger
            foreach (PredictEntity pg in curGhosts)
            {
                Node.PathInfo shortestPath = pg.Node.ShortestPath[nextNode.X, nextNode.Y];
                if (shortestPath != null)
                {
                    float distDanger = 1.0f / shortestPath.Distance;
                    if (distDanger > danger)
                    {
                        danger = distDanger;
                    }
                }
            }
            //Console.WriteLine("");
            //Console.WriteLine(direction + ": " + danger + " -- " + pacmans.Count);
            // save results
            PacDanger[(int)direction]      = danger;
            PacDangerLimit[(int)direction] = dangerLimit;
        }
Пример #7
0
        private void run()
        {
            // generate danger maps
            insertGhostDanger(dangerMaps[0]);
            for (int i = 1; i < dangerMaps.Length; i++)
            {
                dangerMaps[i] = new DangerMap(gs);
                updateGhosts();
                insertGhostDanger(dangerMaps[i]);
                //Console.WriteLine(i + ": " + dangerMaps[i].Danger[13, 23]);
                //Console.WriteLine(i + ": " + dangerMaps[i].Danger[gs.Pacman.Node.X, gs.Pacman.Node.Y]);
            }
            // calculate danger for pacman
            PossibleDirections = new List <Direction>();
            foreach (Node node in gs.Pacman.Node.PossibleDirections)
            {
                PossibleDirections.Add(gs.Pacman.Node.GetDirection(node));
            }
            // eliminate directions where ghosts close
            for (int i = 1; i < 2; i++)
            {
                foreach (PredictGhost ghost in ghosts)
                {
                    if (!ghost.Chasing)
                    {
                        continue;
                    }
                    Node.PathInfo shortestPath = gs.Pacman.Node.ShortestPath[ghost.Node.X, ghost.Node.Y];
                    if (shortestPath != null)
                    {
                        if (i == 1)
                        {
                            //Console.WriteLine("shortest: " + shortestPath.Direction + " @ " + shortestPath.Distance + " : " + ghost.Node);
                        }
                        if (shortestPath.Distance < i)
                        {
                            // remove
                            PossibleDirections.Remove(shortestPath.Direction);
                            if (PossibleDirections.Count == 1)
                            {
                                if (debug)
                                {
                                    Console.WriteLine(":: Close danger decision: " + PossibleDirections[0]);
                                }
                                goto OneDirectionLeft;
                            }
                        }
                    }
                    else if (gs.Pacman.Node == ghost.Node)
                    {
                        List <Direction> newPossibles = new List <Direction>();
                        foreach (Direction d in PossibleDirections)
                        {
                            newPossibles.Add(d);
                        }
                        newPossibles.Remove(StateInfo.GetInverse(ghost.Direction));
                        if (newPossibles.Count == 1)
                        {
                            PossibleDirections = newPossibles;
                            if (debug)
                            {
                                Console.WriteLine(":: Extreme danger decision: " + PossibleDirections[0]);
                            }
                            goto OneDirectionLeft;
                        }
                    }
                }
            }
            // circular run ...
            for (int i = 3; i < 10; i++)
            {
                int result;
                if (i < 6)
                {
                    result = circularTest(i, i - 2);
                }
                else
                {
                    result = circularTest(i, i);
                }
                if (result == 0)
                {
                    break;
                }
                // warp hack
                if (gs.Map.Tunnels[gs.Pacman.Node.Y])
                {
                    if (gs.Pacman.Node.X < 2 || gs.Pacman.Node.X > Map.Width - 3)
                    {
                        PossibleDirections.Remove(Direction.Left);
                        PossibleDirections.Remove(Direction.Right);
                        PossibleDirections.Add(Direction.Left);
                        PossibleDirections.Add(Direction.Right);
                    }
                }
                if (PossibleDirections.Count == 1)
                {
                    if (debug)
                    {
                        Console.WriteLine(":: Circular test decision: " + PossibleDirections[0]);
                    }
                    goto OneDirectionLeft;
                }
            }

            /*
             * // try and predict safe route
             * List<Direction> Safe = new List<Direction>();
             * List<UnsafeDirection> Unsafe = new List<UnsafeDirection>();
             * foreach( Direction d in PossibleDirections ) {
             *      int result = evasionPac(d);
             *      Console.WriteLine(d + ": " + result);
             *      if( result >= Iterations ) {
             *              Safe.Add(d);
             *      } else {
             *              Unsafe.Add(new UnsafeDirection(d,result));
             *      }
             * }
             * if( Safe.Count > 0 ) {
             *      PossibleDirections = Safe;
             * } else{
             *      Unsafe.Sort(new Comparison<UnsafeDirection>(delegate(UnsafeDirection u1, UnsafeDirection u2){
             *              if( u1.Safety == u2.Safety ) return 0;
             *              if( u1.Safety > u2.Safety ) return -1;
             *              return 1;
             *      }));
             *      foreach( UnsafeDirection u in Unsafe ) {
             *              Console.WriteLine(" - " + u.Direction + ": " + u.Safety);
             *      }
             *      PossibleDirections = new List<Direction>();
             *      int best = Unsafe[0].Safety;
             *      foreach( UnsafeDirection u in Unsafe ) {
             *              if( u.Safety == best ) {
             *                      PossibleDirections.Add(Unsafe[0].Direction);
             *              }
             *      }
             * }
             * if( PossibleDirections.Count == 1 ) {
             *      Console.WriteLine(":: Unsafe decision: " + PossibleDirections[0]);
             * }
             */
            // finished
OneDirectionLeft:
            //Console.WriteLine("------------------");
            return;
        }
Пример #8
0
        private int circularTest(int radius, int check)
        {
            int         startX        = gs.Pacman.Node.X - radius;
            int         endX          = gs.Pacman.Node.X + radius;
            int         startY        = gs.Pacman.Node.Y - radius;
            int         endY          = gs.Pacman.Node.Y + radius;
            List <Node> circularNodes = new List <Node>();

            for (int y = startY; y <= gs.Pacman.Node.Y + radius; y++)
            {
                for (int x = startX; x <= gs.Pacman.Node.X + radius; x++)
                {
                    int testY = y; if (testY < 1)
                    {
                        testY = 1;
                    }
                    if (testY >= Map.Height)
                    {
                        testY = Map.Height - 2;
                    }
                    int testX = x;
                    if (gs.Map.Tunnels[testY])
                    {
                        if (testX < 0)
                        {
                            testX = 0;
                        }
                        if (testX >= Map.Width)
                        {
                            testX = Map.Width - 1;
                        }
                    }
                    else
                    {
                        if (testX < 1)
                        {
                            testX = 1;
                        }
                        if (testX >= Map.Width)
                        {
                            testX = Map.Width - 2;
                        }
                    }
                    if (y == startY || y == endY || x == startX || x == endX ||
                        testX == 1 || testY == 1 || testX == Map.Width - 2 || testY == Map.Height - 2)
                    {
                        if (gs.Map.Nodes[testX, testY].Walkable)
                        {
                            circularNodes.Add(gs.Map.Nodes[testX, testY]);
                        }

                        /*if( x >= 0 && x < Map.Width &&
                         *      y >= 0 && y < Map.Height ) {
                         *              if( gs.Map.Nodes[testX, testY].Walkable ) {
                         *              circularNodes.Add(gs.Map.Nodes[testX, testY]);
                         *      }
                         * }*/
                    }
                }
            }
            bool[] possibles = { false, false, false, false };
            bool[] allowed   = { false, false, false, false };
            foreach (Direction d in PossibleDirections)
            {
                allowed[(int)d] = true;
            }
            foreach (Node node in circularNodes)
            {
                Node.PathInfo path = gs.Pacman.Node.ShortestPath[node.X, node.Y];
                if (path != null && possibles[(int)path.Direction] == false && allowed[(int)path.Direction])
                {
                    List <Node> route = gs.Map.GetRoute(gs.Pacman.Node, node);
                    possibles[(int)path.Direction] = true;
                    foreach (Node rNode in route)
                    {
                        if (dangerMaps[check].Danger[rNode.X, rNode.Y] == 1.0f)
                        {
                            possibles[(int)path.Direction] = false;
                            break;
                        }
                        if (rNode.Type == Node.NodeType.PowerPill)
                        {
                            break;
                        }
                    }
                }
            }
            if (debug)
            {
                Console.Write(radius + ": ");
            }
            List <Direction> newPossibleDirections = new List <Direction>();

            for (int i = 0; i < possibles.Length; i++)
            {
                if (possibles[i])
                {
                    newPossibleDirections.Add((Direction)i);
                }
                if (debug)
                {
                    Console.Write(possibles[i] + ",");
                }
            }
            if (newPossibleDirections.Count > 0)
            {
                PossibleDirections = newPossibleDirections;
            }
            if (debug)
            {
                Console.WriteLine("");
            }
            return(newPossibleDirections.Count);
        }