/**
* 创建基本卡组
*
* 思路
* 1. Array.from转化基本花色字符串为数组
* 2. 利用map进行初始化花色以及基本数字, 设置level属性为排序数组做准备
* 3. [].concat()平铺数组
* @returns {Array} 返回type长度的二维数组
*/
const createDeck = (function(){
const type = "♠♥♦♣" // 基本花色
const base = ["3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K", "A", "2"] // 牌组
return [].concat(...Array.from(type, item => {
return base.map( (v, key) => ({val: item + v, level: key}))
}), {val: "大王", level: 13}, {val: "小王", level: 13})
})()
/**
* 返回指定范围的随机数
*
* @param {number} [min] 最小值
* @param {number} [min] 最大值
* @returns {number} 数组下标
*/
function getRandom(min, max){
return Math.floor(Math.random() * (max - min) + min);
}
/**
* 生成随机卡组
*
* 思路
* 1. Array.from初始化卡组长度
* 2. 随机抽取数组元素
* 3. 根据level属性进行重排序
* @returns {Array} 返回len长度的随机数组
*/
function createGrop(len){
let cardNum = createDeck.length / len // 牌数
let copy = createDeck.concat() // 获取基本卡组, 通过concat解引
return Array.from({length: len}, () => {
const sortHandle = (a, b) => b.level - a.level; // 重排序方法
let _, arr = []
// 如果长度为最后立即返回,即后面的随机抽取已没意义
if(copy.length == 18) return copy.sort(sortHandle).map(v => v.val);
_ = function grop(){ // 自调用写法
if(arr.length == cardNum) return; // 达到指定手牌数即终止
let cur = getRandom(0, copy.length)
if(arr.map(v => v.val).includes(copy[cur].val)){ // 检测是否已存在
return grop() // 如果存在重新获取随机数
} else {
arr.push(copy[cur])
copy.splice(cur, 1) // 删除原数组中已被抽取的数子
grop()
}
}()
arr = arr.sort(sortHandle).map(v => v.val) // 重排序数组,并删除level属性
return arr
})
}
console.log(createGrop(3)) // -↓
/*
0: (18) ["大王", "♠2", "♣A", "♦K", "♣K", "♥K", "♥Q", "♣J", "♣10", "♥10", "♦8", "♦7", "♠6", "♥6", "♥4", "♠4", "♣3", "♠3"]
1: (18) ["小王", "♦2", "♥A", "♦A", "♠A", "♠K", "♣Q", "♠Q", "♠J", "♥J", "♦9", "♣9", "♥8", "♣7", "♣6", "♠5", "♣4", "♥3"]
2: (18) ["♥2", "♣2", "♦Q", "♦J", "♠10", "♦10", "♠9", "♥9", "♠8", "♣8", "♠7", "♥7", "♦6", "♥5", "♦5", "♣5", "♦4", "♦3"]
*/