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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 16:36:03