You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Blackjack函数计算异常求助:数值累加错误排查

21点(Blackjack)计算函数数值异常问题

需求背景

实现overTwentyOne函数,接收卡牌数组后判断手牌总值是否超过21:超过返回true,否则返回false。卡牌规则:

  • 2-10牌面对应自身数值
  • J、Q、K每张计10点
  • A可计1或11点,采用保守策略:若计11会使总值超21则计1

测试用例:

  • overTwentyOne({'A', '2', '3'})
  • overTwentyOne({'A', 'J', 'K'})
  • overTwentyOne({'A', 'J', 'K', 'Q'})
  • overTwentyOne({'5', '3', '6', '6', '7', '9'})

异常现象

编写的C++代码中,player1和player4的计算结果完全错误:数字牌累加时数值异常,例如player1的'2'累加后总值变为61,'3'累加后变为112;player4的'5'累加后总值为53,后续数字牌累加数值持续异常。

原代码

#include <iostream>
#include <vector>
using namespace std;
bool overTwentyOne(std::vector<char> cards);
int main()
{
    int player_1 = 10;
    int player_2 = 10;
    int player_3 = 10;
    int player_4 = 10;
    
    std::vector<char> player1 = {'A', '2', '3'};
    std::vector<char> player2 = {'A', 'J', 'K'};
    std::vector<char> player3 = {'A', 'J', 'K', 'Q'};
    std::vector<char> player4 = {'5', '3', '6', '6', '7', '9'};
    
    cout << "Player 1\n";
    player_1 = overTwentyOne(player1);
    cout << player_1;
    cout << "Player 2\n";
    player_2 = overTwentyOne(player2);
    cout << player_2;
    cout << "Player 3\n";
    player_3 = overTwentyOne(player3);
    cout << player_3;
    cout << "Player 4\n";
    player_4 = overTwentyOne(player4);
    cout << player_4;
}

bool overTwentyOne(std::vector<char> cards) {
    int player_total = 0;
    bool ace_in_play = false;
    
    // iterate thru vector
    for (int i = 0; i < cards.size(); i++) {
        //check for face card
        if (cards[i] == 'J'|| cards[i] == 'Q' || cards[i] == 'K') {
            player_total = player_total + 10;
        }
        //check for ace
        else if (cards[i] == 'A') {
            player_total = player_total + 11;
            ace_in_play = true;

        }
        //add number cards
        else 
        {
            player_total = player_total + cards[i];
        }
        
    }
    
    //verifies that the player hand is NOT over 21
    if (player_total <= 21) {
        return false;
    }
    
    //verifies that playe hand is over 21
    else if (player_total > 21) {
        //makes sure that player doesnt have a ace and if not the player will be over 21
        if (ace_in_play == false) {
            return true;
        }
        //checks to see if the ace is worth 1, whether or not the player is still over 21
        else if (ace_in_play == true) {
            player_total -= 10;
            if (player_total <= 21) {
                return false;
            }
            else{ 
            return true;
            }
        }
    }
    return NULL;
}

错误分析

核心问题是数字牌的类型转换错误:代码中直接将char类型的卡牌值(如'2')加到player_total中,而'2'的ASCII码值是50,实际加的是ASCII码而非对应的数字2,导致总值异常。

此外还有两处小问题:

  1. 函数末尾返回NULL不符合bool类型要求,bool只能返回true或false,且当前逻辑分支已覆盖所有情况,该返回语句冗余。
  2. 原代码仅处理了一张A的调整,若手牌中有多张A,无法正确依次调整取值(比如两张A的情况,初始加22,超21后应减10变为12)。

修复后的代码

#include <iostream>
#include <vector>
using namespace std;
bool overTwentyOne(std::vector<char> cards);
int main()
{
    int player_1 = 10;
    int player_2 = 10;
    int player_3 = 10;
    int player_4 = 10;
    
    std::vector<char> player1 = {'A', '2', '3'};
    std::vector<char> player2 = {'A', 'J', 'K'};
    std::vector<char> player3 = {'A', 'J', 'K', 'Q'};
    std::vector<char> player4 = {'5', '3', '6', '6', '7', '9'};
    
    cout << "Player 1\n";
    player_1 = overTwentyOne(player1);
    cout << player_1 << "\n";
    cout << "Player 2\n";
    player_2 = overTwentyOne(player2);
    cout << player_2 << "\n";
    cout << "Player 3\n";
    player_3 = overTwentyOne(player3);
    cout << player_3 << "\n";
    cout << "Player 4\n";
    player_4 = overTwentyOne(player4);
    cout << player_4 << "\n";
}

bool overTwentyOne(std::vector<char> cards) {
    int player_total = 0;
    int ace_count = 0;
    
    // 遍历卡牌计算初始总值
    for (char card : cards) {
        if (card == 'J' || card == 'Q' || card == 'K') {
            player_total += 10;
        } else if (card == 'A') {
            player_total += 11;
            ace_count++;
        } else {
            // 将字符转换为对应的数字:ASCII码中数字字符连续,减去'0'得到实际数值
            player_total += (card - '0');
        }
    }
    
    // 调整A的取值,直到总值不超21或没有A可调整
    while (player_total > 21 && ace_count > 0) {
        player_total -= 10;
        ace_count--;
    }
    
    return player_total > 21;
}

内容的提问来源于stack exchange,提问作者JerRat

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 11:15:38