最近对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;
}