public override GameState ApplyEffect(GameState gameState, Player owner) { return(Card.EffectAppliers.Aggregate(gameState, (state, appl) => TypeSwitchExpr.On <EffectApplier, GameState>(appl) .Case <Targetable>(applier => applier.ApplyOn(state, owner, Target)) .Case <Targetless>(applier => applier.ApplyOn(state, owner, null)) .ElseThrow())); }
public GameState UpdateCharacter(Character oldChar, Character updatedChar) { return (TypeSwitchExpr.On <Character, GameState>(oldChar) .Case <Face>(oldFace => { var updatedFace = (Face)updatedChar; var updatedPlayerState = _playerGameStates.First(x => x.Face == oldFace).With(face: x => updatedFace); return With(updatedPlayerState); }) .Case <Minion>(oldMinion => { var updatedMinion = (Minion)updatedChar; var updatedPlayerState = _playerGameStates.First(x => x.Minions.Contains(oldMinion)).With(minions: x => x.Replace(oldMinion, updatedMinion)); return With(updatedPlayerState); }) .ElseThrow()); }
public GameState ApplyAction(GameState gameState, GameAction gameAction) { var newGameState = TypeSwitchExpr.On <GameAction, GameState>(gameAction) .Case <SummonBattlecryTargetable>(action => { var withMinionSummoned = SummonMinnion(gameState, action); return(action.ApplyEffect(withMinionSummoned, action.Owner)); }) .Case <SummonBattlecryTargetless>(action => { var minionToSummon = new Minion(action.Card); var withMinionSummoned = SummonMinnion(gameState, action, minionToSummon); return(action.ApplyBattlecry(withMinionSummoned, action.Owner, minionToSummon)); }) .Case <SummonAction>(action => SummonMinnion(gameState, action)) .Case <CastSpell>(action => { var handManaUpdated = CardPlayUpdateHandMana(gameState, action.Card, action.Owner); var withSpellApplied = action.ApplyEffect(handManaUpdated, action.Owner); return(withSpellApplied.PlayerEventOccured(new Event(EventType.SpellCasted, Target.FriendlyPlayer), action.Owner)); }) .Case <AttackAction>(action => TypeSwitchExpr.On <ITarget <Character>, GameState>(action.Target) .Case <Minion>(target => { var updatedAttacker = action.Attacker.RecieveDamage(target.Attack); var updatedTarget = target.RecieveDamage(action.Attacker.Attack); var withAttackerUpdated = gameState.UpdateCharacter(action.Attacker, updatedAttacker); var withBothUpdated = withAttackerUpdated.UpdateCharacter(target, updatedTarget); return(withBothUpdated); }) .Case <Face>(target => gameState.With(gameState.OfOpponent(action.Owner).With(face: x => x.RecieveDamage(action.Attacker.Attack)))) .ElseThrow()) .ElseThrow(); newGameState = ProcessChainReactions(newGameState); return(newGameState.RemoveDeadBodies()); }
public GameState ApplyOn(GameState gameState, Player owner, Minion caster) { return(Effects.Aggregate(gameState, (aggregState, eff) => TypeSwitchExpr.On <Effect, GameState>(eff) .Case <CharacterEffect>(effect => { var targets = GetValidTargets(aggregState, owner, caster).ToArray(); var updatedChars = targets.Select(x => effect.ApplyOn((ITarget <Character>)x)); return aggregState.UpdateCharacters(targets, updatedChars); }) .Case <NonCharacterEffect>(effect => { if (Target.HasFlag(Target.FriendlyPlayer)) { aggregState = effect.ApplyOn(aggregState, owner, caster); } if (Target.HasFlag(Target.EnemyPlayer)) { aggregState = effect.ApplyOn(aggregState, aggregState.OpponentOf(owner), caster); } return aggregState; }) .ElseThrow())); }