/// <summary>
        /// Takes the best value according to the heuristic
        /// </summary>
        protected override void HandleTaking(IEnumerable <RainyDiceValue> thrownValues)
        {
            // pick the best according to CalcVal heuristic
            var val = thrownValues.Aggregate((v1, v2) =>
                                             TakeValueScore(v1) >
                                             TakeValueScore(v2) ?
                                             v1 : v2);

            ThrowFlow.TakeValue(val);
        }
 public void Play(GameFlow flow)
 {
     InitPlay(flow);
     if (Flow.CurrentPlayer.IsHuman)
     {
         throw new InvalidOperationException("Don't use computer logic for a human");
     }
     do
     {
         if (ThrowFlow.State == ThrowFlowState.Throwing)
         {
             if (RainyWorm.All.Any(w => Flow.CanTakeRainyWorm(w)))
             {
                 if (HandleThrowing())
                 {
                     return; // Stop when a rainyworm was taken
                 }
             }
             ThrowFlow.ThrowDices();
         }
         else if (ThrowFlow.State == ThrowFlowState.Taking)
         {
             // distinct thrown values that are not thrown yet
             var thrownValues = ThrowFlow.DicesToThrow
                                .Select(d => d.LastThrowDiceValue)
                                .Distinct()
                                .Where(thrown => ThrowFlow.DicesTaken.Select(d => d.LastThrowDiceValue).All(taken => taken != thrown));
             // check if there are any left to pick
             if (thrownValues.Any())
             {
                 HandleTaking(thrownValues);
             }
         }
     } while (ThrowFlow.CanStillThrowOrTake);
     Flow.TakeNothing();
 }