原生js純手寫鬥地主單機版(含人機演算法)
阿新 • • 發佈:2020-12-28
先看效果:
用了一週空閒時間,程式碼寫的比較亂,但所有內容純手寫
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、如果敵人報單,不出小的單牌,檢查其他型別牌,如果都沒有結果,大單牌也沒了才放小的單牌
其他情況就不寫了~~~