Is there an elegant way to deal with the Ace in Bl

2019-01-15 06:57发布

My kiddo had a homework assignment to write Blackjack in Java. I helped him a little but for the most part he did it all himself and it actually plays pretty well. He even caught an error I didn't see in how it was calculating hand values. However, there is a snag that he hasn't dealt with and every solution I can think of is really complicated and way beyond what he's going to be able to easily code up with his still rudimentary Java skills.

The Ace. In fact, not just one Ace, there's four of them and you could possibly get all four of them in a single hand. How do you elegantly deal with calculating the value of a hand of cards when there's one or more Aces, each of which might be valued at one or eleven. I feel like there should be a graceful algorithm for it, but I'm not seeing it. Of course, part of it could just be that I'm tired, but maybe you can help.

7条回答
狗以群分
2楼-- · 2019-01-15 07:18

You will only ever use 1 ace for the 11 points. So calculate all but the last ace as 1 and if have 10 or less points, the last ace counts as 10.

查看更多
做自己的国王
3楼-- · 2019-01-15 07:19

Just treat each ace as 11. Then while the value is over 21, subtract 10 from your total for each ace in your hand.

查看更多
神经病院院长
4楼-- · 2019-01-15 07:22
short aces_count = 0;
short non_aces_sum = 0;
short global_sum = 0;

foreach card in _card:{
    if( card.value != 11 ){ // assuming ace value is 11
        if( card.value > 10 ) 
            non_aces_sum += 10;
        else
            non_aces_sum += card.value
    }else
        aces_count += 1;
}

short aces_sum = 0;
if( aces_count > 0) aces_sum = 11;

for(int i=0 ; i < aces_count - 1; i++){ // - 1 cuz already asigned first ace
    aces_sum += 1; // 2x aces == 22 so max 1 ace has value 11
}
if(aces_sum + non_aces_sum > 21)
    aces_sum = aces_count; // no need for an 11 value ace, so all are 1

global_sum = non_aces_sum + aces_sum;
查看更多
叛逆
5楼-- · 2019-01-15 07:22

The problem is that it's not determined: you can count (as I understand the rules) an Ace as either 1 or 11. But you know you're not going to count it as 11 every time, because you'll bust.

The only solution I think is to compute the score for each possible value of the ace where the sum <= 21.

查看更多
冷血范
6楼-- · 2019-01-15 07:35

Only 1 Ace ever counts as 11.

So, an alternative method to treating each Ace as 11 would be to treat every Ace as 1. Then add 10 to the total value ( carried regardless of Ace on hand ) and keep that in a separate "high" variable ( value + 10 ). Also create a boolean of ~ ace:true if (any) ace comes up.

And so when checking the score against the dealer; check if the players' hand has (any) Ace, in which case you ( can ) use the "high" value, otherwise ( no Ace ) use the "low" value.

That way King + 9 + Ace ( bad example perhaps ) would be ~ low:20 & high:30 & ace:true - With that information you can check if 30 - 10 will "win the game". So, King + 5 + 5 ( low:20 high:30 ace:false ) will not use it's high value of 30.

I'm using this method so I know when to show an alt. Ace score onscreen; like 3/13 ( Ace + 2 ), using the same ace:true|false boolean I already have. This is surely the same answer as the first one given, but this makes more sense to me :)

查看更多
祖国的老花朵
7楼-- · 2019-01-15 07:36

Similar to elundmark's answer...

You've most likely got a method that evaluates a blackjack hand value. Always value aces at one point. If a hand contains an ace, compute a hard value (all aces are ones, +10) and a soft value (all aces ones).

If the hard value is not a bust, return the hard value. If the hard value is a bust, return the soft value.

example 1
2, A, A
hard value 2 + 1 + 1 + 10 = 14
soft value = 2 + 1 + 1 = 4

hard value < 21, so return hard value (hand value is 14)

example 2
2, A, A, 8
hard value = 2 + 1 + 1 + 8 + 10 = 22 (bust)
soft value = 2 + 1 + 1 + 8 = 12

hard value > 21, so return soft value (hand value is 12)

Traditional thinking about the rules and the way the game is played, is that an Ace's value is conditional and can have two values, 1 or 11. This concept is difficult to implement. It's much easier on a programmer to count all Aces as a value of one and conditionally add 10 points to the hand value. That way your Card's Rank or Value implementation can remain rigid and straightforward. I've experimented with this before by returning a collection of values and a couple other methods. It's a pain, and not worth it for just the one Ace rank.

If you want to show an alt on the screen like 2/12, instead of returning an Integer, just return a "BlackjackValue" object that contains an Integer and a String object that you create in the method that evaluates your hand value.

查看更多
登录 后发表回答