2026-01-12 14:53:32
真·扑克牌洗牌算法实现
要实现一个真·扑克牌洗牌算法,我们可以参考前端西瓜哥的实现方法,该方法包括获取一副完整的牌和洗牌两个主要步骤。以下是详细的实现步骤和代码示例:
获取一副完整的牌:
使用字符串来表示每张牌,例如“3_0”表示黑桃3,“J_3”表示方块J。
牌的大小用数组表示:const nums = [3, 4, 5, 6, 7, 8, 9, 10, 'J', 'Q', 'K', 'A', 2];
牌的花色用数字表示:const types = [0, 1, 2, 3];(分别代表黑桃、红心、梅花、方块)
大小王用特殊字符表示,例如'M'和'N'。
实现获取牌的函数:
使用闭包来缓存生成的牌数组,以提高性能。
返回缓存数组的拷贝,以避免直接引用缓存数组。
实现洗牌算法:
使用Fisher-Yates洗牌算法,该算法通过从后向前遍历数组,并随机交换元素来实现洗牌。
洗牌算法的时间复杂度为O(n),空间复杂度为O(1)。
实现排序算法:
在斗地主游戏中,可能需要将洗好的牌重新排序。
排序规则:牌的大小从大到小,相同大小的牌按花色排序(黑桃、红心、梅花、方块)。
使用自定义的等价值计算方法来进行排序。
以下是完整的代码实现:
// 获取一副完整的牌const getCards = (() => { let cacheCards; return () => { if (cacheCards) return [...cacheCards]; const nums = [3, 4, 5, 6, 7, 8, 9, 10, 'J', 'Q', 'K', 'A', 2]; const types = [0, 1, 2, 3]; cacheCards = nums.reduce((cards, num) => { types.forEach(type => { cards.push(`${num}_${type}`); }); return cards; }, []); cacheCards.push('M', 'N'); // 大小王 return [...cacheCards]; };})();// 洗牌算法function shuffle(arr) { for (let i = arr.length - 1; i > 0; i--) { const randIdx = Math.floor(Math.random() * (i + 1)); [arr[i], arr[randIdx]] = [arr[randIdx], arr[i]]; }}// 获取随机整数function getRand(min, max) { return Math.floor(Math.random() * (max - min + 1)) + min;}// 获取洗好的牌function getShuffledCards() { const cards = getCards(); shuffle(cards); return cards;}// 排序算法function sortCards(cards) { function getEqualVal(s) { if (s === 'M') return 9999999; if (s === 'N') return 999999; let [num, type] = s.split('_'); if (num === 'J') num = 11; if (num === 'Q') num = 12; if (num === 'K') num = 13; if (num === 'A') num = 14; if (num === '2') num = 15; return parseInt(num) * 10 - parseInt(type); } cards.sort((a, b) => getEqualVal(b) - getEqualVal(a));}// 斗地主发牌和排序示例function doudizhu() { const cards = getShuffledCards(); const dizhuCards = cards.splice(0, 3); // 地主的额外三张牌 const playerCards = []; // 均分剩下的牌 playerCards[0] = cards.splice(0, Math.floor(cards.length / 3)); playerCards[1] = cards.splice(0, Math.floor(cards.length / 2)); playerCards[2] = cards; // 排序 playerCards.forEach(cards => sortCards(cards)); console.log('地主牌:', dizhuCards); console.log('玩家牌:', playerCards);}// 执行斗地主发牌doudizhu();代码说明:
通过以上步骤和代码,我们可以实现一个完整的扑克牌洗牌和排序算法,适用于斗地主等纸牌游戏。