public Point GetTarget(ref Pac pac) { Point target = null; Pac enemyPac = PacController.GetClosestEnemy(pac); //Pac enemyPac = PacController.GetClosestVisibleEnemy(pac, true); int distanceToEnemy; if (enemyPac != null) { distanceToEnemy = pac.origin.GetDistanceTo(enemyPac.origin); PacType strongerThanMe = Common.GetStrongerPacType(pac.pacType); PacType strongerThanHim = Common.GetStrongerPacType(enemyPac.pacType); Console.Error.WriteLine("ATTACK! pacType" + pac.pacType.ToString() + " strongerThanHim:" + strongerThanHim.ToString() + " distance:" + distanceToEnemy.ToString()); if (pac.pacType == strongerThanHim && distanceToEnemy <= 6) { pac.shouldActivateSpeed = true; pac.inPursuit = true; target = enemyPac.origin; } else { if (pac.cooldown > (enemyPac.speedTurnsLeft > 0 ? distanceToEnemy / 2 : distanceToEnemy)) { //Bezanija!!! //Level.GetClosestJunctionInDirection(); } } } Console.Error.WriteLine("PacId:" + pac.id + " Strategy: Attack " + ((target == null) ? "null" : target.ToString()) + " inPursuit:" + pac.inPursuit.ToString()); return(target); }
public static void SetPath(Pac pac, List <Point> path) { pac.previousTarget = pac.currentTarget; pac.isOnPath = true; pac.isOnHold = false; pac.indexOnPath = 0; pac.distanceToTarget = path.Count; pac.path = path; }
public static Pac GetClosestVisibleEnemy(Pac myPac, bool withOppositeDirection = false) { Console.Error.WriteLine("GetClosestVisibleEnemy start"); Pac result = null; int minDistance = int.MaxValue; int distanceToEnemy = int.MaxValue; if (enemyPacs.Count == 0) { Console.Error.WriteLine("No enemies!"); return(null); } List <Pac> enemies = new List <Pac>(); foreach (Pac enemy in enemyPacs) { Console.Error.WriteLine("GetClosestVisibleEnemy enemy: " + enemy.origin.ToString()); //foreach (Point tile in Level.GetTilesVisibleFrom(myPac.origin)) //{ // Console.Error.WriteLine("GetClosestVisibleEnemy visible: " + tile.ToString()); //} if (Level.GetTilesVisibleFrom(myPac.origin).Contains(enemy.origin)) { Console.Error.WriteLine("GetClosestVisibleEnemy match found! opositeDirection:" + withOppositeDirection.ToString()); distanceToEnemy = myPac.origin.GetDistanceTo(enemy.origin); if (withOppositeDirection) { if (PacController.HaveOppositeDirection(myPac, enemy, myPac.currentTarget)) { if (distanceToEnemy < minDistance) { result = enemy; minDistance = distanceToEnemy; } } } else { if (distanceToEnemy < minDistance) { result = enemy; minDistance = distanceToEnemy; } } } } if (result != null) { Console.Error.WriteLine("Found closest enemy!. myPac:" + myPac.id.ToString() + " enemy: " + result.id.ToString()); } return(result); }
public static void SetTargets() { Console.Error.WriteLine("SetTargets, mypacs count:" + PacController.myPacs.Count().ToString()); for (int i = 0; i < PacController.myPacs.Count; i++) { Pac pac = PacController.myPacs[i]; if (pac.isAlive) { Logic.SetTarget(ref pac); } } }
public static void CheckArrivalToTarget(ref Pac pac) { if (pac.isOnPath && pac.origin.Equals(pac.currentTarget)) { Console.Error.WriteLine("Arrival! Pac: " + pac.id + " target: " + pac.currentTarget.ToString()); pac.currentTarget = null; pac.isOnPath = false; pac.hasFixedTarget = false; pac.indexOnPath = -1; pac.distanceToTarget = 0; } }
public Controller(Maze maze, Random random) //controller creates a Pacman and 3 Ghosts { this.maze = maze; ghost = new List <Ghost>(); this.random = random; pac = new Pac(Properties.Resources.pacman1right, maze); ghost.Add(new Ghost(Properties.Resources.red1, maze)); ghost.Add(new Ghost(Properties.Resources.green1, maze)); ghost.Add(new Ghost(Properties.Resources.purple1, maze)); }
//Used when we realize that there is a pac closer to already selected target that the pac it was selected for, and we want to switch these pacs - assing this already selected target to current/closer pac and keep searching for farther pac public static void SwapPacTargets(ref Pac previousOwner, ref Pac newOwner, Point target) { if (previousOwner.hasFixedTarget || previousOwner.inPursuit) { Console.Error.WriteLine("Cannot swap: Pac: " + previousOwner.id.ToString() + " has fixed target: " + previousOwner.currentTarget.ToString()); return; } Console.Error.WriteLine("Swapping targets - Previous: " + previousOwner.id.ToString() + " New" + newOwner.id.ToString() + " Pellet:" + target.ToString()); newOwner.currentTarget = target; previousOwner.currentTarget = null; //previousOwner.isOnPath = false; newOwner = previousOwner; return; }
public static List <Point> CalculatePath(ref Pac pac, Node start, Node end) { List <Point> path = new List <Point>(); Node currentNode = end; while (currentNode != start) { path.Add(currentNode as Point); currentNode = currentNode.parent; //Console.Error.WriteLine("Added to path: " + currentNode.ToString()); } path.Reverse(); return(path); }
public static void SetTarget(ref Pac pac) { CheckArrivalToTarget(ref pac); Point target = StrategyPicker.GetTargetFromStrategy(ref pac); pac.currentTarget = target; if (pac.currentTarget == null) { pac.currentTarget = new Point(pac.origin); pac.isOnHold = true; Console.Error.WriteLine("Waiting!"); } Console.Error.WriteLine("Pac: " + pac.id + " target: " + pac.currentTarget.ToString()); return; }
public static void FindPaths() { for (int i = 0; i < PacController.myPacs.Count; i++) { Pac pac = PacController.myPacs[i]; if (pac.isAlive) { //if it is on path, target hasn't changed and there is no collision, just proceed if (pac.isOnPath && (pac.currentTarget == pac.previousTarget) && (pac.origin != pac.previousOrigin)) { pac.indexOnPath++; } else { //if (pac.isOnHold || pac.isInCollision) //{ // pac.isOnPath = false; // pac.previousTarget = pac.currentTarget; // //pac.currentTarget = null; // continue; //} List <Point> path; if (FindPath(pac, new Node(pac.origin), new Node(pac.currentTarget), out path)) { if (path.Count > 0) { SetPath(pac, path); } else { pac.isOnPath = false; pac.isOnHold = true; } } else { pac.isOnPath = false; pac.isOnHold = true; } } } } }
public Point GetTarget(ref Pac pac) { Point target = null; double minDistance = Double.MaxValue; double distance; if (pac.currentTarget != null && pac.currentTarget.hasVisiblePellets) // && !PacController.GetCurrentTargets().Values.Contains(pac.currentTarget)) { Console.Error.WriteLine("Keeping current target:" + pac.currentTarget.ToString()); return(pac.currentTarget); } foreach (KeyValuePair <Point, int> junction in Level.junctions) { if (PacController.GetCurrentTargets().Values.Contains(junction.Key)) { Pac previousTargetOwner = PacController.GetPacWithCurrentTarget(junction.Key); if ((pac.origin.GetDistanceTo(junction.Key) < previousTargetOwner.origin.GetDistanceTo(junction.Key))) { Common.SwapPacTargets(ref previousTargetOwner, ref pac, junction.Key); } else { Console.Error.WriteLine("Junction to skip:" + junction.Key.ToString()); } continue; } if (junction.Key.hasVisiblePellets) { distance = pac.origin.GetDistanceTo(junction.Key); if ((distance < minDistance) && (distance > 0.1)) { minDistance = distance; target = junction.Key; Console.Error.WriteLine("Junction target:" + junction.Key.ToString() + " distance: " + distance.ToString()); } } } Console.Error.WriteLine("PacId:" + pac.id + " Strategy: Junctions " + ((target == null) ? "null" : target.ToString())); return(target); }
public static Pac GetPacWithCurrentTarget(Point target) { Pac pac = null; if (GetCurrentTargets().Values.Contains(target)) { foreach (KeyValuePair <int, Point> keyValuePair in GetCurrentTargets()) { if (keyValuePair.Value.Equals(target)) { Console.Error.WriteLine("Found pac for target: " + target.ToString() + " id: " + keyValuePair.Key.ToString()); pac = GetMyPac(keyValuePair.Key); } } //pac = GetPac(GetCurrentTargets().Where(x => x.Value.Equals(target)).FirstOrDefault().Key); } return(pac); }
public static bool HaveOppositeDirection(Pac myPac, Pac otherPac, Point myPacTarget = null) { Point myPacDirection; Point otherPacDirection; if (myPacTarget != null) { myPacDirection = GetDirectionSigns(myPac.origin, myPacTarget); } else { //Special case for first turn if (myPac.previousOrigin == null) { return(false); //myPacDirection = new Point(0, 0); } else { myPacDirection = GetDirectionSigns(myPac.previousOrigin, myPac.origin); } } //Special case for first turn if (otherPac.previousOrigin == null) { return(false); //otherPacDirection = new Point(0, 0); } else { otherPacDirection = GetDirectionSigns(otherPac.previousOrigin, otherPac.origin); } //either other pac is stationary, or distance in x or y between two pacs is getting smaller bool result = (otherPacDirection.x == 0 && otherPacDirection.y == 0) || ((myPacDirection.x == -otherPacDirection.x) && Math.Abs(myPac.origin.x + myPacDirection.x - otherPac.origin.x - otherPacDirection.x) < Math.Abs(myPac.origin.x - otherPac.origin.x)) || ((myPacDirection.y == -otherPacDirection.y) && Math.Abs(myPac.origin.y + myPacDirection.y - otherPac.origin.y - otherPacDirection.y) < Math.Abs(myPac.origin.y - otherPac.origin.y)); Console.Error.WriteLine("Pac directions. myPac:" + myPac.id.ToString() + " direction:" + myPacDirection.ToString() + " other pac:" + otherPac.id.ToString() + " direction:" + otherPacDirection.ToString()); return(result); }
public Point GetTarget(ref Pac pac) { Console.Error.WriteLine("Mimic strategy start"); Point target = null; Pac enemyPac = PacController.GetClosestVisibleEnemy(pac, true); int distance = Common.minDistanceForSwitch; if (enemyPac != null) { if (enemyPac.speedTurnsLeft > 0) { if (pac.speedTurnsLeft > 0) { distance = distance + 2; } else { distance = distance + 1; } } } if (enemyPac != null && pac.origin.GetDistanceTo(enemyPac.origin) <= distance) { PacType strongerType = Common.GetStrongerPacType(enemyPac.pacType); if (pac.pacType != strongerType) { pac.shouldActivateSwitch = true; pac.switchTo = strongerType; } } else { return(null); } target = enemyPac.origin; Console.Error.WriteLine("PacId:" + pac.id + " Strategy: Mimic " + ((target == null) ? "null" : target.ToString())); return(target); }
public static Point GetTargetFromStrategy(ref Pac pac) { Point result; result = new AttackStrategy().GetTarget(ref pac); if (result != null && pac.inPursuit) { return(result); } else { pac.inPursuit = false; } result = new MimicStrategy().GetTarget(ref pac); if ((result == null) && (PelletController.BigPellets.Count > 0)) { result = new GreedyStrategy().GetTarget(ref pac); result = pac.ResetTargetIfStationary(result); } if ((result == null) && (PelletController.Pellets.Count > 0)) { result = new VisibleStrategy().GetTarget(ref pac); result = pac.ResetTargetIfStationary(result); } if ((result == null) && (Level.junctions.Count > 0)) { result = new JunctionsStrategy().GetTarget(ref pac); result = pac.ResetTargetIfStationary(result); } if (result == null) { result = new WaitStrategy().GetTarget(ref pac); } return(result); }
public Point GetTarget(ref Pac pac) { if (pac.currentTarget != null && PelletController.ExistsAtPosition(pac.currentTarget)) // && !PacController.GetCurrentTargets().Values.Contains(pac.currentTarget)) { return(pac.currentTarget); } Point target = null; double minDistance = Double.MaxValue; double distance; if (PelletController.BigPellets.Count > 0) { foreach (Point bigPellet in PelletController.BigPellets) { if (PacController.GetCurrentTargets().Values.Contains(bigPellet)) { Pac previousTargetOwner = PacController.GetPacWithCurrentTarget(bigPellet); if ((pac.origin.GetDistanceTo(bigPellet) < previousTargetOwner.origin.GetDistanceTo(bigPellet))) { Common.SwapPacTargets(ref previousTargetOwner, ref pac, bigPellet); } else { Console.Error.WriteLine("Pellet to skip:" + bigPellet.ToString()); } continue; } distance = bigPellet.GetDistanceTo(pac.origin); if (distance < minDistance) { minDistance = distance; target = new Point(bigPellet); } } } Console.Error.WriteLine("PacId:" + pac.id + " Strategy: Greedy" + ((target == null) ? "null" : target.ToString())); return(target); }
public static void AddPac(int id, int x, int y, string pacType, bool mine, int speedTurnsLeft, int abilityCooldown) { Point origin = new Point(x, y); Pac pac = new Pac(id, origin, pacType); pac.speedTurnsLeft = speedTurnsLeft; pac.cooldown = abilityCooldown; pac.cooldown = abilityCooldown; if (mine) { myCurrentPacs.Add(pac); //myPacs.Add(pac); } else { enemyCurrentPacs.Add(pac); //enemyPacs.Add(pac); } Console.Error.WriteLine("Added Pac! Id: " + pac.id.ToString() + " Pac origin: " + pac.origin.ToString()); }
//Not thread safe public static List <Point> MarkObstacles(Pac pac, Point target) { List <Point> result = new List <Point>(); Point pacDirection = PacController.GetDirectionSigns(pac.origin, target); foreach (Pac otherPac in PacController.myPacs) { if (pac.id == otherPac.id || !otherPac.isAlive || otherPac.previousOrigin == null) { continue; } Point otherPacDirection = PacController.GetDirectionSigns(otherPac.previousOrigin, otherPac.origin); if (PacController.HaveOppositeDirection(pac, otherPac, target)) { Console.Error.WriteLine("Obstacle found:" + otherPac.origin.ToString()); result.Add(otherPac.origin); Level.map[otherPac.origin.y, otherPac.origin.x] = -1; } } return(result); }
public static Pac GetClosestEnemy(Pac pac) { Pac result = null; int minDistance = int.MaxValue; int distance; for (int i = 0; i < enemyPacs.Count(); i++) { distance = pac.origin.GetDistanceTo(enemyPacs[i].origin); if (distance < minDistance) { result = enemyPacs[i]; minDistance = distance; } } if (result != null) { Console.Error.WriteLine("Found closest enemy!. myPac:" + pac.id.ToString() + " enemy: " + result.id.ToString()); } return(result); }
public static void SyncPacs() { if (myPacs.Count() != 0) { foreach (Pac pac in myPacs) { Pac currentPac = myCurrentPacs.Where(x => x.id == pac.id).FirstOrDefault(); if (currentPac == null) { pac.isAlive = false; Console.Error.WriteLine("Synced dead Pac! Id: " + pac.id.ToString() + " Pac origin: " + pac.origin.ToString()); } else { pac.speedTurnsLeft = currentPac.speedTurnsLeft; pac.pacType = currentPac.pacType; pac.cooldown = currentPac.cooldown; pac.previousOrigin = pac.origin; pac.origin = currentPac.origin; pac.CheckFixedTarget(); pac.isInCollision = false; pac.shouldActivateSpeed = false; pac.shouldActivateSwitch = false; pac.isOnHold = false; Console.Error.WriteLine("Synced Pac! Id: " + pac.id.ToString() + " Pac origin: " + pac.origin.ToString()); } } } //First turn only - adding pacs else { foreach (Pac pac in myCurrentPacs) { myPacs.Add(pac); Console.Error.WriteLine("Synced added Pac! Id: " + pac.id.ToString() + " Pac origin: " + pac.origin.ToString()); } } Console.Error.WriteLine("Enemy pacs count:" + enemyPacs.Count().ToString()); if (enemyPacs.Count() != 0) { List <Pac> enemyPacsToRemove = new List <Pac>(); foreach (Pac pac in enemyPacs) { Pac currentPac = enemyCurrentPacs.Where(x => x.id == pac.id).FirstOrDefault(); if (currentPac == null) { enemyPacsToRemove.Add(pac); Console.Error.WriteLine("Enemy pac to remove! Id: " + pac.id.ToString()); } else { pac.speedTurnsLeft = currentPac.speedTurnsLeft; pac.cooldown = currentPac.cooldown; pac.previousOrigin = pac.origin; pac.origin = currentPac.origin; Console.Error.WriteLine("Synced enemy pac! Id: " + pac.id.ToString() + " Pac origin: " + pac.origin.ToString()); } } foreach (Pac enemyPac in enemyPacsToRemove) { Pac currentPac = GetEnemyPac(enemyPac.id); if (currentPac != null) { enemyPacs.Remove(currentPac); } } foreach (Pac enemyPac in enemyCurrentPacs) { Pac currentPac = GetEnemyPac(enemyPac.id); if (currentPac == null) { enemyPacs.Add(enemyPac); } Console.Error.WriteLine("Synced added enemy pac! Id: " + enemyPac.id.ToString() + " Pac origin: " + enemyPac.origin.ToString()); } } //First turn only - adding pacs else { foreach (Pac pac in enemyCurrentPacs) { enemyPacs.Add(pac); Console.Error.WriteLine("Synced added enemy pac! Id: " + pac.id.ToString() + " Pac origin: " + pac.origin.ToString()); } } }
static void Main(string[] args) { string[] inputs; inputs = Console.ReadLine().Split(' '); int width = int.Parse(inputs[0]); // size of the grid int height = int.Parse(inputs[1]); // top left corner is (x=0, y=0) string[] levelRows = new string[height]; for (int i = 0; i < height; i++) { string row = Console.ReadLine(); // one line of the grid: space " " is floor, pound "#" is wall levelRows[i] = row; } Level.InitializeLevel(width, height); Level.StringsToMatrix(levelRows); Level.CalculateJunctions(); //Level.PrintJunctions(); // game loop while (true) { Common.CurrentTurn++; //PacController.ClearCurrentTargets(); //Common.currentTargets.Clear(); inputs = Console.ReadLine().Split(' '); int myScore = int.Parse(inputs[0]); int opponentScore = int.Parse(inputs[1]); int visiblePacCount = int.Parse(Console.ReadLine()); // all your pacs and enemy pacs in sight PacController.ClearPacs(); for (int i = 0; i < visiblePacCount; i++) { inputs = Console.ReadLine().Split(' '); int pacId = int.Parse(inputs[0]); // pac number (unique within a team) bool mine = inputs[1] != "0"; // true if this pac is yours int x = int.Parse(inputs[2]); // position in the grid int y = int.Parse(inputs[3]); // position in the grid string typeId = inputs[4]; // unused in wood leagues int speedTurnsLeft = int.Parse(inputs[5]); // unused in wood leagues int abilityCooldown = int.Parse(inputs[6]); // unused in wood leagues PacController.AddPac(pacId, x, y, typeId, mine, speedTurnsLeft, abilityCooldown); } PacController.SyncPacs(); //PacController.DetectCollisions(); PelletController.ClearPellets(); int visiblePelletCount = int.Parse(Console.ReadLine()); // all pellets in sight Console.Error.WriteLine("Visible pellets: " + visiblePelletCount.ToString()); if (visiblePelletCount == 0) { Logic.MarkEmptyTiles(); } for (int i = 0; i < visiblePelletCount; i++) { inputs = Console.ReadLine().Split(' '); int x = int.Parse(inputs[0]); int y = int.Parse(inputs[1]); int value = int.Parse(inputs[2]); // amount of points this pellet is worth if (value > 1) { PelletController.AddBigPellet(x, y); } else { PelletController.AddPellet(x, y); } } Logic.SetTargets(); Logic.FindPaths(); List <Point> targets = new List <Point>(); string output = ""; for (int i = 0; i < PacController.myPacs.Count; i++) { Pac pac = PacController.myPacs[i]; if (!pac.isAlive) { continue; } Point target; if (pac.isOnPath) { Console.Error.WriteLine("Pac on path: id: " + pac.id.ToString() + " index:" + pac.indexOnPath + " target:" + pac.currentTarget.ToString() + " distance:" + pac.distanceToTarget.ToString()); target = pac.path[pac.indexOnPath]; } else { target = pac.currentTarget; } if (targets.Contains(target)) { Pac otherPac = PacController.GetPacWithCurrentTarget(target); if (otherPac != null && PacController.myPacs[i].origin.GetDistanceTo(otherPac.origin) <= 2) { target = PacController.myPacs[i].previousTarget; } } else { targets.Add(target); } string command = ""; if (pac.cooldown == 0 && pac.shouldActivateSwitch) { command = "SWITCH " + pac.id.ToString() + " " + pac.switchTo.ToString(); } else { if (pac.cooldown == 0)// && pac.shouldActivateSpeed) { command = "SPEED " + pac.id.ToString(); } else { if (target != null) { command = "MOVE " + pac.id.ToString() + " " + target.ToString(); } } } output += (output == "") ? "" : "|"; output += command; } Console.WriteLine(output); } }
public static bool FindPath(Pac pac, Node start, Node end, out List <Point> path) { Console.Error.WriteLine("Pathfinding started! pac:" + pac.id.ToString()); List <Point> obstacles = MarkObstacles(pac, end); path = null; try { List <Node> openSet = new List <Node>(); HashSet <Node> closedSet = new HashSet <Node>(); start.gCost = 0; start.hCost = start.GetDistanceTo(end); openSet.Add(start); while (openSet.Count() > 0) { Node 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]; } } //Console.Error.WriteLine("Pathfinding currentNode: " + currentNode.ToString()); openSet.Remove(currentNode); closedSet.Add(currentNode); if (currentNode == end) { path = CalculatePath(ref pac, start, currentNode); Console.Error.WriteLine("Found path: pac:" + pac.id + " start:" + start.ToString() + " end:" + currentNode.ToString() + " distance: " + path.Count.ToString()); return(true); } List <Point> neighbours = Level.GetNeighbours(currentNode.x, currentNode.y); foreach (Point neighbour in neighbours) { //Console.Error.WriteLine("Pathfinding neighbour: " + neighbour.ToString()); if (!closedSet.Contains(neighbour)) { Node node; if (!openSet.Contains(neighbour)) { node = new Node(neighbour); openSet.Add(node); } else { node = openSet.Find(a => a.x == neighbour.x && a.y == neighbour.y); } node.gCost = currentNode.gCost + 1; node.hCost = node.GetDistanceTo(end); node.parent = currentNode; } } } return(false); } finally { UnmarkObstacles(obstacles); } }
public Point GetTarget(ref Pac pac) { Console.Error.WriteLine("PacId:" + pac.id + " Strategy: Wait"); pac.isOnHold = true; return(pac.origin); }