Beispiel #1
0
        //////////Methods//////////

        /// <summary>
        /// Creates a new map of the game
        /// </summary>
        public Map(IPirateGame game)
        {
            // updates map constants
            this.Rows         = game.GetRows();
            this.Collumns     = game.GetCols();
            this.AttackRadius = Utils.Sqrt(game.GetAttackRadius());

            // set the computing limits
            this.IsBig = this.Rows > 40 || this.Collumns > 40;

            // create the pirate managers
            this.MyPirateManager    = new PirateManager(game, Owner.Me);
            this.MyAttackMap        = new AttackMap(this, this.MyPirateManager.GetAllPirates());
            this.EnemyPirateManager = new PirateManager(game, Owner.Enemy);
            this.EnemyAttackMap     = new AttackMap(this, this.EnemyPirateManager.GetAllPirates());

            // create the sail manager
            this.SailManager = new SailManager(game, this);

            // create the update proxy
            this.updateProxy = new UpdateProxy <IPirateGame>();
            this.updateProxy.Add(this.MyPirateManager);
            this.updateProxy.Add(this.EnemyPirateManager);
            this.updateProxy.Add(this.SailManager);


            // initialize the neighbors matrix
            this.neighbors = new List <Location> [this.Rows, this.Collumns, (2 * game.GetActionsPerTurn()) + 1];
            // calculate the neighbors for each location in map
            for (int row = 0; row < this.Rows; row++)
            {
                for (int collumn = 0; collumn < this.Collumns; collumn++)
                {
                    // assign neighbors of distance 0 ;)
                    this.neighbors[row, collumn, 0] = new List <Location>();
                    this.neighbors[row, collumn, 0].Add(new Location(row, collumn));

                    // for each distance from 1 to max
                    for (int distance = 1; distance < this.neighbors.GetLength(2); distance++)
                    {
                        this.neighbors[row, collumn, distance] = new List <Location>();
                        // add all the neighbors in a windmill-like shape
                        for (int i = 0; i < distance; i++)
                        {
                            // all four quarters, were the row delta is i
                            this.neighbors[row, collumn, distance].Add(new Location(row + i, collumn + (distance - i)));
                            this.neighbors[row, collumn, distance].Add(new Location(row - i, collumn - (distance - i)));
                            this.neighbors[row, collumn, distance].Add(new Location(row - (distance - i), collumn + i));
                            this.neighbors[row, collumn, distance].Add(new Location(row + (distance - i), collumn - i));
                        }
                        // remove neighbors which are not in the map
                        this.neighbors[row, collumn, distance].RemoveAll(loc => !this.InMap(loc));
                    }
                }
            }


            // the list of availible treasures
            List <Pirates.Treasure> allTreasures = game.Treasures();

            // initialize the lists containing the treasures by states
            this.treasuresByStates = new List <Treasure> [(int)TreasureState.COUNT];
            for (int i = 0; i < this.treasuresByStates.Length; i++)
            {
                this.treasuresByStates[i] = new List <Treasure>();
            }

            // initialize the allTreasures array and the treasuresSpawnOnMap dictionary
            this.allTreasures        = new Treasure[allTreasures.Count];
            this.treasuresSpawnOnMap = new Dictionary <Location, Treasure>();

            // initialize all the treasures in the allTreasures array, and add them to freeToTakeTreasures and to treasuresSpawnOnMap
            foreach (Pirates.Treasure t in allTreasures)
            {
                Treasure newTreasure = new Treasure(t);
                newTreasure.NativeObject = t;
                this.allTreasures[t.Id]  = newTreasure;
                this.treasuresByStates[(int)TreasureState.FreeToTake].Add(newTreasure);
                this.treasuresSpawnOnMap.Add(newTreasure.InitialLocation, newTreasure);
            }

            // initialize the piratesSpawnOnMap dictionary
            this.piratesSpawnOnMap = new Dictionary <Location, Pirate>();
            foreach (Pirate p in this.MyPirateManager.GetAllPirates())
            {
                this.piratesSpawnOnMap.Add(p.InitialLocation, p);
            }
            foreach (Pirate p in this.EnemyPirateManager.GetAllPirates())
            {
                this.piratesSpawnOnMap.Add(p.InitialLocation, p);
            }

            // initialize the map dictionaries, and update them
            this.piratesOnMap = new Dictionary <Location, Pirate>();
            this.updatePiratesMapDictionary();
            this.treasuresOnMap = new ListsDictionary <Location, Treasure>();
            this.updateTreasuresMapDictionary();

            // initialize the powerups list
            this.powerups = new List <Powerup>();
            this.repopulatePowerups(game.Powerups(), game.GetTurn());

            // initialize treasuresSpawnClusters
            this.treasuresSpawnClusers = Cluster.Clusterify <Treasure>(this.allTreasures, this.AttackRadius);

            // initialize the value being carried
            this.myCarriedValue    = 0;
            this.enemyCarriedValue = 0;
        }
Beispiel #2
0
        /// <summary>
        /// Returns a list of possible immediate destinations for the sail and the calculated distance to the destination,
        ///     that uses every number of moves satisfing minMoves &lt;= moves &lt;= maxMoves
        /// </summary>
        /// <param name="from">The start location</param>
        /// <param name="to">The destination</param>
        /// <param name="minToDistance">The minimum distance from the destination, which is OK to get to</param>
        /// <param name="maxToDistance">The maximum distance from the destination, which is OK to get to</param>
        /// <param name="maxDistancePerTurn">the maximum amount of distance a pirate can travel in a turn</param>
        /// <param name="dontStayInRange">should you avoid staying in the attack range of an enemy pirate</param>
        /// <param name="minMoves">The minimum number of moves to use</param>
        /// <param name="maxMoves">The maximum number of moves to use (or less, if the destination is in reach from the start location)</param>
        /// <param name="maxResultsForMovesNum">The maximum number of results to include, for each number of moves being checked</param>
        /// <param name="disallowedTerrain">the list of disallowed terrain to NOT walk on</param>
        /// <returns>A list of possible immediate destinations for the sail and their calculated distance to the destination</returns>
        public List <KeyValuePair <Location, int> > GetCompleteSailOptions(ILocateable from, ILocateable to, int minToDistance, int maxToDistance, int maxDistancePerTurn, bool dontStayInRange, int minMoves, int maxMoves, int maxResultsForMovesNum, params Terrain[] disallowedTerrain)
        {
            // sanity check
            if (from == null || from.GetLocation() == null || !this.map.InMap(from) ||
                to == null || to.GetLocation() == null || !this.map.InMap(to))
            {
                return(new List <KeyValuePair <Location, int> >());
            }

            // the attack map of the enemy
            AttackMap enemyAttackMap = this.map.EnemyAttackMap;

            // do the location stays in attack range
            System.Predicate <Location> staysInAttackRange =
                loc => enemyAttackMap.GetDangerousPiratesInAttackRange(loc).Intersect(
                    enemyAttackMap.GetDangerousPiratesInAttackRange(from)).Count() > 0;

            // use at most "distance" moves to reach destination
            int distance = Map.ManhattanDistance(from, to);

            if (distance < maxMoves)
            {
                maxMoves = distance;
            }

            // get all the possible results
            List <Location> possibleResults = new List <Location>();

            for (int moves = minMoves; moves <= maxMoves; moves++)
            {
                possibleResults.AddRange(this.map.GetNeighbors(from, moves));
            }
            // remove the results that stay in attack range if needed
            if (dontStayInRange)
            {
                possibleResults.RemoveAll(staysInAttackRange);
            }

            // get all the possible final destinations
            List <Location> finalDestinations = new List <Location>();

            for (int radius = minToDistance; radius <= maxToDistance; radius++)
            {
                finalDestinations.AddRange(this.map.GetNeighbors(to, radius));
            }

            // update A* algorithm
            this.Update_AStar(finalDestinations, possibleResults, maxDistancePerTurn, disallowedTerrain);

            // calculate the results
            List <KeyValuePair <Location, int> > results = new List <KeyValuePair <Location, int> >();

            // for each possible "moves" value
            for (int moves = minMoves; moves <= maxMoves; moves++)
            {
                // choose only best results
                possibleResults.Clear();
                possibleResults.AddRange(this.map.GetNeighbors(from, moves));
                // remove the results that stay in attack range if needed
                if (dontStayInRange)
                {
                    possibleResults.RemoveAll(staysInAttackRange);
                }
                possibleResults.Shuffle();                                                      // shuffle the neighbors, so that two neighbors with the same gScore will be randomly ordered
                possibleResults = possibleResults.OrderBy(loc => this.getGScore(loc)).ToList(); // sort by gScore
                for (int i = 0; i < possibleResults.Count && i < maxResultsForMovesNum; i++)
                {
                    if (this.getGScore(possibleResults[i]) >= this.aStar_gScore.Length) // if the value is "infinity"
                    {
                        break;
                    }
                    // add the result, and its distance to the destination
                    results.Add(new KeyValuePair <Location, int>(possibleResults[i], this.getGScore(possibleResults[i])));
                }
            }
            return(results);
        }