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