Example #1
0
        public override void AttachUnits(Dispatcher dispatcher, Player player, List <PlayerUnit> moveableUnits)
        {
            Dictionary <Position, TileWithDistance> positionsToScount = CollectIncludedPositions();
            List <PlayerUnit> unitsAlreadyInArea = CollectUnitsAlreadyInArea(player, Range);

            List <UnitType> currentDemandedUnitTypes = new List <UnitType>();

            currentDemandedUnitTypes.AddRange(DemandedUnitTypes);

            List <string> deadUnits = new List <string>();

            foreach (string unitId in AssignedUnits)
            {
                bool playerUnitFound = false;

                foreach (PlayerUnit playerUnit in player.Units.Values)
                {
                    if (playerUnit.Unit.UnitId == unitId)
                    {
                        if (!moveableUnits.Contains(playerUnit))
                        {
                            // Attached unit found, but is busy doing something else
                            // Keep unit, no request
                            foreach (UnitType unitType in DemandedUnitTypes)
                            {
                                if (unitType.Matches(playerUnit))
                                {
                                    currentDemandedUnitTypes.Remove(unitType);
                                    playerUnitFound = true;
                                    break;
                                }
                            }
                        }
                        else
                        {
                            if (playerUnit.Unit.IsComplete())
                            {
                                // Move that punk here or keep it
                                foreach (UnitType unitType in DemandedUnitTypes)
                                {
                                    if (unitType.Matches(playerUnit))
                                    {
                                        currentDemandedUnitTypes.Remove(unitType);
                                        if (playerUnit.Unit.Pos != Center && playerUnit.Unit.Engine != null)
                                        {
                                            dispatcher.MoveUnit(this, playerUnit, Center);
                                        }
                                        playerUnitFound = true;
                                        break;
                                    }
                                }
                            }
                            else
                            {
                                if (playerUnit.Unit.UnderConstruction)
                                {
                                    // Wait for completion
                                    foreach (UnitType unitType in DemandedUnitTypes)
                                    {
                                        if (unitType.Fits(playerUnit))
                                        {
                                            if (unitsAlreadyInArea.Contains(playerUnit))
                                            {
                                                // Discard connection to demaged unit.
                                                deadUnits.Add(playerUnit.Unit.UnitId);
                                            }
                                            else
                                            {
                                                // Unit in production
                                                // Request the unit again, so the factorys will produce it, but add this unit as the favourite
                                                // so only this unit will be supplied and not a new unit
                                                dispatcher.RequestUnit(this, unitType, playerUnit);
                                                playerUnitFound = true;

                                                // It not attached, the extractor will eat this unit in the factory...
                                                //deadUnits.Add(playerUnit.Unit.UnitId);
                                            }
                                            currentDemandedUnitTypes.Remove(unitType);
                                            break;
                                        }
                                    }
                                }
                            }
                        }

                        break;
                    }
                }
                if (!playerUnitFound)
                {
                    // Unit no longer exists
                    deadUnits.Add(unitId);
                }
            }

            foreach (string deadUnitId in deadUnits)
            {
                AssignedUnits.Remove(deadUnitId);
            }

            if (currentDemandedUnitTypes.Count > 0 && AssignedUnits.Count == 0)
            {
                List <UnitType> remainingUnitTypes = new List <UnitType>();
                remainingUnitTypes.AddRange(currentDemandedUnitTypes);

                foreach (PlayerUnit playerUnit in unitsAlreadyInArea)
                {
                    if (!moveableUnits.Contains(playerUnit))
                    {
                        continue;
                    }

                    bool unitMatches = false;
                    foreach (UnitType unitType in currentDemandedUnitTypes)
                    {
                        if (unitType.Matches(playerUnit))
                        {
                            remainingUnitTypes.Remove(unitType);
                            unitMatches = true;
                            break;
                        }
                    }
                    if (!unitMatches)
                    {
                        // Unmatching unit in area. Do not request another unit, wait for clear
                        remainingUnitTypes.Clear();
                    }
                }
                foreach (UnitType unitType in remainingUnitTypes)
                {
                    dispatcher.RequestUnit(this, unitType, null);
                }
            }
        }
Example #2
0
        public override void AttachUnits(Dispatcher dispatcher, Player player, List <PlayerUnit> moveableUnits)
        {
            base.AttachUnits(dispatcher, player, moveableUnits);
            if (WaitingForBuilder)
            {
                WaitForBuilder(dispatcher, moveableUnits);
            }
            else if (WaitingForDeconstrcut)
            {
                Deconstrcut(dispatcher, player, moveableUnits);
            }
            else
            {
                SanityCheck(dispatcher, player, moveableUnits);

                HandlyUnitsToExtract(dispatcher, player, moveableUnits);
            }
#if old
            UnitsAlreadyInArea = CollectUnitsAlreadyInArea(player, Range);

            currentDemandedUnitTypes = new List <UnitType>();
            currentDemandedUnitTypes.AddRange(DemandedUnitTypes);

            List <string> deadUnits = new List <string>();

            foreach (string unitId in AssignedUnits)
            {
                bool playerUnitFound = false;

                foreach (PlayerUnit playerUnit in player.Units.Values)
                {
                    if (playerUnit.Unit.UnitId == unitId)
                    {
                        if (!moveableUnits.Contains(playerUnit))
                        {
                            // Attached unit found, but is busy doing something else
                            // Keep unit, no request
                            foreach (UnitType unitType in DemandedUnitTypes)
                            {
                                if (unitType.Matches(playerUnit))
                                {
                                    currentDemandedUnitTypes.Remove(unitType);
                                    break;
                                }
                            }
                        }
                        else
                        {
                            if (playerUnit.Unit.IsComplete())
                            {
                                // Move that punk here or keep it
                                foreach (UnitType unitType in DemandedUnitTypes)
                                {
                                    if (unitType.Matches(playerUnit))
                                    {
                                        //dispatcher.ClaimUnit(this, playerUnit, RequestType.Attack);
                                        currentDemandedUnitTypes.Remove(unitType);
                                        if (playerUnit.Unit.Pos != Center && playerUnit.Unit.Engine != null)
                                        {
                                            dispatcher.MoveUnit(this, playerUnit, Center);
                                        }
                                        break;
                                    }
                                }
                            }
                            else
                            {
                                // Wait for completion
                                foreach (UnitType unitType in DemandedUnitTypes)
                                {
                                    if (unitType.Fits(playerUnit))
                                    {
                                        if (this is Assemble)
                                        {
                                            if (UnitsAlreadyInArea.Contains(playerUnit))
                                            {
                                                // Units are produced
                                                int x = 0;
                                            }
                                            else
                                            {
                                                // called when new factory
                                                // Units are produced
                                                dispatcher.RequestUnit(this, unitType, playerUnit);
                                                currentDemandedUnitTypes.Remove(unitType);
                                            }
                                        }
                                        else
                                        {
                                            // Not called

                                            if (UnitsAlreadyInArea.Contains(playerUnit))
                                            {
                                                // Discard connection to demaged unit
                                                deadUnits.Add(playerUnit.Unit.UnitId);
                                            }
                                            else
                                            {
                                                // Unit in production
                                                // Request the unit again, so the factorys will produce it, but add this unit as the favourite
                                                // so only this unit will be supplied and not a new unit
                                                dispatcher.RequestUnit(this, unitType, playerUnit);

                                                // It not attached, the extractor will eat this unit in the factory...
                                                //deadUnits.Add(playerUnit.Unit.UnitId);
                                            }
                                            currentDemandedUnitTypes.Remove(unitType);
                                        }
                                        break;
                                    }
                                }
                            }
                        }
                        playerUnitFound = true;
                        break;
                    }
                }
                if (!playerUnitFound)
                {
                    // Unit no longer exists
                    deadUnits.Add(unitId);
                }
            }

            foreach (string deadUnitId in deadUnits)
            {
                AssignedUnits.Remove(deadUnitId);
            }

            if (currentDemandedUnitTypes.Count > 0 && AssignedUnits.Count == 0)
            {
                // called when new factory
                List <UnitType> remainingUnitTypes = new List <UnitType>();
                remainingUnitTypes.AddRange(currentDemandedUnitTypes);

                foreach (PlayerUnit playerUnit in UnitsAlreadyInArea)
                {
                    if (!moveableUnits.Contains(playerUnit))
                    {
                        continue;
                    }

                    bool unitMatches = false;
                    foreach (UnitType unitType in currentDemandedUnitTypes)
                    {
                        if (unitType.Matches(playerUnit))
                        {
                            remainingUnitTypes.Remove(unitType);
                            unitMatches = true;
                            break;
                        }
                    }
                    if (!unitMatches)
                    {
                        // Unmatching unit in area. Do not request another unit, wait for clear
                        remainingUnitTypes.Clear();
                    }
                }
                foreach (UnitType unitType in remainingUnitTypes)
                {
                    currentDemandedUnitTypes.Remove(unitType);
                    dispatcher.RequestUnit(this, unitType, null);
                }
            }

            string builderUnitId = null;
            if (WaitingForBuilder)
            {
                foreach (PlayerUnit playerUnit in UnitsAlreadyInArea)
                {
                    if (playerUnit.PossibleMoves.Count > 0)
                    {
                        continue;
                    }

                    if (playerUnit.Unit.Pos == Center)
                    {
                        if (DemandedUnitTypes[0].Fits(playerUnit))
                        {
                            // Builder arrived. Build factory
                            builderUnitId     = playerUnit.Unit.UnitId;
                            WaitingForBuilder = false;
                            DemandedUnitTypes.Clear();

                            DemandStartupUnits();
                            currentDemandedUnitTypes.Clear();
                            currentDemandedUnitTypes.AddRange(DemandedUnitTypes);
                            break;
                        }
                    }
                }
            }
            if (currentDemandedUnitTypes.Count == DemandedUnitTypes.Count)
            {
                // Nothing fits Starting condition?
                foreach (PlayerUnit playerUnit in UnitsAlreadyInArea)
                {
                    if (playerUnit.PossibleMoves.Count > 0)
                    {
                        continue;
                    }

                    if (builderUnitId == playerUnit.Unit.UnitId &&
                        playerUnit.Unit.Engine != null)
                    {
                        // Builder unit
                        List <Move> possiblemoves = new List <Move>();
                        playerUnit.Unit.Assembler.ComputePossibleMoves(possiblemoves, null, MoveFilter.Assemble);
                        if (possiblemoves.Count > 0)
                        {
                            // possiblemoves contains possible output places
                            foreach (Move possibleMove in possiblemoves)
                            {
                                if (possibleMove.UnitId == "Engine")
                                {
                                    PlayerMove playerMove = new PlayerMove(possibleMove);
                                    playerMove.NewUnitId = "RemoveEngine";
                                    playerUnit.PossibleMoves.Add(playerMove);
                                    break;
                                }
                            }
                        }
                        break;
                    }
                    if (playerUnit.Unit.Assembler != null &&
                        playerUnit.Unit.Extractor != null &&
                        playerUnit.Unit.Reactor != null)
                    {
                        List <Move> possiblemoves = new List <Move>();
                        playerUnit.Unit.Assembler.ComputePossibleMoves(possiblemoves, null, MoveFilter.Assemble);
                        if (possiblemoves.Count > 0)
                        {
                            // possiblemoves contains possible output places
                            foreach (Move possibleMove in possiblemoves)
                            {
                                if (possibleMove.UnitId == "Reactor")
                                {
                                    PlayerMove playerMove = new PlayerMove(possibleMove);
                                    playerMove.Command   = this;
                                    playerMove.NewUnitId = "RemoveReactor";
                                    playerUnit.PossibleMoves.Add(playerMove);
                                    break;
                                }
                            }
                        }
                        break;
                    }

                    if (playerUnit.PossibleMoves.Count == 0 &&
                        playerUnit.Unit.Assembler != null &&
                        playerUnit.Unit.Extractor != null &&
                        playerUnit.Unit.Container != null)
                    {
                        List <Move> possiblemoves = new List <Move>();
                        playerUnit.Unit.Assembler.ComputePossibleMoves(possiblemoves, null, MoveFilter.Assemble);
                        if (possiblemoves.Count > 0)
                        {
                            // possiblemoves contains possible output places
                            foreach (Move possibleMove in possiblemoves)
                            {
                                if (possibleMove.UnitId == "Container")
                                {
                                    PlayerMove playerMove = new PlayerMove(possibleMove);
                                    playerMove.Command   = this;
                                    playerMove.NewUnitId = "RemoveContainer";
                                    playerUnit.PossibleMoves.Add(playerMove);
                                    break;
                                }
                            }
                        }
                        break;
                    }
                    if (playerUnit.PossibleMoves.Count > 0)
                    {
                        break;
                    }
                }
            }

            PlayerUnit assemblerUnit = null;

            // units are missing or demaged, try to recover
            if (currentDemandedUnitTypes.Count > 0)
            {
                // Find a unit to produce
                foreach (PlayerUnit unit in UnitsAlreadyInArea)
                {
                    if (unit.Unit.Assembler != null && unit.Unit.Assembler.CanProduce)
                    {
                        // produce missing part
                        assemblerUnit = unit;
                        break;
                    }
                }
            }

            // Step 1: Doing Upgrades (used when building itself)
            if (assemblerUnit != null && assemblerUnit.PossibleMoves.Count == 0)
            {
                List <Move> possiblemoves = new List <Move>();
                assemblerUnit.Unit.Assembler.ComputePossibleMoves(possiblemoves, null, MoveFilter.Upgrade);

                // check what is missing
                bool found = false;
                foreach (UnitType unitType in currentDemandedUnitTypes)
                {
                    foreach (PlayerUnit playerUnit in UnitsAlreadyInArea)
                    {
                        if (unitType.Fits(playerUnit))
                        {
                            foreach (Move move in possiblemoves)
                            {
                                if (move.Positions[1] != playerUnit.Unit.Pos)
                                {
                                    continue;
                                }

                                // Will this move upgrade the unit so it fits into the unittype wanted
                                if (Assembler.DoesMoveMinRequest(move, unitType, playerUnit.Unit))
                                {
                                    assemblerUnit.PossibleMoves.Add(new PlayerMove(move));
                                    currentDemandedUnitTypes.Remove(unitType);
                                    found = true;
                                    break;
                                }
                            }
                        }
                    }
                    if (found)
                    {
                        break;
                    }
                }
            }

            // Step 2: Create new units
            if (assemblerUnit != null && assemblerUnit.PossibleMoves.Count == 0)
            {
                // not called
                List <Move> possibleAssemblemoves = new List <Move>();
                assemblerUnit.Unit.Assembler.ComputePossibleMoves(possibleAssemblemoves, null, MoveFilter.Assemble);

                // check what is missing
                bool found = false;
                foreach (UnitType unitType in currentDemandedUnitTypes)
                {
                    foreach (Move move in possibleAssemblemoves)
                    {
                        //if (IsOccupied(player, moves, move.Positions[move.Positions.Count - 1]))
                        //    continue;

                        if (Assembler.DoesMoveMinRequest(move, unitType, null))
                        {
                            PlayerMove playerMove = new PlayerMove(move);
                            playerMove.Command   = this;
                            playerMove.NewUnitId = move.UnitId;

                            assemblerUnit.PossibleMoves.Add(playerMove);
                            currentDemandedUnitTypes.Remove(unitType);
                            found = true;
                            break;
                        }
                    }
                    if (found)
                    {
                        break;
                    }
                }
            }

            // Keep request
            if (assemblerUnit != null && assemblerUnit.PossibleMoves.Count == 0)
            {
                // not called

                // Still remaining demands?
                foreach (UnitType unitType in currentDemandedUnitTypes)
                {
                    if (unitType.MinRadarLevel >= 1)
                    {
                        dispatcher.RequestUnit(this, unitType, null);
                    }
                }
            }
#endif
        }
Example #3
0
        public override void AttachUnits(Dispatcher dispatcher, Player player, List <PlayerUnit> moveableUnits)
        {
            base.AttachUnits(dispatcher, player, moveableUnits);

            List <string> deadUnits = new List <string>();

            foreach (string unitId in AssignedUnits)
            {
                bool playerUnitFound = false;
                foreach (PlayerUnit playerUnit in player.Units.Values)
                {
                    if (playerUnit.Unit.UnitId == unitId)
                    {
                        if (playerUnit.PossibleMoves.Count > 0)
                        {
                            playerUnitFound = true;
                            break;
                        }

                        if (!moveableUnits.Contains(playerUnit))
                        {
                            // Attached unit found, but is busy doing something else
                            // Keep unit, no request
                            foreach (UnitType unitType in DemandedUnitTypes)
                            {
                                if (unitType.Matches(playerUnit))
                                {
                                    currentDemandedUnitTypes.Remove(unitType);
                                    break;
                                }
                            }
                        }
                        else
                        {
                            if (playerUnit.Unit.IsComplete())
                            {
                                if (playerUnit.Unit.Extractor.CanExtract)
                                {
                                    TileWithDistance nextTile = null;
                                    if (nextTile == null || nextTile.Metal == 0)
                                    {
                                        // Move that punk to metal
                                        Dictionary <Position, TileWithDistance> tiles = Map.EnumerateTiles(Center, Range, true, matcher: tile =>
                                        {
                                            if (!this.PosititionsInArea.ContainsKey(tile.Pos))
                                            {
                                                return(false);
                                            }

                                            if (tile.Pos != playerUnit.Unit.Pos)
                                            {
                                                // Extract from others, not the extractor
                                                if (tile.Unit != null)
                                                {
                                                    if (tile.Unit.Owner.PlayerModel.Id != playerUnit.Unit.Owner.PlayerModel.Id)
                                                    {
                                                        // Extract from eneny? Why not.
                                                        return(true);
                                                    }
                                                    else
                                                    {
                                                        if (tile.Unit.ExtractMe)
                                                        {
                                                            return(true);
                                                        }
                                                        else
                                                        {
                                                            return(false);
                                                        }
                                                    }
                                                }
                                            }
                                            return(tile.Metal > 0);
                                        });

                                        nextTile = null;
                                        if (tiles.Count > 0)
                                        {
                                            foreach (TileWithDistance possibleTile in tiles.Values)
                                            {
                                                if (possibleTile.Tile.CanMoveTo()) // && */possibleTile.Unit == null)
                                                {
                                                    nextTile = possibleTile;
                                                    break;
                                                }
                                                else
                                                {
                                                    // If cannot move on tile, move next to it
                                                    foreach (Tile tx in possibleTile.Neighbors)
                                                    {
                                                        if (tx.CanMoveTo())
                                                        {
                                                            nextTile = new TileWithDistance(tx, 0);
                                                            break;
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    }
                                    if (nextTile != null)
                                    {
                                        playerUnit.Unit.ExtractMe         = false;
                                        UnitReachedCommandDoNotFollowPath = true;
                                        if (nextTile.Pos != playerUnit.Unit.Pos)
                                        {
                                            dispatcher.MoveUnit(this, playerUnit, nextTile.Pos);
                                        }

                                        playerUnitFound = true;
                                    }
                                    else
                                    {
                                        // Release container. No more metal to collect. The stray collector should catch this
                                        playerUnit.Unit.ExtractMe = true;
                                        nomoreMetalFound          = true;

                                        foreach (CommandSource commandSource in CommandSources)
                                        {
                                            // Assign it to the source. The source will take care of extraction
                                            commandSource.Parent.AssignUnit(playerUnit.Unit.UnitId);
                                        }
                                    }
                                }
                                else
                                {
                                    // Container full. Release it
                                    playerUnit.Unit.ExtractMe = true;

                                    foreach (CommandSource commandSource in CommandSources)
                                    {
                                        // Assign it to the source. The source will take care of extraction
                                        commandSource.Parent.AssignUnit(playerUnit.Unit.UnitId);
                                    }
                                }
                            }
                            else
                            {
                                if (!UnitReachedCommandDoNotFollowPath)
                                {
                                    // Not arrived yet. In production?
                                    playerUnitFound = true;
                                }
                                else
                                {
                                    // Otherwise: Has arrived, was collecting and is now damaged. Unassign and mark for extraction
                                    if (!playerUnit.Unit.UnderConstruction)
                                    {
                                        playerUnit.Unit.ExtractMe = true;

                                        foreach (CommandSource commandSource in CommandSources)
                                        {
                                            // Assign it to the source. The source will take care of extraction
                                            commandSource.Parent.AssignUnit(playerUnit.Unit.UnitId);
                                        }
                                    }
                                    else
                                    {
                                        playerUnitFound = true;
                                    }
                                }
                            }
                        }
                        break;
                    }
                }
                if (!playerUnitFound)
                {
                    // Unit no longer exists
                    deadUnits.Add(unitId);
                }
            }

            foreach (string deadUnitId in deadUnits)
            {
                AssignedUnits.Remove(deadUnitId);
            }
        }
Example #4
0
        public override void AttachUnits(Dispatcher dispatcher, Player player, List <PlayerUnit> moveableUnits)
        {
            if (ScoutingPositions.Count == 0)
            {
                FindScoutingPositions(dispatcher, player);
            }

            List <Position> unseenTiles = new List <Position>();

            Dictionary <Position, TileWithDistance> positionsToScount = Map.EnumerateTiles(Center, Range);
            // Search +2 to get units move behind the border
            List <PlayerUnit> unitsAlreadyInArea = CollectUnitsAlreadyInArea(player, Range + 2);

            if (EnemyUnits.Count > 0)
            {
                // Enemy detected
                dispatcher.RequestAttack(this, EnemyUnits[0]);
                IsPeaceFul = false;

                ScoutingPositions.Clear();
                Center = EnemyUnits[0].Unit.Pos;
                return;
            }

            List <UnitType> remainingUnitTypes = new List <UnitType>();

            remainingUnitTypes.AddRange(DemandedUnitTypes);

            List <PlayerUnit> unitsAlreadyInAreaMatchingDemand     = new List <PlayerUnit>();
            List <PlayerUnit> unitsAlreadyInAreaMatchingButDamaged = new List <PlayerUnit>();


            List <string> deadUnits = new List <string>();

            foreach (string unitId in AssignedUnits)
            {
                bool playerUnitFound = false;

                foreach (PlayerUnit playerUnit in player.Units.Values)
                {
                    if (playerUnit.Unit.UnitId == unitId)
                    {
                        playerUnitFound = true;

                        if (moveableUnits.Contains(playerUnit))
                        {
                            foreach (UnitType unitType in remainingUnitTypes)
                            {
                                if (unitType.Matches(playerUnit))
                                {
                                    unitsAlreadyInAreaMatchingDemand.Add(playerUnit);
                                    //dispatcher.ClaimUnit(this, playerUnit, RequestType.Scout);
                                    remainingUnitTypes.Remove(unitType);
                                }
                                break;
                            }
                        }
                    }
                }
                if (!playerUnitFound)
                {
                    // Unit no longer exists
                    deadUnits.Add(unitId);
                }
            }
            foreach (string deadUnitId in deadUnits)
            {
                AssignedUnits.Remove(deadUnitId);
            }

            // Do not scout around. Attack!
            //if (!IsPeaceFul) return;



            // Collect all fit units

            /*
             * foreach (PlayerUnit playerUnit in unitsAlreadyInArea)
             * {
             *  if (!moveableUnits.Contains(playerUnit))
             *      continue;
             *  if (dispatcher.ClaimedUnits.Contains(playerUnit))
             *      continue;
             *  //if (!playerUnit.Unit.IsComplete())
             *  //    continue;
             *
             *  foreach (UnitType unitType in remainingUnitTypes)
             *  {
             *      if (unitType.Matches(playerUnit))
             *      {
             *          unitsAlreadyInAreaMatchingDemand.Add(playerUnit);
             *          dispatcher.ClaimUnit(this, playerUnit, RequestType.Scout);
             *          remainingUnitTypes.Remove(unitType);
             *      }
             *      break;
             *  }
             * }*/

            // Collect all demaged units that may fit

            /*
             * foreach (PlayerUnit playerUnit in unitsAlreadyInArea)
             * {
             *  if (!moveableUnits.Contains(playerUnit))
             *      continue;
             *
             *  foreach (UnitType unitType in remainingUnitTypes)
             *  {
             *      if (unitType.Matches(playerUnit))
             *      {
             *          if (!playerUnit.Unit.IsComplete())
             *          {
             *              // Do not collect damaged units. Request a new one.
             *              //unitsAlreadyInAreaMatchingButDamaged.Add(playerUnit);
             *              //remainingUnitTypes.Remove(unitType);
             *          }
             *
             *      }
             *      break;
             *  }
             * }*/

            // Request new units if needed
            foreach (UnitType unitType in remainingUnitTypes)
            {
                dispatcher.RequestUnit(this, unitType, null);
            }
            foreach (PlayerUnit playerUnit in unitsAlreadyInAreaMatchingButDamaged)
            {
                //dispatcher.RequestUpgrade(this, playerUnit);
            }

            // Priorise scout position order
            SortedList <int, ScoutPosition> sortedScoutPositions = new SortedList <int, ScoutPosition>(new DegreeComparer());

            foreach (ScoutPosition scoutPosition in ScoutingPositions)
            {
                scoutPosition.MovesNotVisited++;
                sortedScoutPositions.Add(scoutPosition.MovesNotVisited, scoutPosition);
            }

            if (unitsAlreadyInAreaMatchingDemand.Count > 0)
            {
                // Reverse
                for (int i = sortedScoutPositions.Values.Count - 1; i > 0; i--)
                {
                    ScoutPosition scoutPosition = sortedScoutPositions.Values[i];
                    Map.EnumerateTiles(scoutPosition.Pos, Range, stopper: p =>
                    {
                        foreach (PlayerUnit playerUnit in unitsAlreadyInAreaMatchingDemand)
                        {
                            if (!moveableUnits.Contains(playerUnit))
                            {
                                continue;
                            }

                            if (playerUnit.Unit.Pos == p.Pos)
                            {
                                if (p.Distance <= 1)
                                {
                                    // Close enough unit counts a visited
                                    scoutPosition.MovesNotVisited = 0;
                                }


                                // Closest unit to scout point. Move closer, remove unit from list if the unit isn't there already
                                if (scoutPosition.Pos != playerUnit.Unit.Pos)
                                {
                                    //unitsAlreadyInAreaMatchingDemand.Remove(playerUnit);
                                    dispatcher.MoveUnit(this, playerUnit, scoutPosition.Pos);

                                    /* Select a path that does not leave the area. Needed?
                                     * Move move = dispatcher.GameController.MoveTo(playerUnit.Unit.Pos, scoutPosition.Pos, playerUnit.Unit.Engine);
                                     * if (move != null)
                                     * {
                                     *  bool pathOutsideOfArea = false;
                                     *  foreach (Position path in move.Positions)
                                     *  {
                                     *      // Is each position in path in scout area?
                                     *      if (!positionsToScount.ContainsKey(path))
                                     *      {
                                     *          pathOutsideOfArea = true;
                                     *      }
                                     *  }
                                     *  if (pathOutsideOfArea)
                                     *  {
                                     *      // unreachable, try another
                                     *  }
                                     *  else
                                     *  {
                                     *      dispatcher.MoveUnit(this, playerUnit, move);
                                     *      unitsAlreadyInAreaMatchingDemand.Remove(playerUnit);
                                     *  }
                                     * }
                                     * else
                                     * {
                                     *  // unreachable, try another
                                     * }*/
                                }

                                // Stop searching for this point
                                return(true);
                            }
                        }
                        return(false);
                    });
                }


                // Move any other attached units closer
                foreach (PlayerUnit playerUnit in unitsAlreadyInAreaMatchingDemand)
                {
                    if (!moveableUnits.Contains(playerUnit))
                    {
                        continue;
                    }

                    int ix;

#pragma warning disable CS0162 // Unreachable code detected
                    for (ix = sortedScoutPositions.Values.Count - 1; ix > 0; ix--)
#pragma warning restore CS0162 // Unreachable code detected
                    {
                        ScoutPosition scoutPosition = sortedScoutPositions.Values[ix];
                        dispatcher.MoveUnit(this, playerUnit, scoutPosition.Pos);

                        /*
                         * Move move = dispatcher.GameController.MoveTo(playerUnit.Unit.Pos, scoutPosition.Pos, playerUnit.Unit.Engine);
                         * if (move != null)
                         * {
                         *  dispatcher.MoveUnit(this, playerUnit, move);
                         * }
                         * else
                         * {
                         *  // Cannot reach, move unit to center, hope the best
                         *  //dispatcher.MoveUnit(this, playerUnit, Center);
                         * }
                         */
                        break;
                    }
                }
            }
        }