public static int pathCounter = int.MinValue + 1; // Incremented after every check

        #endregion Fields

        #region Methods

        // Yay C# has generators!
        /// <summary>
        /// A generator that produces positions by doing a breadth first iteration of tiles starting at a given position.
        /// </summary>
        /// <param name="engine">An engine object to get tiles from</param>
        /// <param name="position">The starting position.</param>
        /// <param name="distance">The maximum distance from the starting position.  Or negative for no limit.</param>
        /// <param name="size">The maximum number of tiles traversed.  Or negative for no limit.</param>
        public static IEnumerable<Position> BreadthFirst(Engine engine, Position position, int distance = -1, int size = -1)
        {
            // Reset ONE tile's pathIndex on the map to the minimum value to prevent integer rollover
            int index = pathCounter < 0 ? -pathCounter : pathCounter;
            engine.map.tiles[index % engine.map.width, (index / engine.map.width)%engine.map.height].pathIndex = int.MinValue;

            int localPathCounter = pathCounter++;
            LinkedList<Tile> perimeter = new LinkedList<Tile>();
            perimeter.AddLast(engine.map.GetTileNearestTo(position));
            perimeter.Last.Value.pathDistance = 0;
            while (size != 0 && perimeter.Count > 0)
            {
                Tile top = perimeter.First.Value;
                top.pathIndex = localPathCounter;
                perimeter.RemoveFirst();
                if (distance >= 0 && top.pathDistance > distance)
                {
                    yield break;
                }
                yield return top.position;

                foreach (var neighbor in top.neighbors)
                {
                    if (neighbor.pathIndex < localPathCounter)
                    {
                        perimeter.AddLast(neighbor);
                        neighbor.pathIndex = localPathCounter;
                        neighbor.pathDistance = top.pathDistance + 1;
                    }
                }
                size -= 1;
            }
            // This is not the place for cleanup code
        }
Beispiel #2
0
        public Map(Vector2 startingPosition, int width, int height, ref Engine engine, GraphicsDevice graphicsDevice,
            int numberOfDreadlands, int numberOfDeserts, int numberOfPlains, int numberOfMountains, int numberOfTundras,
            int numberOfForests, int numberOfOceans, int numberOfResourceNodes)
        {
            tileIndex = startingPosition;
            this.width = width;
            this.height = height;
            this.engine = engine;
            this.graphicsDevice = graphicsDevice;

            this.numberOfDreadlands = numberOfDreadlands;
            this.numberOfDeserts = numberOfDeserts;
            this.numberOfPlains = numberOfPlains;
            this.numberOfMountains = numberOfMountains;
            this.numberOfTundras = numberOfTundras;
            this.numberOfForests = numberOfForests;
            this.numberOfOceans = numberOfOceans;
            this.numberOfResourceNodes = numberOfResourceNodes;

            // Generate map
            charmap = Generator.generate(width, height, numberOfDreadlands, numberOfDeserts, numberOfPlains, numberOfMountains, numberOfTundras, numberOfForests, numberOfOceans, numberOfResourceNodes);
            engine.map.UpdateTilesFromCharmap(charmap);

            // Generate map cache
            xCaches = (int) Math.Ceiling(width/214.0);
            yCaches = (int) Math.Ceiling(height/214.0);
            mapCaches = new RenderTarget2D[xCaches, yCaches];
            for (int y = 0; y < yCaches; ++y)
            {
                for (int x = 0; x < xCaches; ++x)
                {
                    mapCaches[x, y] = new RenderTarget2D(graphicsDevice, 214 * tilePxSize, 214 * tilePxSize);
                }
            }
        }
 public static Position FindNextStep( Engine engine, Unit unit, Tile start, Tile end )
 {
     List<Position> temp = FindPath(engine, unit, start, end);
     if (temp != null && temp.Count > 1)
         return temp[1];
     else
         return null;
 }
Beispiel #4
0
        public AI( Engine e, Player player, List<Position> g, List<Position> i, List<Position> m )
        {
            engine = e;

            me = player;

            goldTiles = g;
            ironTiles = i;
            manaTiles = m;
        }
Beispiel #5
0
        // handles context displays, selected units, resource counters,
        public Hud(ref Engine engine, ref Map map, Texture2D boxSelect, Texture2D HPbar)
        {
            this.engine = engine;
            this.map = map;
            this.boxSelect = boxSelect;
            this.HPbar = HPbar;
            this.currentPlayer = engine.players[0];

            selectedUnits = new List<Unit>();
            startRect = new Vector2();
            endRect = new Vector2();

            // initialize
            m = Mouse.GetState();
            m2 = Mouse.GetState();
            lastButtonPressed = "None";
        }
        public Game1()
        {
            graphics = new GraphicsDeviceManager(this);
            Content.RootDirectory = "Content";

            engine = new Engine(width, height);
            // Create initial players
            engine.AddPlayer("Frodo", teamIndex: 0);
            engine.AddPlayer("Sauron", teamIndex: 1);
            engine.ai1.me = engine.players[1];
            engine.ai2.me = engine.players[0];

            graphics.PreferredBackBufferWidth = 1280;
            graphics.PreferredBackBufferHeight = 720;

            IsMouseVisible = true;
            //graphics.ToggleFullScreen(); // activate full screen mode. toggle with alt + enter
        }
Beispiel #7
0
        public Unit(int id, Engine engine, UnitType unitType, Position position, Player owner)
        {
            this.id = id;
            this.engine = engine;
            this.type = unitType;
            this.position = position;
            this.previousPosition = position;
            this.nextMove = -1;
            this.owner = owner;

            health = type.maxHealth;
            status = Status.Idle;
            orders = new List<Order>();
            modifiers = new List<UnitModifier>();

            animationStartTick = 0;
            direction = 0;

            currentPath = null;
            currentTargetPosition = null;
        }
        public static List<Position> FindPath( Engine engine, Unit unit, Tile start, Tile end )
        {
            List<Position> path = null;

            if (!unit.CanMove(end.position))
            {
                foreach (Position pos in BreadthFirst(engine, end.position, -1, 500))
                {
                    if (unit.CanMove(pos))
                    {
                        end = engine.map.tiles[pos.x, pos.y];
                        break;
                    }
                }
            }
            if (!unit.CanMove(end.position))
            {
                return null;
            }

            bool success = false;
            start.pathParent = null;
            start.pathDistance = 0;
            start.pathHeuristic = start.pathDistance + FValue(start, end);
            PriorityQueue<Tile> openSet = new PriorityQueue<Tile>();
            openSet.Enqueue(start);
            int count = 0;

            //generate path
            while ( openSet.Count() > 0 )
            {
                count += 1;
                Tile currentBest = openSet.Dequeue();
                currentBest.pathIndex = pathCounter;
                // if we are at the goal end
                if (currentBest.position.Equals(end.position))
                {
                    success = true;
                    break;
                }
                // Give up if we backtrack too far
                if ((currentBest.pathHeuristic >= start.pathHeuristic*14 &&
                    count > 2000) || count > 4000)
                {
                    break;
                }
                // Take current best, generate all possible nodes, push them onto queue
                foreach (var neighbor in currentBest.neighbors)
                {
                    if (!unit.CanMove(neighbor.position))
                    {
                        continue;
                    }
                    double tentativeCost = currentBest.pathDistance + neighbor.tileType.movementCost;
                    if (neighbor.pathIndex < pathCounter)
                    {
                        neighbor.pathIndex = pathCounter;
                        neighbor.pathParent = currentBest;
                        neighbor.pathDistance = tentativeCost;
                        neighbor.pathHeuristic = neighbor.pathDistance + FValue(neighbor, end);
                        openSet.Enqueue(neighbor);
                    }
                    else if (tentativeCost < neighbor.pathDistance)
                    {
                        // Update costs if the current path is better than the existing one
                        neighbor.pathParent = currentBest;
                        neighbor.pathDistance = tentativeCost;
                        neighbor.pathHeuristic = neighbor.pathDistance + FValue(neighbor, end);
                        openSet.HeapifyUp(neighbor);
                    }
                }
            }
            if ( success )
            {
                // Generate path by following parent from end to start
                path = new List<Position>();
                Tile runner = end;
                while (runner != null)
                {
                    path.Insert(0, runner.position);
                    runner = runner.pathParent;
                }
            }

            pathCounter += 1;

            return path;
        }
 public static Position FindNextStep( Engine engine, Unit unit, Position start, Position end)
 {
     return FindNextStep(engine, unit, engine.map.GetTileAt(start), engine.map.GetTileAt(end));
 }
 public EngineMap(Engine engine, int width, int height)
 {
     this.engine = engine;
     this.width = width;
     this.height = height;
 }