Tuple <int, ImmutableStack <TurnAction> > _HandleTurn(bool partB, CharacterSet set, Tuple <int, ImmutableStack <TurnAction> > minActions, Tuple <int, ImmutableStack <TurnAction> > actionsSoFar) { set.DoNextTurn(partB); if (!set.Player.IsAlive) { return(Tuple.Create(int.MaxValue, ImmutableStack <TurnAction> .Empty)); } if (!set.Boss.IsAlive) { return(actionsSoFar); } set.ProcessEffects(); if (!set.Player.IsAlive) { return(Tuple.Create(int.MaxValue, ImmutableStack <TurnAction> .Empty)); } if (!set.Boss.IsAlive) { return(actionsSoFar); } switch (set.WhoseTurn) { case WhoseTurn.BossTurn: set.Boss.Attack(set.Player); return(_HandleTurn(partB, set, minActions, Tuple.Create(actionsSoFar.Item1, actionsSoFar.Item2.Push(TurnAction.BossAttack)))); case WhoseTurn.PlayerTurn: foreach (var effect in _Effects) { if (set.Player.Mana < effect.Mana) { continue; } if (set.Player.Effects.Select(e => e.Effect).Contains(effect)) { continue; } var testSet = set.Clone(); testSet.Player.Cast(effect, testSet.Boss); var testCost = actionsSoFar.Item1 + effect.Mana; if (testCost > minActions.Item1) { continue; } var playCost = _HandleTurn(partB, testSet, minActions, Tuple.Create(testCost, actionsSoFar.Item2.Push(effect.TurnAction))); if (playCost.Item1 < minActions.Item1) { minActions = playCost; } } return(minActions); default: throw new InvalidOperationException("Should Never Happen."); } }