private AntDestination FindBest(Player player, List <AntDestination> possibleTiles) //, PheromoneType pheromoneType) { AntDestination moveToTile = null; float a, b; a = 0.5f; b = 0.8f; //if (pheromoneType == PheromoneType.ToHome) { a = 0.5f; b = 1.0f; } //else if (pheromoneType == PheromoneType.ToFood) { a = 0.5f; b = 0.8f; } //else { a = 0.5f; b = 0.8f; } float best_str = 0.01f; // Best pheromone strength foreach (AntDestination destination in possibleTiles) { float phem_d = 0.01f; if (destination.Pheromone != null) { phem_d = destination.Intensity; //.Pheromone.GetIntensityF(player.PlayerModel.Id, pheromoneType); } if (phem_d == 0) { phem_d = 0.01f; } float pos_d = destination.phem_d; // Formula for overall attractiveness // Alpha is pheromone intensity, and Beta is direction factor // Should have really wrote it somewhere else than source code float trail_str; trail_str = (phem_d * a) * (pos_d * b); // Compare, is it better than another directions ? if (trail_str > best_str) { // Add random factor (decision factor) to movements // For example, if ant have choses of two paths of relatively equals pheromone trail strenght // it could follow lesser strenght trail, thus "trying" another path. float a2 = trail_str; float b2 = best_str * 0.2f; // Settings::RANDOM_FACTOR; //float r = rnd(a2 + b2); int maxrnd = (int)((a2 * 100) + (b2 * 100)); double rint = player.Game.Random.Next(maxrnd); double r = rint / 100; if (r < trail_str) { best_str = trail_str; moveToTile = destination; } } } return(moveToTile); }
public void AddDestination(List <AntDestination> possibleTiles, Player player, Tile t, float phem_d, bool onlyIfMovable, PheromoneType pheromoneType) { if (t != null) { if (onlyIfMovable && !t.CanMoveTo()) { return; } AntDestination antDestination = new AntDestination(); antDestination.Tile = t; antDestination.phem_d = phem_d; if (pheromoneType != PheromoneType.None) { antDestination.Pheromone = player.Game.Pheromones.FindAt(t.Pos); if (antDestination.Pheromone == null) { return; } float intensity = antDestination.Pheromone.GetIntensityF(player.PlayerModel.Id, pheromoneType); if (pheromoneType == PheromoneType.AwayFromEnergy) { if (intensity == 1) { return; } } else { if (intensity == 0) { return; } } antDestination.Intensity = intensity; } possibleTiles.Add(antDestination); } }
public bool MoveUnit(Player player, List <Move> moves) { if (MoveAttempts > 0) { } Unit cntrlUnit = PlayerUnit.Unit; // Follow trail if possible. Position moveToPosition = null; if (FollowThisRoute != null) { if (FollowThisRoute.Count == 0) { FollowThisRoute = null; } else { moveToPosition = FollowThisRoute[0]; if (Control.IsOccupied(player, moves, moveToPosition)) { moveToPosition = null; FollowThisRoute = null; } else { FollowThisRoute.RemoveAt(0); if (FollowThisRoute.Count == 0) { FollowThisRoute = null; } } } } List <Tile> tiles = MakeForwardTilesList(player, cntrlUnit); /* * Tile tileForward = GetNextPosition(player, cntrlUnit.Pos, cntrlUnit.Direction, moves); * if (tileForward != null) tiles.Add(tileForward); * * Tile tileLeft = GetNextPosition(player, cntrlUnit.Pos, TurnLeft(cntrlUnit.Direction), moves); * if (tileLeft != null) tiles.Add(tileLeft); * * Tile tileRight = GetNextPosition(player, cntrlUnit.Pos, TurnRight(cntrlUnit.Direction), moves); * if (tileRight != null) tiles.Add(tileRight); */ PheromoneType pheromoneType = PheromoneType.AwayFromEnergy; // Minerals needed? if (cntrlUnit.Weapon != null && !cntrlUnit.Weapon.WeaponLoaded) { pheromoneType = PheromoneType.ToFood; } else if (IsWorker) { if (cntrlUnit.Container != null && cntrlUnit.Container.Metal < cntrlUnit.Container.Capacity) { // Fill up with food! pheromoneType = PheromoneType.ToFood; } else { // Look for a target to unload pheromoneType = PheromoneType.ToHome; } } else if (!IsWorker) { pheromoneType = PheromoneType.Enemy; } List <AntDestination> possibleTiles = ComputePossibleTiles(player, tiles, pheromoneType); if (possibleTiles.Count == 0 && pheromoneType == PheromoneType.ToFood) { moveToPosition = Control.FindFood(player, this); if (moveToPosition != null && Control.IsOccupied(player, moves, moveToPosition)) { moveToPosition = null; FollowThisRoute = null; } } if (IsWorker && possibleTiles.Count == 0 && pheromoneType == PheromoneType.ToHome) { moveToPosition = Control.FindContainer(player, this); if (moveToPosition != null && Control.IsOccupied(player, moves, moveToPosition)) { moveToPosition = null; FollowThisRoute = null; } } if (possibleTiles.Count == 0 && pheromoneType == PheromoneType.Enemy) { moveToPosition = Control.FindEnemy(player, this); if (moveToPosition != null && Control.IsOccupied(player, moves, moveToPosition)) { moveToPosition = null; FollowThisRoute = null; } } if (moveToPosition == null) { if (possibleTiles.Count == 0 && pheromoneType != PheromoneType.AwayFromEnergy) { // Fighter may try to move to border until food is found pheromoneType = PheromoneType.AwayFromEnergy; possibleTiles = ComputePossibleTiles(player, tiles, pheromoneType); } /* * if (possibleTiles.Count == 0 && StuckCounter > 0) * { * Tile tileHardRight; * Tile tileHardLeft; * tileHardRight = GetNextPosition(player, cntrlUnit.Pos, TurnRight(TurnRight(cntrlUnit.Direction)), moves); * AddDestination(possibleTiles, player, tileHardRight, 0.3f, true, pheromoneType); * * tileHardLeft = GetNextPosition(player, cntrlUnit.Pos, TurnLeft(TurnLeft(cntrlUnit.Direction)), moves); * AddDestination(possibleTiles, player, tileHardLeft, 0.3f, true, pheromoneType); * * tileHardLeft = GetNextPosition(player, cntrlUnit.Pos, TurnAround(cntrlUnit.Direction), moves); * AddDestination(possibleTiles, player, tileHardLeft, 0.1f, true, pheromoneType); * }*/ AntDestination moveToTile = null; while (possibleTiles.Count > 0 && moveToTile == null) { moveToTile = FindBest(player, possibleTiles); if (moveToTile == null) { break; } if (Control.IsOccupied(player, moves, moveToTile.Tile.Pos)) { possibleTiles.Remove(moveToTile); moveToTile = null; } } if (moveToTile == null) { if (pheromoneType == PheromoneType.AwayFromEnergy) { // out of reactor range moveToPosition = Control.FindReactor(player, this); if (moveToPosition != null && Control.IsOccupied(player, moves, moveToPosition)) { moveToPosition = null; FollowThisRoute = null; } else { cntrlUnit.Direction = TurnAround(cntrlUnit.Direction); return(true); } } } else { moveToPosition = moveToTile.Tile.Pos; } } /* * if (moveToTile != null && StuckCounter > 2) * { * // If it is really occupied * if (Control.IsOccupied(player, moves, moveToTile.Tile.Pos)) * { * moveToTile = null; * } * }*/ /* Does not help * if (moveToTile != null) // && ReturnHome) * { * // Wrong way check * List<AntDestination> checkPossibleTiles = new List<AntDestination>(); * AddDestination(checkPossibleTiles, player, moveToTile.Tile, 1f, true, pheromoneType); * * Tile back = GetNextPosition(player, cntrlUnit.Pos, TurnAround(cntrlUnit.Direction), moves); * AddDestination(checkPossibleTiles, player, back, 1f, true, pheromoneType); * if (checkPossibleTiles.Count == 2) * { * AntDestination isBackBetter = FindBest(player, possibleTiles, pheromoneType); * if (isBackBetter != null && isBackBetter != moveToTile) * { * moveToTile = isBackBetter; * } * } * }*/ /* * if (moveToTile == null || StuckCounter > 2) * { * // No pheromone found, move randomly * if (ReturnHome) // pheromoneType == PheromoneType.ToHome) * { * //return GoHome(player, moves, true); * GotLostNoWayHome = true; * } * else * { * // Smell Food * bool smelled = SmellFood(player, moves); * if (smelled) * { * return Move(player, moves, pheromoneType); * } * } * * possibleTiles.Clear(); * // Add tiles without pheromones * AddDestination(possibleTiles, player, tileForward, 1f, true, PheromoneType.None); * AddDestination(possibleTiles, player, tileLeft, 1f, true, PheromoneType.None); * AddDestination(possibleTiles, player, tileRight, 1f, true, PheromoneType.None); * * // Move random forward * while (moveToTile == null && possibleTiles.Count > 0) * { * int idx = player.Game.Random.Next(possibleTiles.Count); * moveToTile = possibleTiles[idx]; * * if (Control.IsOccupied(player, moves, moveToTile.Tile.Pos)) * { * possibleTiles.Remove(moveToTile); * moveToTile = null; * } * } * * if (moveToTile == null) * { * // Move random backward * possibleTiles.Clear(); * * Tile tileHardRight; * Tile tileHardLeft; * tileHardRight = GetNextPosition(player, cntrlUnit.Pos, TurnRight(TurnRight(cntrlUnit.Direction)), moves); * AddDestination(possibleTiles, player, tileHardRight, 0.3f, true, PheromoneType.None); * * tileHardLeft = GetNextPosition(player, cntrlUnit.Pos, TurnLeft(TurnLeft(cntrlUnit.Direction)), moves); * AddDestination(possibleTiles, player, tileHardLeft, 0.3f, true, PheromoneType.None); * * tileHardLeft = GetNextPosition(player, cntrlUnit.Pos, TurnAround(cntrlUnit.Direction), moves); * AddDestination(possibleTiles, player, tileHardLeft, 0.1f, true, PheromoneType.None); * * while (moveToTile == null && possibleTiles.Count > 0) * { * int idx = player.Game.Random.Next(possibleTiles.Count); * moveToTile = possibleTiles[idx]; * * if (Control.IsOccupied(player, moves, moveToTile.Tile.Pos)) * { * possibleTiles.Remove(moveToTile); * moveToTile = null; * } * } * } * } */ /* * if (moveToTile != null) * { * if (CheckHandover(moveToTile.Tile.Pos, moves)) * return true; * * // If it is really occupied * if (Control.IsOccupied(player, moves, moveToTile.Tile.Pos)) * { * moveToTile = null; * } * }*/ if (moveToPosition != null && Control.IsOccupied(player, moves, moveToPosition)) { moveToPosition = null; } Move move = null; if (moveToPosition != null) { move = new Move(); move.MoveType = MoveType.Move; move.UnitId = cntrlUnit.UnitId; move.PlayerId = player.PlayerModel.Id; move.Positions = new List <Position>(); move.Positions.Add(cntrlUnit.Pos); move.Positions.Add(moveToPosition); moves.Add(move); /* * if (dropPheromone && !NothingFound) * { * if (pheromoneType == PheromoneType.ToFood) * DropPheromone(player, PheromoneType.ToHome); * else if (pheromoneType == PheromoneType.ToHome) * DropPheromone(player, PheromoneType.ToFood); * }*/ } return(move != null); }
private bool SmellFood(Player player) { if (SmellFoodCooldown > 0) { SmellFoodCooldown--; return(false); } List <AntDestination> possibleTiles = new List <AntDestination>(); Dictionary <Position, TileWithDistance> tiles = player.Game.Map.EnumerateTiles(PlayerUnit.Unit.Pos, 3, false, matcher: tile => { Pheromone pheroHere = player.Game.Pheromones.FindAt(tile.Pos); if (tile.Metal > 0) { AddDestination(possibleTiles, player, tile.Tile, 0.6f, false, PheromoneType.None); return(true); } else if (pheroHere != null) { AddDestination(possibleTiles, player, tile.Tile, 0.2f, false, PheromoneType.ToFood); return(true); } return(false); }); AntDestination bestMetal = null; AntDestination bestPheromone = null; foreach (AntDestination antDestination in possibleTiles) { if (antDestination.Tile.Metal > 0 && (bestMetal == null || bestMetal.Tile.Metal > antDestination.Tile.Metal)) { bestMetal = antDestination; } if (antDestination.Pheromone != null && (bestPheromone == null || antDestination.Pheromone.GetIntensityF(player.PlayerModel.Id, PheromoneType.ToFood) > bestPheromone.Pheromone.GetIntensityF(player.PlayerModel.Id, PheromoneType.ToFood))) { bestPheromone = antDestination; } } // Turn ant to food if (bestMetal != null) { Direction d = TurnToPos(bestMetal.Tile.Pos); if (d != Direction.C && d != PlayerUnit.Unit.Direction) { SmellFoodCooldown = 1; PlayerUnit.Unit.Direction = d; return(true); } } else if (bestPheromone != null) { Direction d = TurnToPos(bestPheromone.Tile.Pos); if (d != Direction.C && d != PlayerUnit.Unit.Direction) { SmellFoodCooldown = 1; PlayerUnit.Unit.Direction = d; return(true); } } /* Move there leads to locks * foreach (AntDestination antDestination in possibleTiles) * { * Unit cntrlUnit = PlayerUnit.Unit; * * Move move = player.Game.MoveTo(cntrlUnit.Pos, antDestination.Tile.Pos, cntrlUnit.Engine); * if (move != null) * { * if (!Control.IsOccupied(player, moves, move.Positions[1])) * { * moves.Add(move); * DropPheromone(player, PheromoneType.ToHome); * return true; * } * } * } */ SmellFoodCooldown = 0; return(false); }