JavaScript实现BlackJack21点游戏函数返回undefined及逻辑错误排查
错误定位&修复方案
1. 控制台返回undefined的原因
checkBlackjack函数仅在抽牌分支有return语句,其余场景(如双方初始就有BlackJack、Sam初始点数≥17、胜负判定等)都无返回值,JavaScript无返回值的函数默认返回undefined,你最后执行console.log(checkBlackjack())自然会打印undefined。- 你把
return写在了抽牌的while循环内部,抽1次牌就直接终止整个函数,后续的爆牌判定、庄家抽牌、胜负判定逻辑完全不会执行,也会导致大量场景无输出、返回undefined。
2. 程序异常卡住的原因
getRandomCard函数生成随机索引时固定乘以52,但你每次抽牌都会用splice删除牌堆元素,牌堆长度会持续减小,当随机索引≥当前牌堆长度时,splice返回空数组,取[0]就会得到undefined,点数累加undefined会变成NaN,后续所有数值比较逻辑全部失效,就会出现逻辑卡死的情况。- 庄家抽牌的循环条件写反了:规则要求庄家点数小于等于Sam点数时需要抽牌,直到超过Sam为止,你写的是
while (dealerPoints > samPoints),也就是庄家点数比Sam大的时候才抽,这种情况会一直抽牌直到爆牌,叠加NaN问题就会出现持续运行的异常。
3. 其他逻辑错误
- BlackJack判定顺序错误:你先判断单方是否为21点,最后才判断双方同时为21点,导致平局场景永远触发不了,正确顺序应该先判断双方同时21点,再判断单方。
- Sam抽牌逻辑错误:循环内加
return导致最多抽1次牌,不符合"抽到17点及以上才停止"的要求。 - 最终胜负判定缺失:双方都抽完牌且都未爆牌的场景,你没有做点数比较的判定逻辑。
修复后的完整代码
const cards = [2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 10, 10, 11]; const deckOfCards = [...cards, ...cards, ...cards, ...cards]; let samPoints = 0; let dealerPoints = 0; function getRandomCard() { // 随机数范围取当前牌堆的长度,避免索引越界 const randomCard = Math.floor(Math.random() * deckOfCards.length); const pickedCard = deckOfCards.splice(randomCard, 1)[0]; return pickedCard; } // 初始化手牌 samPoints += getRandomCard(); samPoints += getRandomCard(); dealerPoints += getRandomCard(); dealerPoints += getRandomCard(); console.log("Sam初始点数:", samPoints); console.log("Dealer初始点数:", dealerPoints); function checkBlackjack() { // 先判断同时BlackJack的平局场景 if (samPoints === 21 && dealerPoints === 21) { console.log("平局"); return; } // 再判断单方BlackJack场景 if (samPoints === 21) { console.log("Sam wins!"); return; } if (dealerPoints === 21) { console.log("Dealer wins"); return; } // Sam抽牌逻辑:抽到≥17停止 while (samPoints < 17) { samPoints += getRandomCard(); console.log("Sam抽牌,当前点数:", samPoints); } // Sam抽完先判断是否爆牌 if (samPoints > 21) { console.log("Sam爆牌,Dealer wins. Game over"); return; } // 庄家抽牌逻辑:抽到超过Sam点数停止 while (dealerPoints <= samPoints) { dealerPoints += getRandomCard(); console.log("Dealer抽牌,当前点数:", dealerPoints); } // 判断庄家是否爆牌 if (dealerPoints > 21) { console.log("Dealer爆牌,Sam wins. Game over"); return; } // 双方都未爆牌,比较点数 if (dealerPoints > samPoints) { console.log("Dealer wins"); } else { console.log("Sam wins"); } } // 函数本身已经内部打印结果,不需要再包一层console.log checkBlackjack();
内容的提问来源于stack exchange,提问作者Oriana Abreu
相关产品推荐
相关产品推荐

