コード例 #1
0
 private void MoveTowards(Position targetPosition)
 {
     if (currentPath == null || currentPath.Count == 0 ||
         !targetPosition.Equals(currentTargetPosition) || !CanMove(currentPath.First()) ||
         (position.Distance(targetPosition) % 11 == 0)) // Every 11 steps make sure that a new best path hasn't magically appeared
     {
         // Try to create a path if the current one is invalid
         currentPath           = Pathfinder.FindPath(engine, this, engine.map.GetTileAt(position), engine.map.GetTileAt(targetPosition));
         currentTargetPosition = targetPosition;
         // Remove the first element because we are already there
         if (currentPath != null)
         {
             currentPath.RemoveAt(0);
         }
     }
     if (currentPath != null && currentPath.Count > 0 && currentTargetPosition.Equals(targetPosition) && CanMove(currentPath.First()))
     {
         Position nextStep = currentPath.First();
         currentPath.RemoveAt(0);
         TryToMove(nextStep);
     }
     else
     {
         status = Status.Idle;
         // Retry after moveRetryCooldown ticks
         engine.ScheduleUpdate(moveRetryCooldown, this);
     }
 }
コード例 #2
0
            public int GetDistanceFrom(Position position)
            {
                // Calculate point nearest to startPosition inside this chunk
                Position nearestPosition = new Position(Math.Max(topLeft.x, Math.Min(bottomRight.x, position.x)),
                                                        Math.Max(topLeft.y, Math.Min(bottomRight.y, position.y)));

                // Return distance
                return(nearestPosition.Distance(position));
            }
コード例 #3
0
        // Kinda private methods

        public void MoveUnit(Unit unit, Position targetPosition)
        {
            Debug.Assert(targetPosition.Distance(unit.position) == 1);
            Debug.Assert(unitGrid[targetPosition.x, targetPosition.y] == null);

            CacheRemoveUnitAt(unit.position);
            unit.previousPosition   = unit.position;
            unit.position           = targetPosition;
            unit.animationStartTick = currentTick;
            CacheSetUnitAt(unit);
        }
コード例 #4
0
        public Unit NearestUnitTo(Unit startUnit, int maxDistance, Position startPosition = null)
        {
            if (startPosition == null)
            {
                startPosition = startUnit.position;
            }
            if (!Inside(startPosition))
            {
                var nearestPosition = new Position(Math.Max(0, Math.Min(startPosition.x, width - 1)),
                                                   Math.Max(0, Math.Min(startPosition.y, height - 1)));
                maxDistance  -= nearestPosition.Distance(startPosition);
                startPosition = nearestPosition;
            }

            Chunk chunk = GetChunk(startPosition);

            // Breadth first search
            HashSet <Chunk> haveBeenInFrontier = new HashSet <Chunk> {
                chunk
            };
            LinkedList <Chunk> frontier = new LinkedList <Chunk>(haveBeenInFrontier);

            while (frontier.Count > 0)
            {
                var top = frontier.First();
                frontier.RemoveFirst();
                // Try to find nearest in this chunk
                Unit closestUnit     = null;
                int  nearestDistance = Int32.MaxValue;
                foreach (var unit in top.units)
                {
                    int distance = startPosition.Distance(unit.position);
                    if (distance <= nearestDistance && unit != startUnit)
                    {
                        nearestDistance = distance;
                        closestUnit     = unit;
                    }
                }
                if (closestUnit != null && nearestDistance <= maxDistance)
                {
                    return(closestUnit);
                }
                // if a unit has not been found yet, try the neighbors
                foreach (var neighbor in top.neighbors)
                {
                    if (!haveBeenInFrontier.Contains(neighbor) && neighbor.GetDistanceFrom(startPosition) <= maxDistance)
                    {
                        frontier.AddLast(neighbor);
                        haveBeenInFrontier.Add(neighbor);
                    }
                }
            }
            return(null); // Didn't find a unit within maxDistance
        }
コード例 #5
0
        //The engine can call this to tell the AI to issue upto numMoves orders. This allows the AI to scale how much it is doing
        public void makeMoves(int numMoves)
        {
            int peasentCount = 0, knightCount = 0, archerCount = 0, mineCount = 0, townCount = 0, attackingCount = 0;

            foreach (Unit u in engine.units)
            {
                if (u.owner != me)
                {
                    continue;
                }
                if (u.type.Equals(engine.unitTypes[2]))
                {
                    peasentCount++;
                }
                if (u.type.Equals(engine.unitTypes[0]))
                {
                    knightCount++;
                    if (u.orders.Count > 0 && u.orders[0].orderType.Equals(Order.OrderType.Attack))
                    {
                        attackingCount++;
                    }
                }
                if (u.type.Equals(engine.unitTypes[1]))
                {
                    archerCount++;
                    if (u.orders.Count > 0 && u.orders[0].orderType.Equals(Order.OrderType.Attack))
                    {
                        attackingCount++;
                    }
                }
                if (u.type.Equals(engine.unitTypes[4]))
                {
                    mineCount++;
                }
                if (u.type.Equals(engine.unitTypes[3]))
                {
                    townCount++;
                }
            }
            //generic loop to determine what the AI does
            for (int i = 0; i < numMoves; i++)
            {
                //Currently we want to be able to gather
                Unit currentUnit = null;
                foreach (Unit u in engine.units)
                {
                    if (u.owner == me)
                    {
                        if (u.CanAttack() && !u.CanGather() && !u.CanProduce())
                        {
                            if (u.orders.Count != 0)
                            {
                                continue;
                            }
                            Position p             = null;
                            int      distance      = 100000000;
                            Unit     closestTarget = null;
                            foreach (Unit target in engine.units)
                            {
                                if (target.owner != me)
                                {
                                    if (target.position.Distance(u.position) < distance)
                                    {
                                        distance      = target.position.Distance(u.position);
                                        closestTarget = target;
                                        p             = target.position;
                                    }
                                }
                            }
                            if (p != null)
                            {
                                engine.OrderAttack(u, closestTarget);
                                break;
                            }
                        }
                        if (u.CanProduce() && !u.CanGather() && archerCount + knightCount <= attackingCount)
                        {
                            int unit_to_produce = -1;
                            if (peasentCount == 0)
                            {
                                unit_to_produce = 2;
                            }
                            else if (knightCount < archerCount)
                            {
                                unit_to_produce = 0;
                            }
                            else
                            {
                                unit_to_produce = 1;
                            }
                            if (unit_to_produce >= 0)
                            {
                                engine.OrderProduce(u, engine.unitTypes[unit_to_produce]);
                                break;
                            }
                        }
                        if (townCount < 5 && me.gold >= engine.unitTypes[3].goldCost && u.CanBuild())   //Can build a town, build it
                        {
                            if (u.orders.Count == 0)
                            {
                                engine.OrderProduce(u, engine.unitTypes[3]);
                            }
                        }
                        if (u.CanMove() && u.CanBuild() && me.gold >= engine.unitTypes[4].goldCost && mineCount < 5) //make mines
                        {
                            if (u.orders.Count == 0 || u.orders[0].orderType.Equals(Order.OrderType.Gather))         //if the unit is not doing anything
                            {
                                currentUnit = u;
                                if (u.orders.Count != 0 && u.orders[0].orderType.Equals(Order.OrderType.Gather) && goldTiles.Contains(u.position))
                                {
                                    u.orders.Clear();
                                    engine.OrderMove(u, u.position + new Position(0, 1));
                                    engine.OrderProduce(u, engine.unitTypes[4], u.position);
                                    break;
                                }
                                //find closest open goldtile and issue order for that
                                Position closestGold  = goldTiles[0];
                                Position unitPosition = currentUnit.position;
                                int      distance     = unitPosition.Distance(closestGold);
                                foreach (Position p in goldTiles)
                                {
                                    if (engine.GetUnitAt(p) == null)  //no one is on the tile
                                    {
                                        if (unitPosition.Distance(p) < distance)
                                        {
                                            distance    = unitPosition.Distance(p);
                                            closestGold = p;
                                        }
                                    }
                                }
                                engine.OrderProduce(currentUnit, engine.unitTypes[4], closestGold);
                                break;
                            }
                        }
                        else if (u.CanMove() && u.CanGather() && me.gold < 1000)
                        {
                            if (u.orders.Count == 0 /* || u.orders[0].orderType.Equals(Order.OrderType.Move) */) //if the unit is not doing anything
                            {
                                currentUnit = u;
                                if (currentUnit == null)
                                {
                                    return; //I have no units
                                }
                                if (goldTiles.Contains(currentUnit.position))
                                {
                                    continue;
                                }
                                //find closest open goldtile and issue order for that
                                Position closestGold  = goldTiles[0];
                                Position unitPosition = currentUnit.position;
                                int      distance     = unitPosition.Distance(closestGold);
                                foreach (Position p in goldTiles)
                                {
                                    if (engine.GetUnitAt(p) == null) //no one is on the tile
                                    {
                                        bool alreadyTargeted = false;
                                        foreach (Unit blocker in engine.units)
                                        {
                                            if (blocker.orders.Count > 0 &&
                                                blocker.orders[0].orderType.Equals(Order.OrderType.Gather) &&
                                                blocker.orders[0].targetPosition.Equals(p))
                                            {
                                                alreadyTargeted = true;
                                                break;
                                            }
                                        }
                                        if (alreadyTargeted)
                                        {
                                            continue;
                                        }
                                        if (unitPosition.Distance(p) < distance)
                                        {
                                            distance    = unitPosition.Distance(p);
                                            closestGold = p;
                                        }
                                    }
                                }
                                if (distance != 0)
                                {
                                    engine.OrderGather(currentUnit, closestGold);
                                    break;
                                }
                            }
                        }
                    }
                }
            }
        }
コード例 #6
0
        // Kinda private methods
        public void MoveUnit(Unit unit, Position targetPosition)
        {
            Debug.Assert(targetPosition.Distance(unit.position) == 1);
            Debug.Assert(unitGrid[targetPosition.x, targetPosition.y] == null);

            CacheRemoveUnitAt(unit.position);
            unit.previousPosition = unit.position;
            unit.position = targetPosition;
            unit.animationStartTick = currentTick;
            CacheSetUnitAt(unit);
        }
コード例 #7
0
        public Unit NearestUnitTo(Unit startUnit, int maxDistance, Position startPosition=null)
        {
            if (startPosition == null)
            {
                startPosition = startUnit.position;
            }
            if (!Inside(startPosition))
            {
                var nearestPosition = new Position(Math.Max(0, Math.Min(startPosition.x, width - 1)),
                    Math.Max(0, Math.Min(startPosition.y, height - 1)));
                maxDistance -= nearestPosition.Distance(startPosition);
                startPosition = nearestPosition;
            }

            Chunk chunk = GetChunk(startPosition);

            // Breadth first search
            HashSet<Chunk> haveBeenInFrontier = new HashSet<Chunk> {chunk};
            LinkedList<Chunk> frontier = new LinkedList<Chunk>(haveBeenInFrontier);
            while (frontier.Count > 0)
            {
                var top = frontier.First();
                frontier.RemoveFirst();
                // Try to find nearest in this chunk
                Unit closestUnit = null;
                int nearestDistance = Int32.MaxValue;
                foreach (var unit in top.units)
                {
                    int distance = startPosition.Distance(unit.position);
                    if (distance <= nearestDistance && unit != startUnit)
                    {
                        nearestDistance = distance;
                        closestUnit = unit;
                    }
                }
                if (closestUnit != null && nearestDistance <= maxDistance)
                {
                    return closestUnit;
                }
                // if a unit has not been found yet, try the neighbors
                foreach (var neighbor in top.neighbors)
                {
                    if (!haveBeenInFrontier.Contains(neighbor) && neighbor.GetDistanceFrom(startPosition) <= maxDistance)
                    {
                        frontier.AddLast(neighbor);
                        haveBeenInFrontier.Add(neighbor);
                    }
                }
            }
            return null; // Didn't find a unit within maxDistance
        }
コード例 #8
0
 public int GetDistanceFrom(Position position)
 {
     // Calculate point nearest to startPosition inside this chunk
     Position nearestPosition = new Position(Math.Max(topLeft.x, Math.Min(bottomRight.x, position.x)),
         Math.Max(topLeft.y, Math.Min(bottomRight.y, position.y)));
     // Return distance
     return nearestPosition.Distance(position);
 }