/// <summary>
    /// Restores all of the tokens to their default / healthy state.
    /// </summary>
    static public void HealTokens(TokenCountDictionary counts)
    {
        void RestoreAllToDefault(Token token)
        {
            if (token is not HealthToken ht || ht.Damage == 0)
            {
                return;
            }
            int num = counts[token];

            counts.Adjust(ht.Healthy, num);
            counts.Adjust(token, -num);
        }

        void HealGroup(TokenClass group)
        {
            foreach (var token in counts.OfType(group).ToArray())
            {
                RestoreAllToDefault(token);
            }
        }

        HealGroup(Invader.City);
        HealGroup(Invader.Town);
        HealGroup(TokenType.Dahan);
    }
    async Task BringerPushNInvaders(Space source, int countToPush, params TokenClass[] healthyInvaders)
    {
        // We can't track which original invader is was killed, so let the user choose.

//		TokenCountDictionary tokens = ctx.Target(source).Tokens;
        TokenCountDictionary tokens = ctx.GameState.Tokens[source];

        Token[] CalcInvaderTypes() => tokens.OfAnyType(healthyInvaders);

        var invaders = CalcInvaderTypes();

        while (0 < countToPush && 0 < invaders.Length)
        {
            var invader = await ctx.Decision(Select.TokenFrom1Space.TokenToPush(source, countToPush, invaders, Present.Always));

            if (invader == null)
            {
                break;
            }

            var destination = await ctx.Decision(new Select.Space(
                                                     "Push " + invader.ToString() + " to",
                                                     source.Adjacent.Where(s => ctx.Target(s).IsInPlay(Invader.Explorer))
                                                     , Present.Always
                                                     ));

            await tokens.MoveTo(invader, destination);

            --countToPush;
            invaders = CalcInvaderTypes();
        }
    }
    //public override void HealAll( GameState gs ) {
    //	// Invaders and dahan in your lands don't heal Damage.
    //	skipHealSpaces.UnionWith( spirit.Presence.Spaces );
    //	base.HealAll( gs );
    //}

    public override void HealSpace(TokenCountDictionary tokens)
    {
        if (!spirit.Presence.IsOn(tokens.Space))
        {
            base.HealSpace(tokens);
        }
    }
Beispiel #4
0
    public static int DamageFrom1StrifedInvaders(TokenCountDictionary tokens)
    {
        var strifedInvaderWithMostDamage = tokens.Invaders().OfType <HealthToken>()
                                           .OrderByDescending(x => x.FullHealth)
                                           .FirstOrDefault();

        return(strifedInvaderWithMostDamage != null ? strifedInvaderWithMostDamage.FullHealth : 0);
    }
Beispiel #5
0
 public TokenCountDictionary this[Space space] {
     get {
         if (!tokenCounts.ContainsKey(space))
         {
             tokenCounts[space] = new TokenCountDictionary(space, new CountDictionary <Token>(), this);
         }
         return(tokenCounts[space]);
     }
 }
Beispiel #6
0
    public static void Init(this TokenCountDictionary currentTokens, string expectedInvaderSummary)
    {
        CountDictionary <Token> desiredTokens = new();

        if (!string.IsNullOrEmpty(expectedInvaderSummary))
        {
            foreach (var part in expectedInvaderSummary.Split(','))
            {
                Token token = part[1..] switch {
Beispiel #7
0
    public void InitTokens(TokenCountDictionary tokens)
    {
        StartUpCounts initialCounts = StartUpCounts;

        tokens.InitDefault(Invader.City, initialCounts.Cities);
        tokens.InitDefault(Invader.Town, initialCounts.Towns);
        tokens.InitDefault(Invader.Explorer, initialCounts.Explorers);
        tokens.Dahan.Init(initialCounts.Dahan);
        tokens.Blight.Init(initialCounts.Blight);           // don't use AddBlight because that pulls it from the card and triggers blighted island
    }
Beispiel #8
0
    static async Task EachInvaderReduceHealthByStrifeCount(TokenCountDictionary tokens, int minimum)
    {
        var strifedInvaders = tokens.Invaders()
                              .Where(x => 0 < x.StrifeCount)
                              .OrderBy(x => x.RemainingHealth)
                              .ToArray(); // get the lowest ones first so we can reduce without them cascading

        foreach (HealthToken strifedInvader in strifedInvaders)
        {
            await ReduceInvaderHealthByItsOwnStrife(tokens, strifedInvader, minimum);
        }
    }
Beispiel #9
0
    static async Task EachInvaderTakesDamageByStrifeCount(TokenCountDictionary tokens)
    {
        var strifedInvaders = tokens.Invaders()
                              .Where(x => 0 < x.StrifeCount)
                              .OrderBy(x => x.RemainingHealth)
                              .ToArray(); // get the lowest ones first so we can reduce without them cascading

        // !!! ??? Do badlands cause damage here?

        foreach (HealthToken strifedInvader in strifedInvaders)
        {
            await DamageInvaderHealthByItsOwnStrife(tokens, strifedInvader);
        }
    }
Beispiel #10
0
    /// <summary>
    /// Conditionally Removes an invader based on the Total # of invaders in a space
    /// </summary>
    static async Task RemoveInvaderWhenMax(FearCtx ctx, int invaderMax, params TokenClass[] removeableInvaders)
    {
        foreach (var spirit in ctx.Spirits)
        {
            var options = spirit.AllSpaces.Where(s => {
                TokenCountDictionary counts = ctx.GameState.Tokens[s];
                return(counts.HasAny(removeableInvaders) && counts.InvaderTotal() <= invaderMax);
            }).ToArray();
            if (options.Length == 0)
            {
                return;
            }

            await spirit.RemoveTokenFromOneSpace(options, 1, removeableInvaders);
        }
    }
Beispiel #11
0
    static async Task DamageInvaderHealthByItsOwnStrife(TokenCountDictionary tokens, HealthToken originalInvader)
    {
        var newInvader = originalInvader.AddDamage(originalInvader.StrifeCount);

        if (newInvader == originalInvader)
        {
            return;
        }

        if (newInvader.IsDestroyed)
        {
            await tokens.Destroy(originalInvader, tokens[originalInvader]);
        }
        else
        {
            tokens.Adjust(newInvader, tokens[originalInvader]);
            tokens.Init(originalInvader, 0);
        }
    }
Beispiel #12
0
    public async Task <string> Exec(
        BuildingEventArgs args,
        TokenCountDictionary tokens,
        GameState gameState
        )
    {
        if (!tokens.HasInvaders())
        {
            return("No invaders");
        }

        BuildingEventArgs.BuildType buildType = args.GetBuildType(tokens.Space);

        this.tokens    = tokens;
        this.buildType = buildType;
        this.gameState = gameState;

        if (await StopBuildWithDiseaseBehavior())
        {
            return(tokens.Space.Label + " build stopped by disease");
        }

        // Determine type to build
        int townCount = tokens.Sum(Invader.Town);
        int cityCount = tokens.Sum(Invader.City);
        HealthTokenClass invaderToAdd = townCount > cityCount ? Invader.City : Invader.Town;

        // check if we should
        bool shouldBuild = buildType switch {
            BuildingEventArgs.BuildType.CitiesOnly => invaderToAdd == Invader.City,
            BuildingEventArgs.BuildType.TownsOnly => invaderToAdd == Invader.Town,
            _ => true,
        };

        // build it
        if (shouldBuild)
        {
            await tokens.AddDefault(invaderToAdd, 1, AddReason.Build);
        }

        return(invaderToAdd.Label);
    }
Beispiel #13
0
    static async Task ReduceInvaderHealthByItsOwnStrife(TokenCountDictionary tokens, HealthToken originalInvader, int minimum)
    {
        int newHealth  = Math.Min(minimum, originalInvader.FullHealth - originalInvader.StrifeCount);
        var newInvader = new HealthToken(originalInvader.Class, newHealth, originalInvader.Damage, originalInvader.StrifeCount);

        if (newInvader == originalInvader)
        {
            return;
        }

        if (newInvader.IsDestroyed)
        {
            await tokens.Destroy(originalInvader, tokens[originalInvader]);
        }
        else
        {
            tokens.Adjust(newInvader, tokens[originalInvader]);
            tokens.Init(originalInvader, 0);
            // !!! Need something at end of turn to restore health.
        }
    }
Beispiel #14
0
 public BlightTokenBinding(TokenCountDictionary tokens) : base(tokens, TokenType.Blight)
 {
 }
 public DefendTokenBinding(TokenCountDictionary tokens)
 {
     this.tokens = tokens;
 }
 /// <summary> Clone / copy constructor </summary>
 public TokenCountDictionary(TokenCountDictionary src)
 {
     this.Space = src.Space;
     counts     = src.counts.Clone();
     tokenApi   = src.tokenApi;
 }
 static public string InvaderSummary(this TokenCountDictionary dict)
 {
Beispiel #18
0
 public static int DamageFromStrifedInvaders(TokenCountDictionary tokens)
 {
     return(tokens.Invaders().OfType <HealthToken>().Where(x => x.StrifeCount > 0).Sum(si => si.FullHealth * tokens[si]));
 }
Beispiel #19
0
 public InvaderBinding(TokenCountDictionary tokens, DestroyInvaderStrategy destroyStrategy)
 {
     this.Tokens          = tokens;
     this.DestroyStrategy = destroyStrategy;
 }
Beispiel #20
0
 static public int Sum(this TokenCountDictionary counts, TokenClass generic)
 => counts.OfType(generic).Sum(k => counts[k]);
Beispiel #21
0
 public DahanGroupBinding(TokenCountDictionary tokens, RemoveReason destoryReason = RemoveReason.Destroyed)
 {
     _tokens        = tokens;
     _tokenGroup    = TokenType.Dahan;
     _destroyReason = destoryReason;
 }
 public WreakVengeanceForTheLandsCorruption(TokenCountDictionary tokens) : base(tokens, TokenType.Badlands)
 {
     blight = new TokenBinding(tokens, TokenType.Blight);
 }
Beispiel #23
0
 static public Token[] OfType(this TokenCountDictionary counts, TokenClass healthyType)
 => counts.Keys.Where(specific => healthyType == specific.Class).ToArray();
Beispiel #24
0
 static public bool HasAny(this TokenCountDictionary counts, params TokenClass[] healthyInvaders)
 => counts.OfAnyType(healthyInvaders).Any();
Beispiel #25
0
 static public HealthToken[] OfAnyType(this TokenCountDictionary counts, params HealthTokenClass[] healthyTypes)
 => counts.Keys.Where(specific => healthyTypes.Contains(specific.Class)).Cast <HealthToken>().ToArray();
Beispiel #26
0
 public static TokenFrom1Space ForStrife(TokenCountDictionary tokens, params TokenClass[] groups)
 => new TokenFrom1Space("Add Strife",
                        tokens.Space,
                        (groups != null && groups.Length > 0) ? tokens.OfAnyType(groups) : tokens.Invaders(),
                        Present.Always
                        );
Beispiel #27
0
 static public int SumAny(this TokenCountDictionary counts, params TokenClass[] healthyInvaders)
 => counts.OfAnyType(healthyInvaders).Sum(k => counts[k]);
Beispiel #28
0
 static (int, HealthToken) GetDamageFromInvader(TokenCountDictionary tokens, HealthToken invader)
 {
     return(0 < invader.StrifeCount
                     ? (0, tokens.RemoveStrife(invader, 1))
                     : (invader.Class.Attack, invader));
 }
Beispiel #29
0
 static public bool Has(this TokenCountDictionary counts, TokenClass inv)
 => counts.OfType(inv).Any();
Beispiel #30
0
 public TokenBinding(TokenCountDictionary tokens, Token token)
 {
     this.tokens = tokens;
     this.token  = token;
 }