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,导致总值异常。
此外还有两处小问题:
- 函数末尾返回
NULL不符合bool类型要求,bool只能返回true或false,且当前逻辑分支已覆盖所有情况,该返回语句冗余。 - 原代码仅处理了一张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
相关产品推荐
相关产品推荐

