/// <summary>
        /// Throw again if the heuristic thinks you can still benefit from it
        /// Else take the highest worm value available
        /// </summary>
        /// <returns></returns>
        protected override bool HandleThrowing()
        {
            var valueToTake = RainyWorm.All.Where(w => Flow.CanTakeRainyWorm(w)).OrderByDescending(w => w.ThrowValue).FirstOrDefault();

            if (ShouldTakeWorm(valueToTake))
            {
                Flow.TakeRainyWorm(valueToTake);
                return(true);
            }
            return(false);
        }
 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();
 }