示例#1
0
        private int RescueLastManStanding(TurnManager turnManager, RiskAnalysis analysis, int availableTroops)
        {
            if (availableTroops < 4)
            {
                return(0);
            }

            var lastManStanding = new Queue <Deployment>(from cnt in analysis.Continents
                                                         where cnt.MyCountries.Sum(x => x.NumberOfTroops) < 3
                                                         from c in cnt.MyCountries
                                                         select
                                                         new Deployment(turnManager)
            {
                ToCountry = c
            });

            if (lastManStanding.Count == 0)
            {
                return(0);
            }

            while (availableTroops > 0)
            {
                availableTroops--;
                var x = lastManStanding.Dequeue();
                x.Troops++;
                lastManStanding.Enqueue(x);
            }
            analysis.Deployments.AddRange(lastManStanding);
            return(lastManStanding.Sum(x => x.Troops));
        }
示例#2
0
        private void DeployRemaining(TurnManager turnManager, RiskAnalysis analysis, int troops, GameInformation gameInfo)
        {
            if (troops <= 0)
            {
                return;
            }
            // deploy remainder evenly...
            var deployments = gameInfo.GetAllCountriesOwnedByPlayer(_player)
                              .OrderBy(x => x.NumberOfTroops)
                              .Select(x => new Deployment(turnManager)
            {
                ToCountry = x
            })
                              .ToList();

            while (troops > 0)
            {
                foreach (var deployment in deployments.TakeWhile(deployment => -- troops >= 0))
                {
                    deployment.Troops++;
                }
            }

            analysis.Deployments.AddRange(deployments.Where(x => x.Troops > 0));
        }
示例#3
0
        private int AustraliaRuleZ(TurnManager turnManager, RiskAnalysis analysis, int availableTroops)
        {
            if (availableTroops == 0)
            {
                return(0);
            }
            var downUnder = analysis.Continents.FirstOrDefault(x => x.Name == EContinent.Australia);

            if (downUnder == null || downUnder.MyCountries.Count == 0)
            {
                return(0);
            }

            if (downUnder.IsOwned)
            {
                availableTroops = Math.Min(availableTroops, 3);
                var whatchamacallit    = downUnder.MyCountries.First(x => x.IsContinentGateway());
                var minAussieDefenders = 6;
                if (whatchamacallit.IsUnderAttack() || whatchamacallit.NumberOfTroops < minAussieDefenders)
                {
                    analysis.Deployments.Add(new Deployment(turnManager)
                    {
                        ToCountry = whatchamacallit,
                        Troops    = availableTroops,
                    });
                    return(availableTroops);
                }
                var thingamajig = whatchamacallit.AdjacentCountries.First(x => x.Continent != EContinent.Australia);
                if (thingamajig.IsUnderAttack() || thingamajig.NumberOfTroops < minAussieDefenders)
                {
                    analysis.Deployments.Add(new Deployment(turnManager)
                    {
                        ToCountry = thingamajig,
                        Troops    = availableTroops,
                    });
                    return(availableTroops);
                }

                return(0);
            }

            var deployments = downUnder.MyCountries.Select(x => new Deployment(turnManager)
            {
                ToCountry = x
            });
            // round-robin deployment, using a queue...
            var q = new Queue <Deployment>(deployments);

            while (availableTroops > 0)
            {
                availableTroops--;
                var c = q.Dequeue();
                c.Troops++;
                q.Enqueue(c);
            }
            analysis.Deployments.AddRange(q);
            return(q.Sum(x => x.Troops));
        }
示例#4
0
        private void DoImportantCountryAnalysis(TurnManager turnManager, RiskAnalysis analysis)
        {
            var countries = analysis.Attacks.Select(x => x.FromCountry)
                            .Concat(analysis.Moves.Select(x => x.FromCountry))
                            .Concat(analysis.Deployments.Select(x => x.ToCountry))
                            .Concat(
                turnManager.GetGameInfo().GetAllCountriesOwnedByPlayer(_player).Where(x => x.IsContinentGateway()));

            analysis.ImportantCountries.AddRange(countries);
        }
示例#5
0
        private void DoDeployAnalysis(TurnManager turnManager, RiskAnalysis analysis)
        {
            var gameInfo = turnManager.GetGameInfo();
            var troops   = gameInfo.GetNumberOfUnitsToDeploy(_player);

            troops = troops - AustraliaRuleZ(turnManager, analysis, troops);
            troops = troops - DeployContinentGatewayDefence(turnManager, analysis, troops);
            troops = troops - DeployOffence(turnManager, analysis, troops);
            troops = troops - RescueLastManStanding(turnManager, analysis, troops);
            DeployRemaining(turnManager, analysis, troops, gameInfo);
        }
示例#6
0
文件: RiskAnalyzer.cs 项目: resc/Risk
 /// <summary>
 ///     Adds attack info to the analysis, but only if there is a chance for success
 /// </summary>
 private void AddAttack(TurnManager turnManager, RiskAnalysis analysis, Country friendly, Country enemy)
 {
     var minDefenders = 2;
     if (friendly.NumberOfTroops > minDefenders+1 && friendly.NumberOfTroops > enemy.NumberOfTroops )
     {
         analysis.Attacks.Add(new Attack(turnManager)
             {
                 FromCountry = friendly,
                 ToCountry = enemy,
                 Troops = friendly.NumberOfTroops - minDefenders,
             });
     }
 }
示例#7
0
        /// <summary>
        ///     Adds attack info to the analysis, but only if there is a chance for success
        /// </summary>
        private void AddAttack(TurnManager turnManager, RiskAnalysis analysis, Country friendly, Country enemy)
        {
            var minDefenders = 2;

            if (friendly.NumberOfTroops > minDefenders + 1 && friendly.NumberOfTroops > enemy.NumberOfTroops)
            {
                analysis.Attacks.Add(new Attack(turnManager)
                {
                    FromCountry = friendly,
                    ToCountry   = enemy,
                    Troops      = friendly.NumberOfTroops - minDefenders,
                });
            }
        }
示例#8
0
        private void DoMoveAnalysis(TurnManager turnManager, RiskAnalysis analysis)
        {
            var gameinfo = turnManager.GetGameInfo();

            var minDefenders = 3;
            var sources      = gameinfo.GetAllCountriesOwnedByPlayer(_player)
                               .Where(x => x.NumberOfTroops > minDefenders && !x.IsUnderAttack() && !x.IsContinentGateway())
                               .ToList();
            var movable = 7;
            var targets = new HashSet <Country>();

            foreach (var source in sources)
            {
                var target =
                    gameinfo.GetAdjacentCountriesWithSameOwner(source)
                    .Where(x => x.IsUnderAttack())
                    .OrderBy(x => x.GetThreatLevel())
                    .FirstOrDefault();
                var toMove = Math.Min(movable, (source.NumberOfTroops - minDefenders));
                if (toMove > 0)
                {
                    if (target == null)
                    {
                        var source1 = source;
                        target = gameinfo.GetAdjacentCountriesWithSameOwner(source)
                                 .Where(x => x.IsContinentGateway() ||
                                        source1.NumberOfTroops - x.NumberOfTroops > minDefenders)
                                 .OrderBy(x => x.NumberOfTroops)
                                 .FirstOrDefault(x => targets.Add(x));
                        if (target != null)
                        {
                            toMove = Math.Min(toMove, minDefenders);
                        }
                    }
                    if (target != null)
                    {
                        movable = Math.Max(0, movable - toMove);
                        analysis.Moves.Add(new Move(turnManager)
                        {
                            FromCountry = source,
                            ToCountry   = target,
                            Troops      = toMove
                        });
                    }
                }
            }
        }
示例#9
0
        /// <returns>The number of deployed troops</returns>
        private int DeployContinentGatewayDefence(TurnManager turnManager, RiskAnalysis analysis, int availableTroops)
        {
            if (availableTroops == 0)
            {
                return(0);
            }
            var gameInformation = turnManager.GetGameInfo();
            var weakGateways    = (from c in analysis.Continents
                                   where c.IsOwned
                                   from country in c.MyCountries
                                   where country.IsContinentGateway()
                                   // make it a reasonable large margin.
                                   let troopTarget = GetTroopTarget(gameInformation, country)
                                                     where country.NumberOfTroops < troopTarget
                                                     select new
            {
                country,
                troopTarget,
                deployment = new Deployment(turnManager)
                {
                    ToCountry = country
                },
            }).ToList();

            var deployments = weakGateways.Select(x => x.deployment).ToList();
            var i           = 0;

            // deploy troops until there are no more available, or we've reached our target numer of troops everywhere.
            while (deployments.Sum(x => x.Troops) < availableTroops && weakGateways.Count > 0)
            {
                var wg = weakGateways[i];
                wg.deployment.Troops++;
                if (wg.country.NumberOfTroops + wg.deployment.Troops >= wg.troopTarget)
                {
                    weakGateways.RemoveAt(i);
                    if (weakGateways.Count == 0)
                    {
                        break;
                    }
                }
                i = (i + 1) % weakGateways.Count;
            }

            analysis.Deployments.AddRange(deployments.Where(x => x.Troops > 0));

            return(deployments.Sum(x => x.Troops));
        }
示例#10
0
文件: RiskAnalyzer.cs 项目: resc/Risk
        /// <summary>
        ///     Performs analysis of the game state.
        ///     It does a full analysis for every phase of a turn.
        ///     This wastes some computational resources, but hopefully leads to a better outcome.
        /// </summary>
        public RiskAnalysis Analyze(TurnManager turnManager)
        {
            var analysis = new RiskAnalysis();
            // the ordering of the analysis steps is important
            // each step depends on the results of the previous steps.

            // first, check the state of the board.
            DoContinentAnalysis(turnManager, analysis);
            // next, find which countries we want.
            DoAttackAnalysis(turnManager, analysis);
            // then check if we need to move troops
            DoMoveAnalysis(turnManager, analysis);
            // then place reinforcements on the board.
            DoDeployAnalysis(turnManager, analysis);

            // gather important countries.
            DoImportantCountryAnalysis(turnManager, analysis);

            return analysis;
        }
示例#11
0
        private int DeployOffence(TurnManager turnManager, RiskAnalysis analysis, int availableTroops)
        {
            if (availableTroops == 0)
            {
                return(0);
            }

            var deployments =
                (// find continent where we're strongest, but not owned
                    from continent in analysis.Continents.Where(x => !x.IsOwned).OrderByDescending(x => x.Dominance)
                    // reinforce weakest countries first.
                    from country in continent.MyCountries.OrderByDescending(x => x.GetThreatLevel())
                    where country.IsUnderAttack()
                    select new Deployment(turnManager)
            {
                ToCountry = country
            }).Take(2).ToList();

            if (availableTroops == 0 || deployments.Count == 0)
            {
                return(0);
            }


            while (deployments.Sum(x => x.Troops) < availableTroops)
            {
                foreach (var deployment in deployments)
                {
                    if (deployments.Sum(x => x.Troops) >= availableTroops)
                    {
                        break;
                    }

                    deployment.Troops += 1;
                }
            }
            analysis.Deployments.AddRange(deployments);
            return(deployments.Sum(x => x.Troops));
        }
示例#12
0
        /// <summary>
        ///     Performs analysis of the game state.
        ///     It does a full analysis for every phase of a turn.
        ///     This wastes some computational resources, but hopefully leads to a better outcome.
        /// </summary>
        public RiskAnalysis Analyze(TurnManager turnManager)
        {
            var analysis = new RiskAnalysis();

            // the ordering of the analysis steps is important
            // each step depends on the results of the previous steps.

            // first, check the state of the board.
            DoContinentAnalysis(turnManager, analysis);
            // next, find which countries we want.
            DoAttackAnalysis(turnManager, analysis);
            // then check if we need to move troops
            DoMoveAnalysis(turnManager, analysis);
            // then place reinforcements on the board.
            DoDeployAnalysis(turnManager, analysis);

            // gather important countries.
            DoImportantCountryAnalysis(turnManager, analysis);


            return(analysis);
        }
示例#13
0
        private void DoContinentAnalysis(TurnManager turnManager, RiskAnalysis analysis)
        {
            // compute continent statistics
            var continents = from c in turnManager.GetGameInfo().GetAllCountries()
                             group c by c.Continent
                             into continent
                             select new Continent
            {
                Name        = continent.Key,
                MyCountries =
                    continent.Where(x => x.Owner == _player).ToList(),
                EnemyCountries =
                    continent.Where(x => x.Owner != _player)
                    .OrderBy(x => x.NumberOfTroops)
                    .ToList(),
                Opponents =
                    continent.Where(x => x.Owner != _player)
                    .Distinct(x => x.Owner)
                    .ToList()
            };

            analysis.Continents.AddRange(continents);
        }
示例#14
0
文件: RiskAnalyzer.cs 项目: resc/Risk
        private int AustraliaRuleZ(TurnManager turnManager, RiskAnalysis analysis, int availableTroops)
        {
            if (availableTroops == 0) return 0;
            var downUnder = analysis.Continents.FirstOrDefault(x => x.Name == EContinent.Australia);
            if (downUnder == null || downUnder.MyCountries.Count == 0)
                return 0;

            if (downUnder.IsOwned)
            {
                availableTroops = Math.Min(availableTroops, 3);
                var whatchamacallit = downUnder.MyCountries.First(x => x.IsContinentGateway());
                var minAussieDefenders = 6;
                if (whatchamacallit.IsUnderAttack() || whatchamacallit.NumberOfTroops < minAussieDefenders)
                {
                    analysis.Deployments.Add(new Deployment(turnManager)
                        {
                            ToCountry = whatchamacallit,
                            Troops = availableTroops,

                        });
                    return availableTroops;
                }
                var thingamajig = whatchamacallit.AdjacentCountries.First(x => x.Continent != EContinent.Australia);
                if (thingamajig.IsUnderAttack() || thingamajig.NumberOfTroops < minAussieDefenders)
                {
                    analysis.Deployments.Add(new Deployment(turnManager)
                    {
                        ToCountry = thingamajig,
                        Troops = availableTroops,

                    });
                    return availableTroops;
                }

                return 0;
            }

            var deployments = downUnder.MyCountries.Select(x => new Deployment(turnManager) { ToCountry = x });
            // round-robin deployment, using a queue...
            var q = new Queue<Deployment>(deployments);
            while (availableTroops > 0)
            {
                availableTroops--;
                var c = q.Dequeue();
                c.Troops++;
                q.Enqueue(c);
            }
            analysis.Deployments.AddRange(q);
            return q.Sum(x => x.Troops);
        }
示例#15
0
文件: RiskAnalyzer.cs 项目: resc/Risk
        private void DeployRemaining(TurnManager turnManager, RiskAnalysis analysis, int troops, GameInformation gameInfo)
        {
            if (troops <= 0) return;
            // deploy remainder evenly...
            var deployments = gameInfo.GetAllCountriesOwnedByPlayer(_player)
                                      .OrderBy(x => x.NumberOfTroops)
                                      .Select(x => new Deployment(turnManager) { ToCountry = x })
                                      .ToList();
            while (troops > 0)
            {
                foreach (var deployment in deployments.TakeWhile(deployment => --troops >= 0))
                {
                    deployment.Troops++;
                }
            }

            analysis.Deployments.AddRange(deployments.Where(x => x.Troops > 0));
        }
示例#16
0
文件: RiskAnalyzer.cs 项目: resc/Risk
        private void DoAttackAnalysis(TurnManager turnManager, RiskAnalysis analysis)
        {
            var continents = (from c in analysis.GetContinentsByDominance()
                              select c).ToList();

            if (continents.Count == 0) return; // shouldn't happen unless we've won, or have been defeated completely.

            var attacked = new HashSet<Country>();
            var gameInfo = turnManager.GetGameInfo();
            foreach (var continent in continents)
            {
                // create a lookup with the ranking of the enemies,
                // 0 is weakest...
                var enemies = continent.EnemyCountries.OrderBy(x => x.NumberOfTroops)
                                       .Select((country, rank) => new { country, rank })
                                       .ToDictionary(key => key.country, val => val.rank);

                // order friendlies by strongest first
                var friendlies = continent.MyCountries.OrderByDescending(x => x.NumberOfTroops).ToList();

                foreach (var friendly in friendlies)
                {
                    var neighbours = gameInfo.GetAdjacentCountriesWithDifferentOwner(friendly).OrderBy(x =>
                        {
                            // use TryGetValue, adjacent countries can be on a different continent.
                            // use a very high ranking for those, so we don't attack them, yet.
                            var rank = 0;
                            return enemies.TryGetValue(x, out rank) ? rank : 100;
                        }).ToList();

                    if (neighbours.Count == 0)
                        continue; // because we're surrounded by friendlies...

                    // only attack countries not already under attack.
                    var enemy = neighbours.FirstOrDefault(x => !attacked.Contains(x));
                    if (enemy != null)
                    {
                        attacked.Add(enemy);
                        AddAttack(turnManager, analysis, friendly, enemy);
                    }
                }
            }

            if (attacked.Count == 0)
            {
                // break out of owned continents
                var fromGateways = from c in gameInfo.GetAllCountriesOwnedByPlayer(_player)
                                   where c.IsContinentGatewayUnderAttack()
                                   select c;
                foreach (var friendly in fromGateways)
                {
                    var enemy = gameInfo.GetAdjacentCountriesWithDifferentOwner(friendly)
                                               .OrderBy(x => friendly.NumberOfTroops - x.NumberOfTroops)
                                               .FirstOrDefault();
                    if (enemy != null && attacked.Add(enemy))
                        AddAttack(turnManager, analysis, friendly, enemy);
                }
            }

            analysis.Attacks
                    .Sort((a, b) =>
                          (b.FromCountry.NumberOfTroops - b.ToCountry.NumberOfTroops) -
                          (a.FromCountry.NumberOfTroops - a.ToCountry.NumberOfTroops));
        }
示例#17
0
文件: RiskAnalyzer.cs 项目: resc/Risk
        private void DoContinentAnalysis(TurnManager turnManager, RiskAnalysis analysis)
        {
            // compute continent statistics
            var continents = from c in turnManager.GetGameInfo().GetAllCountries()
                             group c by c.Continent
                                 into continent
                                 select new Continent
                                     {
                                         Name = continent.Key,
                                         MyCountries =
                                             continent.Where(x => x.Owner == _player).ToList(),
                                         EnemyCountries =
                                             continent.Where(x => x.Owner != _player)
                                                      .OrderBy(x => x.NumberOfTroops)
                                                      .ToList(),
                                         Opponents =
                                             continent.Where(x => x.Owner != _player)
                                                      .Distinct(x => x.Owner)
                                                      .ToList()
                                     };

            analysis.Continents.AddRange(continents);
        }
示例#18
0
文件: RiskAnalyzer.cs 项目: resc/Risk
 private void DoDeployAnalysis(TurnManager turnManager, RiskAnalysis analysis)
 {
     var gameInfo = turnManager.GetGameInfo();
     var troops = gameInfo.GetNumberOfUnitsToDeploy(_player);
     troops = troops - AustraliaRuleZ(turnManager, analysis, troops);
     troops = troops - DeployContinentGatewayDefence(turnManager, analysis, troops);
     troops = troops - DeployOffence(turnManager, analysis, troops);
     troops = troops - RescueLastManStanding(turnManager, analysis, troops);
     DeployRemaining(turnManager, analysis, troops, gameInfo);
 }
示例#19
0
文件: RiskAnalyzer.cs 项目: resc/Risk
        private int DeployOffence(TurnManager turnManager, RiskAnalysis analysis, int availableTroops)
        {
            if (availableTroops == 0) return 0;

            var deployments =
                (// find continent where we're strongest, but not owned
                 from continent in analysis.Continents.Where(x => !x.IsOwned).OrderByDescending(x => x.Dominance)
                 // reinforce weakest countries first.
                 from country in continent.MyCountries.OrderByDescending(x => x.GetThreatLevel())
                 where country.IsUnderAttack()
                 select new Deployment(turnManager) { ToCountry = country }).Take(2).ToList();

            if (availableTroops == 0 || deployments.Count == 0)
                return 0;

            while (deployments.Sum(x => x.Troops) < availableTroops)
            {
                foreach (var deployment in deployments)
                {
                    if (deployments.Sum(x => x.Troops) >= availableTroops)
                        break;

                    deployment.Troops += 1;
                }
            }
            analysis.Deployments.AddRange(deployments);
            return deployments.Sum(x => x.Troops);
        }
示例#20
0
文件: RiskAnalyzer.cs 项目: resc/Risk
        private void DoImportantCountryAnalysis(TurnManager turnManager, RiskAnalysis analysis)
        {
            var countries = analysis.Attacks.Select(x => x.FromCountry)
                           .Concat(analysis.Moves.Select(x => x.FromCountry))
                           .Concat(analysis.Deployments.Select(x => x.ToCountry))
                           .Concat(
                               turnManager.GetGameInfo().GetAllCountriesOwnedByPlayer(_player).Where(x => x.IsContinentGateway()));

            analysis.ImportantCountries.AddRange(countries);
        }
示例#21
0
文件: RiskAnalyzer.cs 项目: resc/Risk
        private int RescueLastManStanding(TurnManager turnManager, RiskAnalysis analysis, int availableTroops)
        {
            if (availableTroops < 4) return 0;

            var lastManStanding = new Queue<Deployment>(from cnt in analysis.Continents
                                                        where cnt.MyCountries.Sum(x => x.NumberOfTroops) < 3
                                                        from c in cnt.MyCountries
                                                        select
                                                            new Deployment(turnManager)
                                                                {
                                                                    ToCountry = c
                                                                });
            if (lastManStanding.Count == 0)
                return 0;

            while (availableTroops > 0)
            {
                availableTroops--;
                var x = lastManStanding.Dequeue();
                x.Troops++;
                lastManStanding.Enqueue(x);
            }
            analysis.Deployments.AddRange(lastManStanding);
            return lastManStanding.Sum(x => x.Troops);
        }
示例#22
0
文件: RiskAnalyzer.cs 项目: resc/Risk
        private void DoMoveAnalysis(TurnManager turnManager, RiskAnalysis analysis)
        {
            var gameinfo = turnManager.GetGameInfo();

            var minDefenders = 3;
            var sources = gameinfo.GetAllCountriesOwnedByPlayer(_player)
                        .Where(x => x.NumberOfTroops > minDefenders && !x.IsUnderAttack() && !x.IsContinentGateway())
                        .ToList();
            var movable = 7;
            var targets = new HashSet<Country>();
            foreach (var source in sources)
            {
                var target =
                    gameinfo.GetAdjacentCountriesWithSameOwner(source)
                            .Where(x => x.IsUnderAttack())
                            .OrderBy(x => x.GetThreatLevel())
                            .FirstOrDefault();
                var toMove = Math.Min(movable, (source.NumberOfTroops - minDefenders));
                if (toMove > 0)
                {
                    if (target == null)
                    {
                        var source1 = source;
                        target = gameinfo.GetAdjacentCountriesWithSameOwner(source)
                                         .Where(x => x.IsContinentGateway()
                                                     || source1.NumberOfTroops - x.NumberOfTroops > minDefenders)
                                         .OrderBy(x => x.NumberOfTroops)
                                         .FirstOrDefault(x => targets.Add(x));
                        if (target != null)
                        {
                            toMove = Math.Min(toMove, minDefenders);
                        }
                    }
                    if (target != null)
                    {
                        movable = Math.Max(0, movable - toMove);
                        analysis.Moves.Add(new Move(turnManager)
                        {
                            FromCountry = source,
                            ToCountry = target,
                            Troops = toMove
                        });
                    }
                }
            }
        }
示例#23
0
        private void DoAttackAnalysis(TurnManager turnManager, RiskAnalysis analysis)
        {
            var continents = (from c in analysis.GetContinentsByDominance()
                              select c).ToList();

            if (continents.Count == 0)
            {
                return;                        // shouldn't happen unless we've won, or have been defeated completely.
            }
            var attacked = new HashSet <Country>();
            var gameInfo = turnManager.GetGameInfo();

            foreach (var continent in continents)
            {
                // create a lookup with the ranking of the enemies,
                // 0 is weakest...
                var enemies = continent.EnemyCountries.OrderBy(x => x.NumberOfTroops)
                              .Select((country, rank) => new { country, rank })
                              .ToDictionary(key => key.country, val => val.rank);

                // order friendlies by strongest first
                var friendlies = continent.MyCountries.OrderByDescending(x => x.NumberOfTroops).ToList();

                foreach (var friendly in friendlies)
                {
                    var neighbours = gameInfo.GetAdjacentCountriesWithDifferentOwner(friendly).OrderBy(x =>
                    {
                        // use TryGetValue, adjacent countries can be on a different continent.
                        // use a very high ranking for those, so we don't attack them, yet.
                        var rank = 0;
                        return(enemies.TryGetValue(x, out rank) ? rank : 100);
                    }).ToList();


                    if (neighbours.Count == 0)
                    {
                        continue; // because we're surrounded by friendlies...
                    }
                    // only attack countries not already under attack.
                    var enemy = neighbours.FirstOrDefault(x => !attacked.Contains(x));
                    if (enemy != null)
                    {
                        attacked.Add(enemy);
                        AddAttack(turnManager, analysis, friendly, enemy);
                    }
                }
            }

            if (attacked.Count == 0)
            {
                // break out of owned continents
                var fromGateways = from c in gameInfo.GetAllCountriesOwnedByPlayer(_player)
                                   where c.IsContinentGatewayUnderAttack()
                                   select c;
                foreach (var friendly in fromGateways)
                {
                    var enemy = gameInfo.GetAdjacentCountriesWithDifferentOwner(friendly)
                                .OrderBy(x => friendly.NumberOfTroops - x.NumberOfTroops)
                                .FirstOrDefault();
                    if (enemy != null && attacked.Add(enemy))
                    {
                        AddAttack(turnManager, analysis, friendly, enemy);
                    }
                }
            }


            analysis.Attacks
            .Sort((a, b) =>
                  (b.FromCountry.NumberOfTroops - b.ToCountry.NumberOfTroops) -
                  (a.FromCountry.NumberOfTroops - a.ToCountry.NumberOfTroops));
        }
示例#24
0
文件: RiskAnalyzer.cs 项目: resc/Risk
        /// <returns>The number of deployed troops</returns>
        private int DeployContinentGatewayDefence(TurnManager turnManager, RiskAnalysis analysis, int availableTroops)
        {
            if (availableTroops == 0) return 0;
            var gameInformation = turnManager.GetGameInfo();
            var weakGateways = (from c in analysis.Continents
                                where c.IsOwned
                                from country in c.MyCountries
                                where country.IsContinentGateway()
                                // make it a reasonable large margin.
                                let troopTarget = GetTroopTarget(gameInformation, country)
                                where country.NumberOfTroops < troopTarget
                                select new
                                    {
                                        country,
                                        troopTarget,
                                        deployment = new Deployment(turnManager) { ToCountry = country },
                                    }).ToList();

            var deployments = weakGateways.Select(x => x.deployment).ToList();
            var i = 0;

            // deploy troops until there are no more available, or we've reached our target numer of troops everywhere.
            while (deployments.Sum(x => x.Troops) < availableTroops && weakGateways.Count > 0)
            {
                var wg = weakGateways[i];
                wg.deployment.Troops++;
                if (wg.country.NumberOfTroops + wg.deployment.Troops >= wg.troopTarget)
                {
                    weakGateways.RemoveAt(i);
                    if (weakGateways.Count == 0)
                        break;
                }
                i = (i + 1) % weakGateways.Count;
            }

            analysis.Deployments.AddRange(deployments.Where(x => x.Troops > 0));

            return deployments.Sum(x => x.Troops);
        }