原生js纯手写斗地主单机版(含人机算法)
先看效果:
代码写的比较乱,但所有内容纯手写
gitee在线演示:http://hymhub.gitee.io/doudizhu/
源代码:https://gitee.com/hymhub/doudizhu
主要算法:
// 洗牌:
// arr保存54张牌
for (const key in arr) {
let index = parseInt(Math.random() * arr.length);
[arr[key], arr[index]] = [arr[index], arr[key]];
}
// 发牌
function faPai(arr) {
let player1 = arr.slice(0,17);
let player2 = arr.slice(17,34);
let player3 = arr.slice(34,51);
let diPai = arr.slice(51,54);
return { player1, player2, player3, diPai };
}
// 排序
// 排大小
arr.sort((a, b) => b.bijiao - a.bijiao);
// 排花色
function setHuaseBijiao(huase) {
switch (huase) {
case '♠':
return 4;
case '♥':
return 3;
case '♣':
return 2;
case '♦':
return 1;
default:
break;
}
}
for (let i = 0; i < 4; i++) {
for (const key in arr) {
if (key != arr.length - 1) { // 不用遍历最后一次
let huaseBijiao1 = setHuaseBijiao(arr[key].huase);
let huaseBijiao2 = setHuaseBijiao(arr[+key + 1].huase);
if (arr[key].pname == arr[+key + 1].pname && huaseBijiao1 < huaseBijiao2) {
[arr[key], arr[+key + 1]] = [arr[+key + 1], arr[key]];
}
}
}
}
// 重复数量检查,返回牌名和对应数量
// 这里是核心,所有出牌类型判断、查询手牌是否能压上、人机算法都靠这个方法实现,他的功能是去除重复牌返回牌名、数量、牌大小(bijiao:用于牌比较)
function getChongFu(arr) {
arr = [...arr];
let newArr = [];
for (let i = 0; i < arr.length; i++) {
let pname = arr[i].pname;
let bijiao = arr[i].bijiao;
let ciShu = 1;
newArr[i] = { pname, ciShu, bijiao };
for (let j = i+1; j <arr.length; ) {
if (arr[i].pname == arr[j].pname) {
newArr[i].ciShu++;
arr.splice(j, 1);
}else {
j++;
}
}
}
return newArr;
}
完整代码,可去我的gitee查看源代码:https://gitee.com/hymhub/doudizhu
人机出牌思路是:
1、敌人出牌自己能压上就压上,不能压上检查有没有炸弹和王炸
2、队友出单牌或对子大于Q就过,炸弹、王炸也过,不误伤队友
3、队友出大于8的三带一(三不带、三带对子)就过,不误伤队友
4、别人都要不起自己开始依次查询是否有合适的连子、连对,根据单牌对子情况查询三带一、三带对子,如果都没有合适的开始检查对子和单牌数量,对子大于或等于单牌就出对子否则出单牌
5、如果队友报单,放单牌,如果下一轮队友要不起,放弃队友,自己继续跟算法出牌
6、如果敌人报双,不出小的对子,检查其他类型牌,如果都没有结果才放小的对子
7、如果敌人报单,不出小的单牌,检查其他类型牌,如果都没有结果,大单牌也没了才放小的单牌
其他情况就不写了~~~