/// <summary>
 /// Max of  - worm after taking value
 ///         - estimated throwscore after taking
 /// </summary>
 protected override double TakeValueScore(RainyDiceValue dv) {
     var toThrow = ThrowFlow.DicesToThrow.Count(d => d.LastThrowDiceValue != dv);
     var thrown = ThrowFlow.DicesToThrow.Count(d => d.LastThrowDiceValue == dv);
     var newCurrentTotal = ThrowFlow.TotalTakenValue + (thrown * dv.DiceValue);
     var availableValues = ThrowFlow.DicesToThrow.Select(d => d.LastThrowDiceValue).Where(d => d != dv).Distinct();
     return Math.Max(CalcScoreForThrownValue(newCurrentTotal),
         CalcScore(toThrow, newCurrentTotal, availableValues));
 }
 /// <summary>
 /// Takes all dices with the given value
 /// </summary>
 /// <param name="value"></param>
 public void TakeValue(RainyDiceValue value)
 {
     if(State != ThrowFlowState.Taking)
     {
         throw new InvalidOperationException("You can not take dices while you are not in the taking state");
     }
     if (!CanTakeValue(value))
     {
         throw new InvalidOperationException("The value "+value+" can not be taken.");
     }
     _dicesTaken.AddRange(_dicesToThrow.Where(d => d.LastThrowDiceValue == value));
     _dicesToThrow.RemoveAll(d => d.LastThrowDiceValue == value);
     State = ThrowFlowState.Throwing;
     ResetThrownDice();
 }
 /// <summary>
 /// Checks it if is possible to take a specific value
 /// </summary>
 /// <param name="value"></param>
 /// <returns>
 /// True if - The value is thrown
 ///         - The value is not already taken
 ///  </returns>
 public bool CanTakeValue(RainyDiceValue value) {
     return State == ThrowFlowState.Taking
         && _dicesTaken.All(d => d.LastThrowDiceValue != value)
         && _dicesToThrow.Any(d => d.LastThrowDiceValue == value);
 }
 /// <summary>
 /// Resets the current dice
 /// </summary>
 public void Reset()
 {
     LastThrowDiceValue = null;
 }
 /// <summary>
 /// Throws the dice and returns the thrown value, uniformly random
 /// </summary>
 /// <remarks>To recheck the result, the LastThrownDiceValue can be checked</remarks>
 /// <returns>The thrown value</returns>
 public RainyDiceValue ThrowDice()
 {
     LastThrowDiceValue = RainyDiceValue.GetBySequence(_rnd.Next(RainyDiceValue.Count));
     return LastThrowDiceValue;
 }
 /// <summary>
 /// Resets the current dice
 /// </summary>
 public void Reset()
 {
     LastThrowDiceValue = null;
 }
 /// <summary>
 /// Throws the dice and returns the thrown value, uniformly random
 /// </summary>
 /// <remarks>To recheck the result, the LastThrownDiceValue can be checked</remarks>
 /// <returns>The thrown value</returns>
 public RainyDiceValue ThrowDice()
 {
     LastThrowDiceValue = RainyDiceValue.GetBySequence(_rnd.Next(RainyDiceValue.Count));
     return(LastThrowDiceValue);
 }
 /// <summary>
 /// returns a score that will be used to determine which dicevalue should be taken ideally
 /// The highest will be taken from these that are still available
 /// </summary>
 protected abstract double TakeValueScore(RainyDiceValue dv);
 protected override double TakeValueScore(RainyDiceValue dv)
 {
     return dv.SequenceNumber; // take the one with the heigesht sequence number
 }