Пример #1
0
        public void Attack(
            IAttackService attackService,
            IRandomGen randomGen,
            MapTemplate mapTemplate,
            string sourceCountryIdentifier,
            string destCountryIdentifier,
            int numberOfUnits)
        {
            this.RequireGameActive();

            if (this.PlayState != PlayState.Attack)
            {
                throw new DomainException(ErrorCode.AttackingNotPossible, "Cannot attack, state incorrect");
            }

            var sourceCountry = this.Map.GetCountry(sourceCountryIdentifier);
            var destCountry   = this.Map.GetCountry(destCountryIdentifier);

            // Check connection
            if (!mapTemplate.AreConnected(sourceCountryIdentifier, destCountryIdentifier))
            {
                throw new DomainException(ErrorCode.CountriesNotConnected, "There is no connection between those countries");
            }

            // Check ownership
            if (sourceCountry.TeamId != this.CurrentPlayer.TeamId)
            {
                throw new DomainException(ErrorCode.OriginCountryNotOwnedByTeam, "Can only initiate actions from countries that belong to the same team");
            }

            if (sourceCountry.PlayerId == destCountry.PlayerId)
            {
                throw new DomainException(ErrorCode.AttackOwnCountries, "Cannot attack own countries");
            }

            if (numberOfUnits <= 0 || sourceCountry.Units - numberOfUnits < this.Options.MinUnitsPerCountry)
            {
                throw new DomainException(ErrorCode.NotEnoughUnits, "Cannot attack with that many units");
            }

            var otherPlayer = this.GetPlayerById(destCountry.PlayerId);

            int attackerUnitsLost = 0;
            int defenderUnitsLost = 0;
            var result            = attackService.Attack(numberOfUnits, destCountry.Units, out attackerUnitsLost, out defenderUnitsLost);

            if (result)
            {
                // Attack was successful
                destCountry.Units = numberOfUnits - attackerUnitsLost;

                this.Map.UpdateOwnership(otherPlayer, this.CurrentPlayer, destCountry);

                this.DistributeCard(randomGen);
            }
            else
            {
                // Attack failed
                destCountry.Units -= defenderUnitsLost;
            }

            // Reduce units in this country in any case
            sourceCountry.Units -= numberOfUnits;

            this.GameHistory.RecordAttack(
                this.CurrentPlayer, otherPlayer,
                sourceCountryIdentifier, destCountryIdentifier,
                numberOfUnits, attackerUnitsLost, defenderUnitsLost,
                result);

            // Reduce number of attacks left
            this.AttacksInCurrentTurn++;

            // Check for victory
            this.CheckForVictory(this.CurrentPlayer, otherPlayer);

            if (this.AttacksInCurrentTurn >= this.Options.AttacksPerTurn)
            {
                this.EndAttack();
            }
        }
Пример #2
0
 public void Attack(Player target)
 {
     _attackService.Attack(this, target);
 }
Пример #3
0
        public void Attack(
            IAttackService attackService,
            IRandomGen randomGen,
            MapTemplate mapTemplate,
            string sourceCountryIdentifier, 
            string destCountryIdentifier, 
            int numberOfUnits)
        {
            this.RequireGameActive();

            if (this.PlayState != PlayState.Attack)
            {
                throw new DomainException(ErrorCode.AttackingNotPossible, "Cannot attack, state incorrect");
            }

            var sourceCountry = this.Map.GetCountry(sourceCountryIdentifier);
            var destCountry = this.Map.GetCountry(destCountryIdentifier);

            // Check connection
            if (!mapTemplate.AreConnected(sourceCountryIdentifier, destCountryIdentifier))
            {
                throw new DomainException(ErrorCode.CountriesNotConnected, "There is no connection between those countries");
            }

            // Check ownership
            if (sourceCountry.TeamId != this.CurrentPlayer.TeamId)
            {
                throw new DomainException(ErrorCode.OriginCountryNotOwnedByTeam, "Can only initiate actions from countries that belong to the same team");
            }

            if (sourceCountry.PlayerId == destCountry.PlayerId)
            {
                throw new DomainException(ErrorCode.AttackOwnCountries, "Cannot attack own countries");
            }

            if (numberOfUnits <= 0 || sourceCountry.Units - numberOfUnits < this.Options.MinUnitsPerCountry)
            {
                throw new DomainException(ErrorCode.NotEnoughUnits, "Cannot attack with that many units");
            }

            var otherPlayer = this.GetPlayerById(destCountry.PlayerId);

            int attackerUnitsLost = 0;
            int defenderUnitsLost = 0;
            var result = attackService.Attack(numberOfUnits, destCountry.Units, out attackerUnitsLost, out defenderUnitsLost);

            if (result)
            {
                // Attack was successful
                destCountry.Units = numberOfUnits - attackerUnitsLost;

                this.Map.UpdateOwnership(otherPlayer, this.CurrentPlayer, destCountry);

                this.DistributeCard(randomGen);
            }
            else
            {
                // Attack failed
                destCountry.Units -= defenderUnitsLost;
            }

            // Reduce units in this country in any case
            sourceCountry.Units -= numberOfUnits;

            this.GameHistory.RecordAttack(
                this.CurrentPlayer, otherPlayer,
                sourceCountryIdentifier, destCountryIdentifier,
                numberOfUnits, attackerUnitsLost, defenderUnitsLost,
                result);

            // Reduce number of attacks left
            this.AttacksInCurrentTurn++;

            // Check for victory
            this.CheckForVictory(this.CurrentPlayer, otherPlayer);

            if (this.AttacksInCurrentTurn >= this.Options.AttacksPerTurn)
            {
                this.EndAttack();
            }
        }