我在C#中实现了一个小Black Jack游戏,我在计算玩家的手牌值时遇到以下问题。根据玩家的手牌,A值可能为1或11。如果玩家有三张牌和一张牌,那么如果牌的总和<= 10,则牌的值为11,否则值为1.
现在让我们假设我不知道玩家获得了多少个游戏并且实施了游戏,这使得经销商可以使用多张牌。用户可以用一只手甚至5,6,7,8 ... aces。
最好的方式(可能使用Linq)评估玩家获得最接近21的所有a(除了其他牌之外)的最佳方式是什么?
我知道玩家的牌,我想计算他们的价值,使用A来达到最接近21的值。
答案 0 :(得分:3)
看起来并不那么复杂,
sum <= 10
:所以你检查假设一个ace可以被认为是11的两个结果:sum + 11 + (numAces-1)*1 <= 21
,那么这是最接近21的值,否则sum + numAces*1
(因为使用ace作为11会溢出)sum > 10
:您可以将Aces视为1,因此最终值为sum + numAces*1
(从未使用 C#所以这个答案是元代码)
答案 1 :(得分:2)
添加所有非a的值并添加a的数量:2,Q,A,A = 2 + 10 +(2)= 14
然后从21:21-14 = 7
减去这个数字是否小于10(如果只有1个ace == 11)?少于20(如果两个A = = 11)?
因为这感觉就像家庭作业一样,故意不是完整的答案,而是应该引导你。
答案 2 :(得分:0)
如上所述,您应该能够使用Aggregate扩展方法实现此功能。编写一个实现算法的函数并使用它:
IEnumerable<int> cards = // card values
var f = (int i1, int i2) => // implement algorithm here
var result = cards.Aggregate(f);
答案 3 :(得分:0)
从我的角度来看,你必须考虑这样一个事实:当玩家有一个或多个A时,他或她在任何给定的时间都有两个可能的分数。试图计算最接近的单个值到21岁是对二十一点中持有王牌的意义的错误抽象。
作为一名玩家,我不希望程序告诉我,当我拥有ace&amp; 5,因为我可能不会打16,但如果我有ace&amp; 5我绝对会接受这个打击。从概念上讲,我确实有6个 或 16。
我认为手的价值应该可以表示为一个或两个值。显然,在没有王牌的情况下,只有一个值。同样地,当ace-as-eleven意味着被击败的手时,手牌只有一个值,因为ace 必须被计为1.你也可以说任何ace + 10组合只有一个值,因为那是即时二十一点。
这是一个部分实现 - 许多方法之一,皮肤这猫。我这样写它是为了让你以某种方式思考;因为只有a只能有一个以上的值而且给定的手最多可以有两个可能的值,所以这可以更简洁地完成。
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;
}
}
答案 4 :(得分:0)
以这种方式考虑它可能是最简单的 - 每张牌都会将牌值加到总计数牌为11.如果牌是王牌,并且牌手被击败,则扣除10。 示例:
int total = 0;
...
int hit = GetHit();
total = total + hit;
if (total > 21 && hit == 11)
{
total = total - 10
}
// check if player busted, etc
在您的初始交易中,您可以使用GetHit()“处理”这些卡片,或者自己动手处理Ace-Ace(只有2张卡片的问题情况)。这将始终为您提供最高的手。我认为可以认为球员知道一个ace可以是1或11,所以用Ace-5击球将永远不会让球员摔倒。