예제 #1
0
        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);
        }
예제 #2
0
        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);
            }
        }
예제 #3
0
        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);
        }
예제 #4
0
        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);
        }