如何为JavaScript Blackjack游戏编写统一的牌值计算函数?
解决Blackjack手牌值计算函数重复问题
你的两个手牌值计算函数核心逻辑完全一致,仅操作的数组和全局变量不同,我们可以将其重构为一个通用的纯函数,既避免重复代码,也让逻辑更清晰。同时原代码中存在两个小问题需要修正:
- 字符串分割错误:
card.slice("-")应该改为card.split("-"),slice用于截取字符串,split才是按分隔符分割字符串。 - 重复计算问题:原函数每次调用都会遍历整个手牌数组并累加,导致总点数被重复计算(比如玩家拿两张牌,总点数会被计算两次)。
重构后的通用函数
编写一个calculateHandValue函数,接收手牌数组作为参数,返回该手牌的总点数:
function calculateHandValue(cards) { let total = 0; cards.forEach(card => { const cardValue = card.split("-")[0]; if (cardValue === "A") { total += 11; // 后续可优化A的1/11切换逻辑,当前先按11计算 } else if (["J", "Q", "K"].includes(cardValue)) { total += 10; } else { total += parseInt(cardValue); } }); return total; }
替换原函数并修改调用逻辑
删除原来的getValuePlayerCards和getValueDealerCards,然后修改发牌函数的调用方式:
- 玩家发牌逻辑:
function dealCardstoPlayer() { for(let i = 0; i < 2; i++) { let cardImg = document.createElement("img"); const card = cards.pop(); playerCards.push(card); cardImg.src = "./cards/" + card + ".png"; document.getElementById("PlayerCardsShow").append(cardImg); } // 发完初始牌后统一计算总点数 playerHand = calculateHandValue(playerCards); console.log(`The player currently has ${playerHand}`); }
- 庄家发牌逻辑:
function dealCardstoDealer() { let cardImg = document.createElement("img"); hidden = cards.pop(); dealerCards.push(hidden); cardImg.src = "./cards/" + "BACK" + ".png"; document.getElementById("DealerHiddenCards").append(cardImg); do { const card = cards.pop(); dealerCards.push(card); const cardImg = document.createElement("img"); cardImg.src = "./cards/" + card + ".png"; document.getElementById("DealerCardsShow").append(cardImg); // 每次加牌后重新计算总点数 dealerHand = calculateHandValue(dealerCards); } while(dealerHand < 17); console.log(`The dealer currently has ${dealerHand}`); }
额外优化建议
- A牌的灵活计算:当前A都按11计算,但Blackjack中A可以算1或11,后续可以在通用函数中添加逻辑,当总点数超过21时,将A的11转为1。
- 减少全局变量依赖:可以将玩家和庄家的状态封装成对象(比如
const player = { cards: [], handValue: 0 }),让代码更模块化。
内容的提问来源于stack exchange,提问作者Newb2CodingCareer
相关产品推荐
相关产品推荐

