JavaScript纸牌游戏开发:如何实现卡牌被选中后不再被重复抽取?
卡牌不重复抽取实现方案
我们采用预构建完整可用牌库+抽牌后移除元素的方案实现不重复抽卡,相比生成后校验重抽的逻辑效率更高,避免多次无效随机计算。
改动说明
- 移除原函数内每次执行都合并卡牌数组的逻辑,改为全局一次性初始化完整牌库,牌库中存储所有完整卡牌文件名(不带路径后缀)
- 抽卡时直接从可用牌库随机取元素,取到后立即将该元素从可用牌库中移除,从根源避免重复抽取
- 增加牌库空判断,避免无牌可抽时报错
修改后完整代码
// 全局变量区域 新增可用牌库初始化逻辑,需在generateNumber执行前运行 let availableCards = []; const usedCard = []; // 保留你原有的各卡牌数组定义即可,示例如下: // const cardArray = ['H','S','C','D']; // 普通牌花色:红桃/黑桃/梅花/方块 // const acesArray = ['AH','AS','AC','AD']; // A类牌 // const jackArray = ['JH','JS','JC','JD']; // J类牌 // const kingArray = ['KH','KS','KC','KD']; // K类牌 // const queenArray = ['QH','QS','QC','QD']; // Q类牌 // 初始化完整可用牌库,全局仅需运行一次 function initCardDeck() { // 拼接2-10的普通数字牌 for (let num = 2; num <=10; num++) { cardArray.forEach(suit => { availableCards.push(`${num}${suit}`) }) } // 拼接特殊牌 availableCards = availableCards.concat(acesArray, jackArray, kingArray, queenArray); } // 页面加载完成后先执行初始化牌库 initCardDeck(); // 修改后的抽牌函数 function generateNumber() { // 牌库为空时终止执行 if (availableCards.length === 0) { alert('所有卡牌已抽取完毕'); return; } // 从可用牌库随机生成索引 const randomIndex = Math.floor(Math.random() * availableCards.length); // 取出卡牌的同时从可用牌库移除该卡牌,避免重复抽取 const pickedCard = availableCards.splice(randomIndex, 1)[0]; // 拼接图片路径 const cardToShow = `PNG/${pickedCard}.png`; console.log(`The card slot with id: '${selectedSlot}' was selected! The new card file path to show is: ${cardToShow}`); // 更新卡牌显示 const changeImgSrc = document.getElementById(selectedSlot); changeImgSrc.src = cardToShow; // 存入已用卡牌数组,可保留用于后续业务逻辑 usedCard.push(pickedCard); console.log(usedCard); }
内容的提问来源于stack exchange,提问作者natia
相关产品推荐
相关产品推荐

