protected override Point SelectDestination(Unit unit, Point origin, List<Point> destinations) { // Recovers the Roadmap (graph of links between tiles) for the selected Unit var unitType = unit.GetType(); if (!roadmaps.ContainsKey(unitType)) { roadmaps.Add(unitType, Game.Map.GetRoadmap(unit)); } var roadmap = roadmaps[unitType]; // Find best path Tuple<double, List<Point>> bestPath = null; var targets = GetTargets(); foreach (var target in targets) { var path = Dijkstra(roadmap, origin, target); if ((path.Item1 != Infinity) && (bestPath == null || path.Item1 < bestPath.Item1)) { bestPath = path; } } // If no path to any targets if (bestPath == null) { // Returns one possible destination return destinations.First(); } // Else, returns the first step of the path return bestPath.Item2.First(); }
public void AddUnit(Unit unit, Point tile) { if (!Units.ContainsKey(tile)) { Units[tile] = new List<Unit>(); } Units[tile].Add(unit); }
public static FactionType GetType(Unit unit) { var type = unit.GetType().Name; switch (type) { case "DwarfUnit": return FactionType.Dwarf; case "ElfUnit": return FactionType.Elf; case "KnightUnit": return FactionType.Knight; case "OrcUnit": return FactionType.Orc; case "SlimeUnit": return FactionType.Slime; default: throw new ArgumentException("Impossible to retrieve type of Unit \"" + type + "\"", "unit"); } }
public FightIssue Fight(Unit defender) { Unit attacker = this; int currentRound = 1; int minRound = 3; int maxRound = minRound + Math.Max(attacker.HealthPoints, defender.HealthPoints); int totalRound = randomizer.Next(minRound, maxRound); double baseChanceToLose = 0.5; while (currentRound <= totalRound && attacker.IsAlive() && defender.IsAlive()) { double realAttackAttacker = attacker.GetRealAttack(); double realDefenseDefender = defender.GetRealDefense(); double balanceOfPower; double chanceToLose; // Fighting random chance if (realAttackAttacker < realDefenseDefender) { balanceOfPower = 1 - (realAttackAttacker / realDefenseDefender); chanceToLose = baseChanceToLose * (1 + balanceOfPower); } else { balanceOfPower = 1 - (realDefenseDefender / realAttackAttacker); chanceToLose = baseChanceToLose * (1 - balanceOfPower); } double random = randomizer.NextDouble(); // Attacker lose one health point if (random < chanceToLose) { attacker.HealthPoints--; } // Defender lose one health point else { defender.HealthPoints--; } // Next round currentRound++; } // Before attacker died if (attacker.IsDead()) { attacker.BeforeDying(); } // Before defender died else if (defender.IsDead()) { defender.BeforeDying(); } // Check again, because, before dying, some unit may resurrected (e.g: the elf unit) // Attacker died => Lose if (attacker.IsDead()) { // After defender kills defender.AfterKill(); return FightIssue.Lose; } // Defender died => Win else if (defender.IsDead()) { // After attacker kills attacker.AfterKill(); return FightIssue.Win; } // No unit died => Draw else { return FightIssue.Draw; } }
public bool MoveUnit(Unit unit, Point origin, Point destination) { if (!IsFinished && CurrentPlayer == Map.GetTileController(origin) && origin != destination && Map.IsReachableTile(unit, origin, destination)) { bool executeMovement = false; // If the destination tile is not controlled, or controlled by the same CurrentPlayer if (!Map.TileIsControlled(destination) || Map.TileIsControlledBy(destination, CurrentPlayer)) { // The Player can move to the destination tile executeMovement = true; } // Else, the unit need to fight before move else { // Get fighting Players Player attackerPlayer = CurrentPlayer; Player defenderPlayer = Map.GetTileController(destination); // Get fighting Units Unit attacker = unit; Unit defender = defenderPlayer.GetBestUnitOn(destination); // Fight var fightIssue = attacker.Fight(defender); // Attacker died if (fightIssue == FightIssue.Lose) { attackerPlayer.RemoveUnit(attacker, origin); // If there is no more unit on the star tile if (!attackerPlayer.HasUnitsOn(origin)) { // Releases the tile Map.PlayerReleasesTile(attackerPlayer, origin); } } // Defender died else if (fightIssue == FightIssue.Win) { defenderPlayer.RemoveUnit(defender, destination); // If there is no more unit on the star tile if (!defenderPlayer.HasUnitsOn(destination)) { // Releases the tile Map.PlayerReleasesTile(defenderPlayer, destination); // The attacker can finaly move to the destination tile executeMovement = true; } } // If there is a winner to the fight, check if there is a winner for the game if (fightIssue != FightIssue.Draw && CheckForAWinner()) { EndOfTheGame(); } } // Move the unit (decrease its movement points but does not move it on the map) unit.Move(Map.Tiles[origin], Map.Tiles[destination], Map.AreAdjacent(origin, destination)); // Move the unit (physically on the map) if (executeMovement) { CurrentPlayer.MoveUnit(unit, origin, destination); if (!CurrentPlayer.HasUnitsOn(origin)) { Map.PlayerReleasesTile(CurrentPlayer, origin); } Map.PlayerControlsTile(CurrentPlayer, destination); } return true; } return false; }
public bool RemoveUnit(Unit unit, Point tile) { if (Units.ContainsKey(tile) && Units[tile].Contains(unit)) { Units[tile].Remove(unit); if (Units[tile].Count == 0) { Units.Remove(tile); } return true; } return false; }
public void MoveUnit(Unit unit, Point origin, Point destination) { if (RemoveUnit(unit, origin)) { AddUnit(unit, destination); } }
public bool IsReachableTile(Unit unit, Point origin, Point destination) { return unit.CanMove(Tiles[origin], Tiles[destination], AreAdjacent(origin, destination)); }
public Dictionary<Point, Dictionary<Point, double>> GetRoadmap(Unit unit) { var roadmap = new Dictionary<Point, Dictionary<Point, double>>(); foreach (var tile in Tiles) { var origin = tile.Key; var reachableTiles = GetReachableTiles(unit, origin); roadmap.Add(origin, new Dictionary<Point, double>()); foreach(var destination in reachableTiles) { var cost = unit.GetMovementCost(Tiles[origin], Tiles[destination]); roadmap[origin].Add(destination, cost); } } return roadmap; }
public List<Point> GetReachableTiles(Unit unit, Point origin) { var reachableTiles = new List<Point>(); foreach (var tile in Tiles) { var destination = tile.Key; if (IsReachableTile(unit, origin, destination)) { reachableTiles.Add(destination); } } return reachableTiles; }
protected override Point SelectDestination(Unit unit, Point origin, List<Point> destinations) { return destinations[randomizer.Next(destinations.Count())]; }
protected abstract Point SelectDestination(Unit unit, Point origin, List<Point> destinations);
private void SelectUnit(Unit unit) { if (!Game.CurrentPlayer.IsAI() && SelectedTile != null) { var unitsOnSelectedTile = Game.CurrentPlayer.GetUnits()[SelectedTile]; if (unitsOnSelectedTile.Contains(unit)) { SelectedUnit = unit; } } }