如何用JavaScript按输入人数均分洗牌后的扑克牌并动态填充Div
发牌功能实现方案
核心是把原来的“逐张牌直接输出”的逻辑,替换为按轮次逐张分发给玩家、聚合后再渲染的逻辑,无需手动计算每个玩家该分多少张。
关键实现要点
- 把输入框拿到的字符串值显式转为整数,避免JS隐式转换带来的判断异常
- 按照用户输入的玩家人数,初始化对应长度的二维数组,每个子数组用来存单个玩家的手牌
- 遍历洗好的牌堆,按「当前牌在牌堆中的索引 对 玩家人数取模」的规则,把牌放到对应玩家的手牌数组里,本质就是模拟真实扑克逐张轮转发牌的流程
- 渲染时从第1个玩家循环到最后1个玩家,不管手牌是否为空都逐行输出,自然就兼容了人数超过52的场景
当前代码的缺失点
现有实现已经覆盖了牌堆生成、洗牌逻辑,但发牌环节的循环仅将单张牌独立渲染为段落,没有按玩家维度做分组聚合,无法得到按人拆分的结果。
修改后的JavaScript核心代码
function shuffleCards() { // 获取输入值,显式转为10进制整数 const playerCount = parseInt(document.getElementById("number_of_people").value.trim(), 10); // 定义牌型、牌值常量 const card_types = ["S", "D", "C", "H"]; const card_values = ["A", "2", "3", "4", "5", "6", "7", "8", "9", "X", "J", "Q", "K"]; // 生成完整52张牌的牌堆 let deck = []; for (let typeIdx = 0; typeIdx < card_types.length; typeIdx++) { for (let valIdx = 0; valIdx < card_values.length; valIdx++) { deck.push(`${card_types[typeIdx]}-${card_values[valIdx]}`); } } // 输入合法性校验 if (isNaN(playerCount) || playerCount <= 0 || playerCount > 99) { $(".results").html(`<h3>Input value does not exist or value is invalid</h3>`); return; } // 保留原有Fisher-Yates洗牌逻辑 for (let i = deck.length - 1; i > 0; i--) { let j = Math.floor(Math.random() * i); let temp = deck[i]; deck[i] = deck[j]; deck[j] = temp; } // 初始化每个玩家的手牌列表,长度和玩家人数一致 const playerHands = Array.from({ length: playerCount }, () => []); // 逐张轮转发牌 deck.forEach((card, cardIndex) => { // 每张牌按索引取模,计算要分给哪个玩家 const targetPlayer = cardIndex % playerCount; playerHands[targetPlayer].push(card); }); // 清空原有结果 $(".results").html(``); // 逐行渲染每个玩家的手牌 playerHands.forEach((hand, idx) => { const handContent = hand.join(", "); $(".results").append(`<p>Person ${idx + 1} : ${handContent}</p>`); }); }
实现效果
- 输入人数为3时,牌逐张轮流转给3位玩家,每位玩家的手牌用逗号连接,输出格式和需求示例完全一致
- 输入人数超过52时,前52位玩家各分得1张牌,第53位及之后的玩家手牌为空,渲染时自动输出对应空行,无需额外做边界判断
- 这种发牌逻辑是扑克牌的标准公平规则:52张牌分给n个玩家时,会有
52 % n个玩家多拿1张牌,其余玩家获得等量手牌
内容的提问来源于stack exchange,提问作者M.Izzat
相关产品推荐
相关产品推荐

