私の見解では、プレーヤーが 1 つ以上のエースを持っている場合、いつでも 2 つの可能なスコアを持っているという事実を説明する必要があります。21 に最も近い単一の値を計算しようとすることは、ブラックジャックでエースを保持することの意味を誤って抽象化したものです。
プレーヤーとして、私はエースと 5 を持っているときに 16 を持っているとプログラムに言われたくありません。なぜなら、16 でヒットしないかもしれないからです。 . 概念的には、私は実際に 6つまたは16 を持っています。
ハンドの値は、1 つまたは 2 つの値として表現できるべきだと思います。明らかに、エースがない場合、値は 1 つだけになります。同様に、ace-as-eleven がバステッド ハンドを意味する場合、そのエースは 1 としてカウントされる必要があるため、そのハンドには 1 つの値しかありません。また、任意のエース + 10 の組み合わせには 1 つの値しかないとも言えます。これはインスタントであるためです。ブラックジャック。
これは部分的な実装です。この猫の皮を剥ぐための非常に多くの方法の 1 つです。このように書いたのは、あなたに特定の方法で考えてもらうためです。ただし、複数の値を持つことができるのはエースだけであり、与えられたハンドは最大 2 つの可能な値を持つことができるため、これはもっと簡潔に行うことができます。
public interface Hand
{
IEnumerable<int> PossibleValues { get; set; }
}
public interface Card
{
CardValues PossibleValues { get; set; }
}
public interface CardValues
{
int Value1 { get; }
int Value2 { get; }
}
public class BlackjackHand : Hand
{
IList<Card> cards;
public IEnumerable<int> PossibleValues
{
IList<int> possible_values = new List<int>();
int initial_hand_value = cards.Sum(c => c.Value1);
if(initial_hand_value <= 21)
{
possible_values.Add(initial_hand_value);
yield return initial_hand_value;
}
foreach(Card card in cards.Where(c => c.Value2 > 0))
{
IList<int> new_possible_values = new List<int>();
foreach(int value in possible_values)
{
var alternate_value = value + card.Value2;
if(alternate_value <= 21)
{
new_possible_values.Add(alternate_value);
yield return alternate_value;
}
}
possible_values.AddRange(new_possible_values);
}
yield break;
}
}