js-斗地主发牌算法

最近对websocket模块非常感兴趣,想做一个联机游戏练练手,于是萌生了自己动手尝试的想法。

由于对网上直接找来的js斗地主代码看起来有些头大, 不如就从零开始做一个试试,核心依赖random函数。

今天做的是洗牌算法

首先新建一个存放扑克牌的数组;每张扑克牌为一个对象,type1~4为方块桃心梅花黑桃,value大小表示牌面大小,name作为扑克牌代名一些不需要的就没加这个属性,status作为预留字段。

let pokeArr1 = [
    {type:1,value:3,status:0},{type:2,value:3,status:0},{type:3,value:3,status:0},{type:4,value:3,status:0},
    {type:1,value:4,status:0},{type:2,value:4,status:0},{type:3,value:4,status:0},{type:4,value:4,status:0},
    {type:1,value:5,status:0},{type:2,value:5,status:0},{type:3,value:5,status:0},{type:4,value:5,status:0},
    {type:1,value:6,status:0},{type:2,value:6,status:0},{type:3,value:6,status:0},{type:4,value:6,status:0},
    {type:1,value:7,status:0},{type:2,value:7,status:0},{type:3,value:7,status:0},{type:4,value:7,status:0},
    {type:1,value:8,status:0},{type:2,value:8,status:0},{type:3,value:8,status:0},{type:4,value:8,status:0},
    {type:1,value:9,status:0},{type:2,value:9,status:0},{type:3,value:9,status:0},{type:4,value:9,status:0},
    {type:1,value:10,status:0},{type:2,value:10,status:0},{type:3,value:10,status:0},{type:4,value:10,status:0},
    {type:1,value:11,name:'J',status:0},{type:2,value:11,name:'J',status:0},{type:3,value:11,name:'J',status:0},{type:4,value:11,name:'J',status:0},
    {type:1,value:12,name:'Q',status:0},{type:2,value:12,name:'Q',status:0},{type:3,value:12,name:'Q',status:0},{type:4,value:12,name:'Q',status:0},
    {type:1,value:13,name:'K',status:0},{type:2,value:13,name:'K',status:0},{type:3,value:13,name:'K',status:0},{type:4,value:13,name:'K',status:0},
    {type:1,value:14,name:'A',status:0},{type:2,value:14,name:'A',status:0},{type:3,value:14,name:'A',status:0},{type:4,value:14,name:'A',status:0},
    {type:1,value:15,name:'2',status:0},{type:2,value:15,name:'2',status:0},{type:3,value:15,name:'2',status:0},{type:4,value:15,name:'2',status:0},
    {type:1,value:19,name:'小王',status:0},{type:2,value:20,name:'大王',status:0}
]

先深层拷贝一下,我们需要得到四组扑克牌。分别是三个玩家组与一组底牌。

使用random得到打乱数组,洗牌完成。

使用sort排序算法进行牌面排序,这样基本上洗牌抓牌整理牌就完成了。

function Shuffle(){
    let newArr =deepCopy(pokeArr1)
    let i=0;
    let cardArr = {
        player1:[],
        player2:[],
        player3:[],
        land:[]
    };
    
    for(i;i<54;i++){
        let newLength = Number(newArr.length);
        let arrSub = Math.floor((Math.random()*newLength));
        if(i<17){
            cardArr['player1'].push(newArr[arrSub]);
        }else if(i<34){
            cardArr['player2'].push(newArr[arrSub]);
        }else if(i<51){
            cardArr['player3'].push(newArr[arrSub]);
        }else{
            cardArr['land'].push(newArr[arrSub]);
        }  
        newArr.splice(arrSub,1)   
    }
        
    console.log(sort(cardArr.player1),cardArr.player1.length)
    console.log(sort(cardArr.player2),cardArr.player2.length)
    console.log(sort(cardArr.player3),cardArr.player3.length)
    console.log(cardArr['land'])

}

下面是我用到的两个算法-深层拷贝与排序


function deepCopy (obj, cache = []) {
    // typeof [] => 'object'
    // typeof {} => 'object'
    if (obj === null || typeof obj !== 'object') {
      return obj
    }
    // 如果传入的对象与缓存的相等, 则递归结束, 这样防止循环
    /**
     * 类似下面这种
     * var a = {b:1}
     * a.c = a
     * 资料: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Errors/Cyclic_object_value
     */
    const hit = cache.filter(c => c.original === obj)[0]
    if (hit) {
      return hit.copy
    }
  
    const copy = Array.isArray(obj) ?  [] :   {}
    // 将copy首先放入cache, 因为我们需要在递归deepCopy的时候引用它
    cache.push({
      original: obj,
      copy
    })
    Object.keys(obj).forEach(key => {
      copy[key] = deepCopy(obj[key], cache)
    })
  
    return copy
}

function sort(arr) {
    var len = arr.length;
    var minIndex, temp;
    for (var i = 0; i < len - 1; i++) {
        minIndex = i;
        for (var j = i + 1; j < len; j++) {
            if (arr[j]['value'] < arr[minIndex]['value']) {     //寻找最小的数
                minIndex = j;                 //将最小数的索引保存
            }
        }
        temp = arr[i];
        arr[i]  = arr[minIndex];
        arr[minIndex] = temp;
    }
    return arr;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值