代码编织梦想

单机版斗地主游戏源代码,纯JS编写的斗地主单机版小游戏源代码,下载游戏后,直接运行index.html即可。
在这里插入图片描述
完整代码下载地址:单机版斗地主游戏源代码

index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>斗地主单机版-微信关注:Python代码大全</title>
    <link rel="icon" href="img/favicon.ico" sizes="32x32">
    <link rel="stylesheet" href="css/reset.css">
    <link rel="stylesheet" href="css/style.min.css">
    <script src="js/alert.js"></script>
    <script src="js/cards.js"></script>
</head>
<body>
    <main>
        <div class="wanduoda">
            <h3>底注: 100</h3>
        </div>
        <div class="wanduoda beishu">
            <h3>倍数: 1</h3>
        </div>
        <div class="box">
            <div class="box-left">
                <!-- 等待创建card -->
            </div>
            <div class="box-mid">
                <!-- 等待创建card -->
            </div>
            <div class="box-right">
                <!-- 等待创建card -->
            </div>
        </div>
        <div class="my">
            <!-- 等待创建card -->
        </div>
        <div class="btnBox">
            <input type="button" value="抢地主">
            <input type="button" value="出牌">
            <input type="button" value="过" id="woGuo">
        </div>
        <div class="whatPlayer">
            <div class="p1">
                <h3>玩家1正在出牌</h3>
            </div>
            <div class="p2">
                <h3>玩家2正在出牌</h3>
            </div>
            <div class="p3">
                <h3>我正在出牌</h3>
            </div>
        </div>
        <div class="user">
            <div class="p1">
                <span>剩余牌数:17</span>
                <img src="img/p1.jpg" alt="">
                <h4>余额:1509</h4>
                <div>
                    <h6>报双</h6>
                    <img src="img/baodan.gif" alt="">
                </div>
            </div>
            <div class="p2">
                <span>剩余牌数:17</span>
                <img src="img/p2.jpg" alt="">
                <h4>余额:8165</h4>
                <div>
                    <h6>报双</h6>
                    <img src="img/baodan.gif" alt="">
                </div>
            </div>
            <div class="p3">
                <img src="img/p3.jpg" alt="">
                <h4>余额:896</h4>
            </div>
        </div>
        <div class="iconShow">
            <img src="img/jiantou.png" alt="">
            <img src="img/jiantou.png" alt="">
            <img src="img/jiantou.png" alt="">
        </div>
    </main>
    <!-- bg -->
    <audio src="" loop></audio> 
    <!-- 其他音效 -->
    <audio src=""></audio>
    <!-- 出牌音效 -->
    <audio src=""></audio>
    <!-- 飞机火箭炸弹呜呜呜等音效 -->
    <audio src=""></audio>
</body>
</html>

card.js

let all = [
    {
        huase: '🃏',
        pname: '大王',
        bijiao: 15
    },
    {
        huase: '🃏',
        pname: '小王',
        bijiao: 14
    },
    // ----------------------------
    {
        huase: '♠',
        pname: '2',
        bijiao: 13
    },
    {
        huase: '♥',
        pname: '2',
        bijiao: 13
    },
    {
        huase: '♣',
        pname: '2',
        bijiao: 13
    },
    {
        huase: '♦',
        pname: '2',
        bijiao: 13
    },
    // ----------------------------
    {
        huase: '♠',
        pname: 'A',
        bijiao: 12
    },
    {
        huase: '♥',
        pname: 'A',
        bijiao: 12
    },
    {
        huase: '♣',
        pname: 'A',
        bijiao: 12
    },
    {
        huase: '♦',
        pname: 'A',
        bijiao: 12
    },
    // ----------------------------
    {
        huase: '♠',
        pname: 'K',
        bijiao: 11
    },
    {
        huase: '♥',
        pname: 'K',
        bijiao: 11
    },
    {
        huase: '♣',
        pname: 'K',
        bijiao: 11
    },
    {
        huase: '♦',
        pname: 'K',
        bijiao: 11
    },
    // ----------------------------
    {
        huase: '♠',
        pname: 'Q',
        bijiao: 10
    },
    {
        huase: '♥',
        pname: 'Q',
        bijiao: 10
    },
    {
        huase: '♣',
        pname: 'Q',
        bijiao: 10
    },
    {
        huase: '♦',
        pname: 'Q',
        bijiao: 10
    },
    // ----------------------------
    {
        huase: '♠',
        pname: 'J',
        bijiao: 9
    },
    {
        huase: '♥',
        pname: 'J',
        bijiao: 9
    },
    {
        huase: '♣',
        pname: 'J',
        bijiao: 9
    },
    {
        huase: '♦',
        pname: 'J',
        bijiao: 9
    },
    // ----------------------------
    {
        huase: '♠',
        pname: '10',
        bijiao: 8
    },
    {
        huase: '♥',
        pname: '10',
        bijiao: 8
    },
    {
        huase: '♣',
        pname: '10',
        bijiao: 8
    },
    {
        huase: '♦',
        pname: '10',
        bijiao: 8
    },
    // ----------------------------
    {
        huase: '♠',
        pname: '9',
        bijiao: 7
    },
    {
        huase: '♥',
        pname: '9',
        bijiao: 7
    },
    {
        huase: '♣',
        pname: '9',
        bijiao: 7
    },
    {
        huase: '♦',
        pname: '9',
        bijiao: 7
    },
    // ----------------------------
    {
        huase: '♠',
        pname: '8',
        bijiao: 6
    },
    {
        huase: '♥',
        pname: '8',
        bijiao: 6
    },
    {
        huase: '♣',
        pname: '8',
        bijiao: 6
    },
    {
        huase: '♦',
        pname: '8',
        bijiao: 6
    },
    // ----------------------------
    {
        huase: '♠',
        pname: '7',
        bijiao: 5
    },
    {
        huase: '♥',
        pname: '7',
        bijiao: 5
    },
    {
        huase: '♣',
        pname: '7',
        bijiao: 5
    },
    {
        huase: '♦',
        pname: '7',
        bijiao: 5
    },
    // ----------------------------
    {
        huase: '♠',
        pname: '6',
        bijiao: 4
    },
    {
        huase: '♥',
        pname: '6',
        bijiao: 4
    },
    {
        huase: '♣',
        pname: '6',
        bijiao: 4
    },
    {
        huase: '♦',
        pname: '6',
        bijiao: 4
    },
    // ----------------------------
    {
        huase: '♠',
        pname: '5',
        bijiao: 3
    },
    {
        huase: '♥',
        pname: '5',
        bijiao: 3
    },
    {
        huase: '♣',
        pname: '5',
        bijiao: 3
    },
    {
        huase: '♦',
        pname: '5',
        bijiao: 3
    },
    // ----------------------------
    {
        huase: '♠',
        pname: '4',
        bijiao: 2
    },
    {
        huase: '♥',
        pname: '4',
        bijiao: 2
    },
    {
        huase: '♣',
        pname: '4',
        bijiao: 2
    },
    {
        huase: '♦',
        pname: '4',
        bijiao: 2
    },
    // ----------------------------
    {
        huase: '♠',
        pname: '3',
        bijiao: 1
    },
    {
        huase: '♥',
        pname: '3',
        bijiao: 1
    },
    {
        huase: '♣',
        pname: '3',
        bijiao: 1
    },
    {
        huase: '♦',
        pname: '3',
        bijiao: 1
    },
];
// 玩家余额
let user1Money = 5509;
let user2Money = 6165;
let user3Money = 600;
// 首次运行存浏览器缓存
let moneyObj = {
    user1Money: 0,
    user2Money: 0,
    user3Money: 0
};
function setLocalStorageMoney() {
    moneyObj.user1Money = user1Money;
    moneyObj.user2Money = user2Money;
    moneyObj.user3Money = user3Money;
    localStorage.setItem('douDiZhuPMoney', JSON.stringify(moneyObj));
}
if (localStorage.getItem('douDiZhuPMoney')) {
    [user1Money, user2Money, user3Money] = [...Object.values(JSON.parse(localStorage.getItem('douDiZhuPMoney')))];
}else {
    setLocalStorageMoney();
}
// 当前倍数
let nowBeiShu = 1;
// 当前底注
let nowDizhu = 200;
// 洗牌
function xiPai(arr) {
    arr = [...arr];// 解决栈与堆问题,这样下面的操作不会改变原数组
    for (const key in arr) {
        let index = parseInt(Math.random() * arr.length);
        [arr[key], arr[index]] = [arr[index], arr[key]];
    }
    // arr.reverse();
    return arr;
}
let newAll = xiPai(all);
// 发牌
function faPai(arr) {
    let player1 = arr.slice(0,17);
    let player2 = arr.slice(17,34);
    let player3 = arr.slice(34,51);//34
    let diPai = arr.slice(51,54);
    return { player1, player2, player3, diPai };
}
let { player1, player2, player3, diPai } = faPai(newAll);
// 排序
function paiXu(arr){ // 这里会改变原数组(栈内引用地址复制),后面不用返回值
    // 排大小
    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]];
                }
            }
        }
    }
}
window.addEventListener('load', function(){
    const audioYinXiaoBox = document.querySelectorAll('audio');
    audioYinXiaoBox[0].src = 'audio/bg.mp3';
    // 音效状态
    function yinXiaoZhuangTaiChange(arg, sex = true) {
        let srcAudio = '';
        if (sex) {
            switch (arg[0]) {
                case '单牌':
                    switch (arg[1]) {
                        case 1:
                            srcAudio = 'audio/斗地主音效/斗地主音效/A_K女声/3.ogg';
                            break;
                        case 2:
                            srcAudio = 'audio/斗地主音效/斗地主音效/A_K女声/4.ogg';
                            break;
                        case 3:
                            srcAudio = 'audio/斗地主音效/斗地主音效/A_K女声/5.ogg';
                            break;
                        case 4:
                            srcAudio = 'audio/斗地主音效/斗地主音效/A_K女声/6.ogg';
                            break;
                        case 5:
                            srcAudio = 'audio/斗地主音效/斗地主音效/A_K女声/7.ogg';
                            break;
                        case 6:
                            srcAudio = 'audio/斗地主音效/斗地主音效/A_K女声/8.ogg';
                            break;
                        case 7:
                            srcAudio = 'audio/斗地主音效/斗地主音效/A_K女声/9.ogg';
                            break;
                        case 8:
                            srcAudio = 'audio/斗地主音效/斗地主音效/A_K女声/10.ogg';
                            break;
                        case 9:
                            srcAudio = 'audio/斗地主音效/斗地主音效/A_K女声/J.ogg';
                            break;
                        case 10:
                            srcAudio = 'audio/斗地主音效/斗地主音效/A_K女声/Q.ogg';
                            break;
                        case 11:
                            srcAudio = 'audio/斗地主音效/斗地主音效/A_K女声/K.ogg';
                            break;
                        case 12:
                            srcAudio = 'audio/斗地主音效/斗地主音效/A_K女声/A.ogg';
                            break;
                        case 13:
                            srcAudio = 'audio/斗地主音效/斗地主音效/A_K女声/2.ogg';
                            break;
                        case 14:
                            srcAudio = 'audio/斗地主音效/斗地主音效/A_K女声/小王.ogg';
                            break;
                        case 15:
                            srcAudio = 'audio/斗地主音效/斗地主音效/A_K女声/大王.ogg';
                            break;
                    
                        default:
                            break;
                    }
                    break;
                case '对子':
                    switch (arg[1]) {
                        case 1:
                            srcAudio = 'audio/斗地主音效/斗地主音效/对子/女声/对3.ogg';
                            break;
                        case 2:
                            srcAudio = 'audio/斗地主音效/斗地主音效/对子/女声/对4.ogg';
                            break;
                        case 3:
                            srcAudio = 'audio/斗地主音效/斗地主音效/对子/女声/对5.ogg';
                            break;
                        case 4:
                            srcAudio = 'audio/斗地主音效/斗地主音效/对子/女声/对6.ogg';
                            break;
                        case 5:
                            srcAudio = 'audio/斗地主音效/斗地主音效/对子/女声/对7.ogg';
                            break;
                        case 6:
                            srcAudio = 'audio/斗地主音效/斗地主音效/对子/女声/对8.ogg';
                            break;
                        case 7:
                            srcAudio = 'audio/斗地主音效/斗地主音效/对子/女声/对9.ogg';
                            break;
                        case 8:
                            srcAudio = 'audio/斗地主音效/斗地主音效/对子/女声/对10.ogg';;
                            break;
                        case 9:
                            srcAudio = 'audio/斗地主音效/斗地主音效/对子/女声/对J.ogg';
                            break;
                        case 10:
                            srcAudio = 'audio/斗地主音效/斗地主音效/对子/女声/对Q.ogg';
                            break;
                        case 11:
                            srcAudio = 'audio/斗地主音效/斗地主音效/对子/女声/对K.ogg';
                            break;
                        case 12:
                            srcAudio = 'audio/斗地主音效/斗地主音效/对子/女声/对A.ogg';
                            break;
                        case 13:
                            srcAudio = 'audio/斗地主音效/斗地主音效/对子/女声/对2.ogg';
                            break;
                    
                        default:
                            break;
                    }
                    break;
                case '三带一':
                    srcAudio = 'audio/斗地主音效/斗地主音效/三带一/三带一-女.ogg';
                    break;
                case '三带对子':
                    srcAudio = 'audio/斗地主音效/斗地主音效/三带一对/三带一对-女.ogg';
                    break;
                case '三不带':
                    switch (arg[1]) {
                        case 1:
                            srcAudio = 'audio/斗地主音效/斗地主音效/三个/女声/三个3.ogg';
                            break;
                        case 2:
                            srcAudio = 'audio/斗地主音效/斗地主音效/三个/女声/三个4.ogg';
                            break;
                        case 3:
                            srcAudio = 'audio/斗地主音效/斗地主音效/三个/女声/三个5.ogg';
                            break;
                        case 4:
                            srcAudio = 'audio/斗地主音效/斗地主音效/三个/女声/三个6.ogg';
                            break;
                        case 5:
                            srcAudio = 'audio/斗地主音效/斗地主音效/三个/女声/三个7.ogg';
                            break;
                        case 6:
                            srcAudio = 'audio/斗地主音效/斗地主音效/三个/女声/三个8.ogg';
                            break;
                        case 7:
                            srcAudio = 'audio/斗地主音效/斗地主音效/三个/女声/三个9.ogg';
                            break;
                        case 8:
                            srcAudio = 'audio/斗地主音效/斗地主音效/三个/女声/三个10.ogg';;;
                            break;
                        case 9:
                            srcAudio = 'audio/斗地主音效/斗地主音效/三个/女声/三个J.ogg';
                            break;
                        case 10:
                            srcAudio = 'audio/斗地主音效/斗地主音效/三个/女声/三个Q.ogg';
                            break;
                        case 11:
                            srcAudio = 'audio/斗地主音效/斗地主音效/三个/女声/三个K.ogg';
                            break;
                        case 12:
                            srcAudio = 'audio/斗地主音效/斗地主音效/三个/女声/三个A.ogg';
                            break;
                        case 13:
                            srcAudio = 'audio/斗地主音效/斗地主音效/三个/女声/三个2.ogg';
                            break;
                    
                        default:
                            break;
                    }
                    break;
                case '四带二':
                        srcAudio = 'audio/斗地主音效/斗地主音效/四带二/四带二-女.ogg';
                        break;
                case '连子':
                        srcAudio = 'audio/斗地主音效/斗地主音效/顺子/顺子-女.ogg';
                        break;
                case '连对':
                        srcAudio = 'audio/斗地主音效/斗地主音效/连对/连对-女.ogg';
                        break;
                case '炸弹':
                        srcAudio = 'audio/斗地主音效/斗地主音效/炸弹/炸弹-女.ogg';
                        audioYinXiaoBox[3].src = 'audio/斗地主音效/斗地主音效/炸弹/炸弹-Duang~.ogg';
                        audioYinXiaoBox[3].play();
                        break;
                case '王炸':
                        srcAudio = 'audio/斗地主音效/斗地主音效/王炸/王炸-女.ogg';
                        audioYinXiaoBox[3].src = 'audio/斗地主音效/斗地主音效/王炸/honghong.mp3';
                        audioYinXiaoBox[3].play();
                        break;
                case '四带二大飞机':
                case '飞机0':
                case '飞机1':
                case '飞机2':
                    srcAudio = 'audio/斗地主音效/斗地主音效/飞机/飞机-女.ogg';
                    audioYinXiaoBox[3].src = 'audio/斗地主音效/斗地主音效/飞机/飞机-呜呜.ogg';
                    audioYinXiaoBox[3].play();
                default:
                    break;
            }
        }else {

        }
        audioYinXiaoBox[2].src = srcAudio;
        audioYinXiaoBox[2].play();
    }
    function otherYinXiao(arg) {
        let srcAudio = '';
        switch (arg) {
            case '过':
                let key = parseInt(Math.random() * 3);
                switch (key) {
                    case 0:
                        srcAudio = 'audio/斗地主音效/斗地主音效/要不起/要不起-女声.ogg';
                        break;
                    case 1:
                        srcAudio = 'audio/斗地主音效/斗地主音效/过/过-女声.ogg';
                        break;
                    case 2:
                        srcAudio = 'audio/斗地主音效/斗地主音效/不要/不要-女.ogg';
                        break;
                    default:
                        break;
                }
                break;
            case '报双':
                srcAudio = 'audio/斗地主音效/斗地主音效/我就两张牌了/我就两张牌了-女声.ogg';
                break;
            case '报单':
                srcAudio = 'audio/斗地主音效/斗地主音效/我就一张牌了/我就一张牌了-女声.ogg';
            default:
                break;
        }
        audioYinXiaoBox[1].src = srcAudio;
        audioYinXiaoBox[1].play();
    }
    // 开始游戏
    function startGame() {
        tangZi = {};
        myShouPai = {};
        newAll = xiPai(all);
        let faPaiArr = faPai(newAll);
        [player1, player2, player3, diPai] = [faPaiArr.player1, faPaiArr.player2, faPaiArr.player3, faPaiArr.diPai];
        shuaXinShouPai();
        shuaXinTangZi();
        btnBox.children[0].style.display = 'inline-block';
        btnBox.children[1].style.display = 'none';
        btnBox.children[2].style.display = 'none';
        shuiChuDePaiJianTou[0].style.display = 'none';
        shuiChuDePaiJianTou[1].style.display = 'none';
        shuiChuDePaiJianTou[2].style.display = 'none';
        zhengZaiChuPaiTile[0].style.display = 'none';
        zhengZaiChuPaiTile[1].style.display = 'none';
        zhengZaiChuPaiTile[2].style.display = 'none';
        p1IsDizhu = p2IsDizhu = p3IsDizhu = false;
        isP1 = isP2 = isP3 = false;
        nowBeiShu = 1;
        wanduoda[1].children[0].innerHTML = `倍数: ${nowBeiShu}`;
        p1ChuPaiLeMaA = p2ChuPaiLeMaA = true;
        userBox[0].querySelector('div').style.display = 'none';
        userBox[1].querySelector('div').style.display = 'none';
        userBox[0].querySelector('span').innerHTML = `剩余牌数:17`;
        userBox[1].querySelector('span').innerHTML = `剩余牌数:17`;
    }
    // 胜利判断
    function canGameOver() {
        if (player1.length == 0 || player2.length == 0) {
            gameOverShuaXinPlayerShouPai();
            setTimeout(() => {
                user1Money += nowBeiShu * nowDizhu;
                user2Money += nowBeiShu * nowDizhu;
                user3Money -= nowBeiShu * nowDizhu * 2;
                alert2(
                    `失败,您余额-${nowDizhu * nowBeiShu * 2}<br/>
                    玩家1余额+${nowDizhu * nowBeiShu}<br/>
                    玩家2余额+${nowDizhu * nowBeiShu}`, startGame
                );
                userBox[0].querySelector('h4').innerHTML = `余额:${user1Money}`;
                userBox[1].querySelector('h4').innerHTML = `余额:${user2Money}`;
                userBox[2].querySelector('h4').innerHTML = `余额:${user3Money}`;
                setLocalStorageMoney();
            },1000);
            return true;
        }else if (player3.length == 0) {
            gameOverShuaXinPlayerShouPai();
            setTimeout(() => {
                user1Money -= nowBeiShu * nowDizhu;
                user2Money -= nowBeiShu * nowDizhu;
                user3Money += nowBeiShu * nowDizhu * 2;
                alert2(
                    `胜利,您余额+${nowDizhu * nowBeiShu * 2}<br/>
                    玩家1余额-${nowDizhu * nowBeiShu}<br/>
                    玩家2余额-${nowDizhu * nowBeiShu}`, startGame
                );
                userBox[0].querySelector('h4').innerHTML = `余额:${user1Money}`;
                userBox[1].querySelector('h4').innerHTML = `余额:${user2Money}`;
                userBox[2].querySelector('h4').innerHTML = `余额:${user3Money}`;
                setLocalStorageMoney();
            },1000);
            return true;
        }
        return false;
    }
    const zhengZaiChuPaiTile = document.querySelector('.whatPlayer').children;
    const shuiChuDePaiJianTou = document.querySelector('.iconShow').children;
    const player1Box = document.querySelector('.box > .box-left');
    const player2Box = document.querySelector('.box > .box-right');
    const player3Box = document.querySelector('.my');
    const diPaiBox = document.querySelector('.box > .box-mid');
    const userBox = document.querySelector('.user').children;
    const wanduoda = document.querySelectorAll('.wanduoda');
    userBox[0].querySelector('h4').innerHTML = `余额:${user1Money}`;
    userBox[1].querySelector('h4').innerHTML = `余额:${user2Money}`;
    userBox[2].querySelector('h4').innerHTML = `余额:${user3Money}`;
    wanduoda[0].children[0].innerHTML = `底注: ${nowDizhu}`;
    wanduoda[1].children[0].innerHTML = `倍数: ${nowBeiShu}`;
    // 出牌箭头显示
    function chuPaiLeJianTouShow(key) {
        shuiChuDePaiJianTou[2].style.display = 'none';
        shuiChuDePaiJianTou[1].style.display = 'none';
        shuiChuDePaiJianTou[0].style.display = 'none';
        switch (key) {
            case 2:
                setTimeout(() => {
                    shuiChuDePaiJianTou[1].style.display = 'block';
                },40);
                break;
            case 1:
                setTimeout(() => {
                    shuiChuDePaiJianTou[0].style.display = 'block';
                },40);
                break;
            case 3:
                setTimeout(() => {
                    shuiChuDePaiJianTou[2].style.display = 'block';
                },40);
                break;
            default:
                break;
        }
    }
    // 出牌桥接对象
    let tangZi = {};
    // 我的手牌
    let myShouPai = {};
    // 刷新点击
    function shuaXinShouPaiDianJi() {
        for (const iterator of player3Box.children) {
            iterator.onclick = e => {
                if (iterator.getAttribute('data-index') == '1') {
                    iterator.style.transform = 'translateY(-20px)';
                    iterator.setAttribute('data-index','0');
                    myShouPai[iterator.getAttribute('data-key')] = player3[iterator.getAttribute('data-key')];
                }else if(iterator.getAttribute('data-index') == '0') {
                    iterator.style.transform = 'translateY(0)';
                    iterator.setAttribute('data-index','1');
                    delete myShouPai[iterator.getAttribute('data-key')];
                }
            };
        }
    }
    // 刷新人机1手牌
    function shuaXinPlayer1ShouPai() {
        player1Box.innerHTML = '';
        paiXu(player1);
        for (let i = 0; i < player1.length; i++) {
            const card1 = document.createElement('div');
            if (player1[i].huase == '♥' || player1[i].huase == '♦' || player1[i].pname == '大王') {
                card1.style.color = 'red';
            }
            card1.className = 'card';
            card1.setAttribute('data-key', i);
            // card1.innerHTML = `
            //     <div class="card-leftTitle absBox">
            //         <h3>${player1[i].pname}</h3>
            //         <h3>${player1[i].huase}</h3>
            //     </div>
            //     <div class="card-rightTitle absBox">
            //         <h3>${player1[i].pname}</h3>
            //         <h3>${player1[i].huase}</h3>
            //     </div>
            //     <div class="card-content">
            //         <h1>${player1[i].huase}</h1>
            //     </div>
            // `;
            player1Box.appendChild(card1);
        }
    }
    // 游戏结束刷新人机手牌
    function gameOverShuaXinPlayerShouPai() {
        player1Box.innerHTML = '';
        paiXu(player1);
        for (let i = 0; i < player1.length; i++) {
            const card1 = document.createElement('div');
            if (player1[i].huase == '♥' || player1[i].huase == '♦' || player1[i].pname == '大王') {
                card1.style.color = 'red';
            }
            card1.className = 'card';
            card1.setAttribute('data-key', i);
            card1.style.backgroundImage = 'none';
            card1.innerHTML = `
                <div class="card-leftTitle absBox">
                    <h3>${player1[i].pname}</h3>
                    <h3>${player1[i].huase}</h3>
                </div>
                <div class="card-rightTitle absBox">
                    <h3>${player1[i].pname}</h3>
                    <h3>${player1[i].huase}</h3>
                </div>
                <div class="card-content">
                    <h1>${player1[i].huase}</h1>
                </div>
            `;
            player1Box.appendChild(card1);
        }
        player2Box.innerHTML = '';
        paiXu(player2);
        for (let i = 0; i < player2.length; i++) {
            const card2 = document.createElement('div');
            if (player2[i].huase == '♥' || player2[i].huase == '♦' || player2[i].pname == '大王') {
                card2.style.color = 'red';
            }
            card2.className = 'card';
            card2.setAttribute('data-key', i);
            card2.style.backgroundImage = 'none';
            card2.innerHTML = `
                <div class="card-leftTitle absBox">
                    <h3>${player2[i].pname}</h3>
                    <h3>${player2[i].huase}</h3>
                </div>
                <div class="card-rightTitle absBox">
                    <h3>${player2[i].pname}</h3>
                    <h3>${player2[i].huase}</h3>
                </div>
                <div class="card-content">
                    <h1>${player2[i].huase}</h1>
                </div>
            `;
            player2Box.appendChild(card2);
        }
    }
    // 刷新人机2手牌
    function shuaXinPlayer2ShouPai() {
        player2Box.innerHTML = '';
        paiXu(player2);
        for (let i = 0; i < player2.length; i++) {
            const card2 = document.createElement('div');
            if (player2[i].huase == '♥' || player2[i].huase == '♦' || player2[i].pname == '大王') {
                card2.style.color = 'red';
            }
            card2.className = 'card';
            card2.setAttribute('data-key', i);
            // card2.innerHTML = `
            //     <div class="card-leftTitle absBox">
            //         <h3>${player2[i].pname}</h3>
            //         <h3>${player2[i].huase}</h3>
            //     </div>
            //     <div class="card-rightTitle absBox">
            //         <h3>${player2[i].pname}</h3>
            //         <h3>${player2[i].huase}</h3>
            //     </div>
            //     <div class="card-content">
            //         <h1>${player2[i].huase}</h1>
            //     </div>
            // `;
            player2Box.appendChild(card2);
        }
    }
    // 刷新手牌
    function shuaXinShouPai() {
        shuaXinPlayer1ShouPai();
        shuaXinPlayer2ShouPai();
        player3Box.innerHTML = '';
        paiXu(player3);
        for (let i = 0; i < player3.length; i++) {
            const card3 = document.createElement('div');
            if (player3[i].huase == '♥' || player3[i].huase == '♦' || player3[i].pname == '大王') {
                card3.style.color = 'red';
            }
            card3.className = 'card';
            card3.setAttribute('data-index','1');
            card3.setAttribute('data-key', i);
            card3.innerHTML = `
                <div class="card-leftTitle absBox">
                    <h3>${player3[i].pname}</h3>
                    <h3>${player3[i].huase}</h3>
                </div>
                <div class="card-rightTitle absBox">
                    <h3>${player3[i].pname}</h3>
                    <h3>${player3[i].huase}</h3>
                </div>
                <div class="card-content">
                    <h1>${player3[i].huase}</h1>
                </div>
            `;
            player3Box.appendChild(card3);
        }
        shuaXinShouPaiDianJi();
    }
    shuaXinShouPai();
    // 刷新堂子
    function shuaXinTangZi() {
        diPaiBox.innerHTML = '';
        for (let i = 0; i < diPai.length; i++) {
            const card = document.createElement('div');
            card.className = 'card';
            if (diPai[i].huase == '♥' || diPai[i].huase == '♦' || diPai[i].pname == '大王') {
                card.style.color = 'red';
            }
            card.innerHTML = `
                <div class="card-leftTitle absBox">
                    <h3>${diPai[i].pname}</h3>
                    <h3>${diPai[i].huase}</h3>
                </div>
                <div class="card-rightTitle absBox">
                    <h3>${diPai[i].pname}</h3>
                    <h3>${diPai[i].huase}</h3>
                </div>
                <div class="card-content">
                    <h1>${diPai[i].huase}</h1>
                </div>
            `;
            diPaiBox.appendChild(card);
        }
    }
    // 刷新底牌
    function shuaXinDiPai() {
        diPaiBox.innerHTML = '';
        for (let i = 0; i < diPai.length; i++) {
            const card = document.createElement('div');
            card.className = 'card';
            card.style.backgroundImage = "url('img/pai.jpg')";
            card.style.backgroundSize = '100% 100%';
            if (diPai[i].huase == '♥' || diPai[i].huase == '♦' || diPai[i].pname == '大王') {
                card.style.color = 'red';
            }
            diPaiBox.appendChild(card);
        }
    }
    shuaXinDiPai();
    // 谁是地主
    let p1IsDizhu = false, p2IsDizhu = false, p3IsDizhu = false;
    const btnBox = document.querySelector('main > div.btnBox');
    // 要不起(过)(用于人机判定,不能误伤队友)// 淘汰,不再使用
    let p1YaoBuQi = false, p2YaoBuQi = false, p3YaoBuQi = false; // 淘汰
    // 现在是谁出的牌
    let isP1 = false, isP2 = false, isP3 = false;
    // 用于报单人机智商问题
    let p1ChuPaiLeMaA = true, p2ChuPaiLeMaA = true;
    // 人机出牌流程
    function renJiLiuCheng(flag) { // true人机无敌随意出牌 false正常流程
        // ---------------人机2出牌-----------------
        btnBox.children[1].style.display = 'none';
        btnBox.children[2].style.display = 'none';
        setTimeout(() => {
            if (p3IsDizhu || !isP3) { // p3是地主或p3要不起p1就出牌
                if (flag) {
                    if (player1.length == 1 && p1ChuPaiLeMaA) {
                        // 如果p1报单,p2放单牌,如果下轮p1没出牌,p2放弃p1
                        p2YaoBuQi = renJiPlay(player2, 'p2', false, true, '单牌');
                        p1ChuPaiLeMaA = false;
                    }else {
                        p2YaoBuQi = renJiPlay(player2, 'p2', false, true);
                    }
                }else {
                    p2YaoBuQi = renJiPlay(player2, 'p2');
                }
                shuaXinPlayer2ShouPai();
                if (canGameOver()) {
                    return;
                }
            }else {
                renJiPlay(player2, 'p2', true);
            }
            zhengZaiChuPaiTile[1].style.display = 'none';
            zhengZaiChuPaiTile[0].style.display = 'block';
            zhengZaiChuPaiTile[2].style.display = 'none';
            // ---------------人机1出牌-----------------
            setTimeout(() => {
                if (p2IsDizhu || !isP2 || true) { // p2是地主或p2要不起p1就出牌 ----------暂时开启见人就轰模式,关闭删除true-------------------------
                    // 优化人机算法,防止误伤队友-----------------------------------
                    let flag = true;
                    let num = 0;
                    let tangZiCardType =  getTangZiPaiType();
                    if (tangZiCardType[0] == '炸弹') {
                        flag = false;
                    }else {
                        if (tangZiCardType[0] == '单牌' || tangZiCardType[0] == '对子' || tangZiCardType[0] == '三不带') {
                            for (const iterator of Object.values(tangZi)) {
                                if (iterator.bijiao > 10) { // p2出大于Q的p1就放
                                    flag = false;
                                }
                            }
                        }else if(tangZiCardType[0] == '三带一' || tangZiCardType[0] == '三带对子') {
                            for (const iterator of Object.values(tangZi)) {
                                if (iterator.bijiao > 6) { // P2出大于8的三带*p1就放
                                    num++;
                                    if (num > 2) {
                                        flag = false;
                                    }
                                }
                            }
                        }
                        
                    }
                    // -----------如果地主出的牌,直接干--------------------
                    if (isP3 && p3IsDizhu) {
                        flag = true;
                    }
                    // -------------------------------
                    if (flag) {
                        p1YaoBuQi = renJiPlay(player1, 'p1');
                    }else {
                        p1YaoBuQi = renJiPlay(player1, 'p1', true);
                    }
                    // -------------------------------------------------------------
                    shuaXinPlayer1ShouPai();
                    if (canGameOver()) {
                        return;
                    }
                }else {
                    renJiPlay(player1, 'p1', true);
                }
                
                // tangZi = {};
                btnBox.children[1].style.display = 'inline-block';
                if (!isP3) {
                    btnBox.children[2].style.display = 'inline-block';
                }
                zhengZaiChuPaiTile[0].style.display = 'none';
                zhengZaiChuPaiTile[1].style.display = 'none';
                zhengZaiChuPaiTile[2].style.display = 'block';
                p1YaoBuQi = p2YaoBuQi = p3YaoBuQi = false;
            },2000);
        },2000);
        // --------------------------------
    }
    function renJiLiuCheng1(flag) { // true人机无敌随意出牌 false正常流程
        btnBox.children[1].style.display = 'none';
        btnBox.children[2].style.display = 'none';
            // ---------------人机1出牌-----------------
            setTimeout(() => {
                renJiPlay(player2, 'p2', true);
                zhengZaiChuPaiTile[1].style.display = 'none';
                zhengZaiChuPaiTile[0].style.display = 'block';
                zhengZaiChuPaiTile[2].style.display = 'none';
                setTimeout(() => {
                    if (p2IsDizhu || !isP2) { // p2是地主或p2要不起p1就出牌---------------这里不开启见人就轰模式,让下家(p1)走提高人机胜率----------
                        if (flag) {
                            if (player2.length == 1 && p2ChuPaiLeMaA) {
                                // 如果p2报单,p1放单牌,如果下轮p2没出牌,p1放弃p2
                                p1YaoBuQi = renJiPlay(player1, 'p1', false, true, '单牌');
                                p2ChuPaiLeMaA = false;
                            }else {
                                p1YaoBuQi = renJiPlay(player1, 'p1', false, true);
                            }
                        }else {
                            p1YaoBuQi = renJiPlay(player1, 'p1');
                        }
                        shuaXinPlayer1ShouPai();
                        if (canGameOver()) {
                            return;
                        }
                    }else {
                        renJiPlay(player1, 'p1', true);
                    }
                    
                    // tangZi = {};
                    btnBox.children[1].style.display = 'inline-block';
                    if (!isP3) {
                        btnBox.children[2].style.display = 'inline-block';
                    }
                    zhengZaiChuPaiTile[0].style.display = 'none';
                    zhengZaiChuPaiTile[1].style.display = 'none';
                    zhengZaiChuPaiTile[2].style.display = 'block';
                    p1YaoBuQi = p2YaoBuQi = p3YaoBuQi = false;
                },2000);
            },2000);
        // --------------------------------
    }
    // 检索我是否能出牌压住上家
    function canIPlayCard(myShouPai) {
        console.log('上家堂子',tangZi);
        let tangZiCardType = getTangZiPaiType();
        let myCardType = getTangZiPaiType(myShouPai);
        console.log(tangZiCardType,'tangZiCardType');
        console.log(myCardType,'myCardType');
        if (tangZiCardType == 0) {
            return true;
        }
        if (!isP3) {
            if (tangZiCardType[0] != myCardType[0]) {
                if (tangZiCardType[0] != '炸弹' && tangZiCardType[0] != '王炸' && myCardType[0] == '炸弹') {
                    return true;
                }
                if ((myCardType[0] == '炸弹' && myCardType[1] > tangZiCardType[1]) || myCardType[0] == '王炸') {
                    return true;
                }
                return false;
            }else {
                if (myCardType[1] > tangZiCardType[1]) {
                    return true;
                }
                return false;
            }
        }
        return true;
    }
    btnBox.addEventListener('click',e => {
        // 抢地主
        if (e.target.value == '抢地主') {
            audioYinXiaoBox[0].play();
            isP3 = true;
            zhengZaiChuPaiTile[2].style.display = 'block';
            p3IsDizhu = true;
            tangZi = {};
            myShouPai = {};
            e.target.style.display = 'none';
            btnBox.children[1].style.display = 'inline-block';
            // btnBox.children[2].style.display = 'inline-block';
            diPaiBox.innerHTML = '';
            for (const iterator of diPai) {
                player3.push(iterator);
            }
            shuaXinShouPai();
        }
        // 出牌
        if (e.target.value == '出牌') {
            // e.target.style.display = 'none';
            let shangJiaTangZi = canIPlayCard(myShouPai);
            if (shangJiaTangZi) {
                tangZi = myShouPai;
            }
            console.log('我当前出牌类型:',getTangZiPaiType());
            let cardType = getTangZiPaiType();
            if (cardType && shangJiaTangZi) {
                for (const key in tangZi) {
                    player3[key] = '0';
                }
                for (let i = 0; i < player3.length; ) {
                    if (player3[i] == '0') {
                        player3.splice(i, 1);
                    }else {
                        i++;
                    }
                }
                if (player3.length == 2) {
                    otherYinXiao('报双');
                }else if (player3.length == 1) {
                    otherYinXiao('报单');
                }
                diPai = Object.values(tangZi);
                shuaXinTangZi();
                zhengZaiChuPaiTile[2].style.display = 'none';
                zhengZaiChuPaiTile[0].style.display = 'none';
                zhengZaiChuPaiTile[1].style.display = 'block';
                shuaXinShouPai();
                chuPaiLeJianTouShow(3);
                isP3 = true;
                isP1 = isP2 = false;
                let srcAudio = getTangZiPaiType();
                yinXiaoZhuangTaiChange(srcAudio);
                if (cardType[0] == '王炸' || cardType[0] == '炸弹') {
                    nowBeiShu *= 2;
                    wanduoda[1].children[0].innerHTML = `倍数: ${nowBeiShu}`;
                }
                if (canGameOver()) {
                    return;
                }
                renJiLiuCheng();
            }else {
                alert('当前出牌不正确,请重新出牌');
                setTimeout(function() {
                    document.body.removeChild(document.body.childNodes[document.body.childNodes.length - 1]);
                }, 1000);
                return;
            }
            
            
            myShouPai = {};
            
        }
        // 过
        if (e.target.value == '过') {
            otherYinXiao('过');
            zhengZaiChuPaiTile[2].style.display = 'none';
            zhengZaiChuPaiTile[0].style.display = 'none';
            zhengZaiChuPaiTile[1].style.display = 'block';
            alert1('过', 300, 60, 'left');
            p3YaoBuQi = true;
            if (isP2) {
                renJiLiuCheng(true);
            }else if(isP1) {
                renJiLiuCheng1(true);
            }
        }
    });



    // 重复数量检查,返回出牌的牌名和对应数量
    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;
    }
    // 出牌类型判断
    function getTangZiPaiType(arg = false) {
        let typeArr = [];
        let tangZiValues;
        if (arg) {
            tangZiValues = Object.values(arg);
        }else {
            tangZiValues = Object.values(tangZi);
        }
        const regE = /\W/;
        const chongFuWrapArr = getChongFu(tangZiValues);
        // ------------------------单牌-------------------------
        if (tangZiValues.length == 1) {
            typeArr[0] = '单牌';
            typeArr[1] = tangZiValues[0].bijiao;
            return typeArr;
        }
        // ------------------------对子-------------------------
        if (tangZiValues.length == 2 && tangZiValues[0].pname == tangZiValues[1].pname) {
            typeArr[0] = '对子';
            typeArr[1] = tangZiValues[0].bijiao;
            return typeArr;
        }
        // ------------------------王炸-------------------------
        if (tangZiValues.length == 2 && regE.test(tangZiValues[0].pname) && regE.test(tangZiValues[1].pname)) {
            typeArr[0] = '王炸';
            return typeArr;
        }
        // ------------------------三不带-------------------------
        if (tangZiValues.length == 3 && tangZiValues[0].pname == tangZiValues[1].pname && tangZiValues[1].pname == tangZiValues[2].pname) {
            typeArr[0] = '三不带';
            typeArr[1] = tangZiValues[0].bijiao;
            return typeArr;
        }
        // ------------------------三带一或炸弹(4张牌)-------------------
        if (tangZiValues.length == 4) {
            for (const iterator of chongFuWrapArr) {
                if (iterator.ciShu == 3) {
                    typeArr[0] = '三带一';
                    typeArr[1] = iterator.bijiao;
                    return typeArr;
                }
                if (iterator.ciShu == 4) {
                    typeArr[0] = '炸弹';
                    typeArr[1] = iterator.bijiao;
                    return typeArr;
                }
            }
        }
        // ------------------------三带对子-------------------------
        if (tangZiValues.length == 5) {
            if (chongFuWrapArr.length == 2) {
                for (const iterator of chongFuWrapArr) {
                    if (iterator.ciShu == 3) {
                        typeArr[0] = '三带对子';
                        typeArr[1] = iterator.bijiao;
                        return typeArr;
                    }
                }
            }
        }
        // ------------------------连子-------------------------
        if (tangZiValues.length >= 5 && chongFuWrapArr.length == tangZiValues.length) {
            let flag = true;
            tangZiValues.sort((a, b) => a.bijiao - b.bijiao);
            for (let i = 0; i < tangZiValues.length; i++) {
                if (tangZiValues[i].bijiao == '13' || tangZiValues[i].bijiao == '14' || tangZiValues[i].bijiao == '15') {//剔除出大小王和2
                    flag = false;
                }
                if (tangZiValues.length - 1 != i && tangZiValues[i].bijiao + 1 != tangZiValues[i + 1].bijiao) {// 判断是否连号
                    flag = false;
                }
            }
            if (flag) {
                typeArr[0] = '连子';
                typeArr[1] = tangZiValues[0].bijiao;
                typeArr[2] = tangZiValues.length;
                return typeArr;
            }
        }
        // ------------------------飞机0(三不带飞机)-------------------------
        if (tangZiValues.length % 3 == 0 && tangZiValues.length != 0) {
            let flag = true;
            // 三不带飞机判断
            let fly3 = 0;
            // 保存3张牌的出现判断是否连子
            const fly3Arr = [];
            // 初始化准备
            for (const iterator of chongFuWrapArr) {
                if (iterator.pname == '2') {
                    flag = false;
                }
                if (iterator.ciShu == 3) {
                    fly3++;
                    fly3Arr.push(iterator.bijiao);
                }
            }
            if (tangZiValues.length - fly3 * 3 == 0) {
                fly3Arr.sort((a, b) => a - b);
                for (let i = 0; i < fly3Arr.length - 1; i++) {
                    if (fly3Arr[i] + 1 != fly3Arr[i + 1]) {
                        flag = false;
                    }
                }
                if (flag) {
                    typeArr[0] = '飞机0';
                    typeArr[1] = fly3Arr[0];
                    typeArr[2] = fly3Arr.length;
                    return typeArr;
                }
            }
        }
        // ------------------------飞机1(三带一飞机)或滚炸-------------------------
        if (tangZiValues.length % 4 == 0 && tangZiValues.length != 0) {
            let flag = true;
            let flagBoom = true;
            // 滚炸判断开关
            let gunZha = true;
            // 三带1飞机判断
            let fly3 = 0;
            // 保存3张牌的出现判断是否连子
            const fly3Arr = [];
            // 炸弹出现判断连号
            const boomArr = [];
            // 初始化准备
            for (const iterator of chongFuWrapArr) {
                if (iterator.pname == '2') {
                    flag = false;
                    gunZha = false;
                }
                if (iterator.ciShu != 4) {
                    gunZha = false;
                }
                if (iterator.ciShu == 3) {
                    fly3++;
                    fly3Arr.push(iterator.bijiao);
                }
                if (iterator.ciShu == 4) {
                    boomArr.push(iterator.bijiao);
                }
            }
            // 开始滚炸判断
            // if (gunZha) {
            //     boomArr.sort((a, b) => a - b);
            //     for (let i = 0; i < boomArr.length - 1; i++) {
            //         if (boomArr[i] + 1 != boomArr[i + 1]) {
            //             flagBoom = false;
            //         }
            //     }
            //     if (flagBoom) {
            //         typeArr[0] = '滚炸';
            //         typeArr[1] = boomArr[0];
            //         typeArr[2] = boomArr.length;
            //         return typeArr;
            //     }
            // }
            // 开始三带一飞机判断
            if (tangZiValues.length - fly3 * 3 == fly3 || (tangZiValues.length - (fly3 - 1) * 3 == fly3 - 1 && (fly3 == 4 || fly3 == 5 || fly3 == 6))) {
                fly3Arr.sort((a, b) => a - b);
                if (fly3 < 4) {
                    typeArr[2] = fly3Arr.length;
                    typeArr[1] = fly3Arr[0];
                    for (let i = 0; i < fly3Arr.length - 1; i++) {
                        if (fly3Arr[i] + 1 != fly3Arr[i + 1]) {
                            flag = false;
                        }
                    }
                }
                if (fly3 >= 4) {
                    typeArr[2] = fly3Arr.length - 1;
                    let flag1 = false, flag2 = false;
                    for (let i = 0; i < fly3Arr.length - 2; i++) {
                        if (fly3Arr[i] + 1 != fly3Arr[i + 1]) {
                            flag1 = true;
                            typeArr[1] = fly3Arr[1];
                        }
                    }
                    for (let i = 1; i < fly3Arr.length - 1; i++) {
                        if (fly3Arr[i] + 1 != fly3Arr[i + 1]) {
                            flag2 = true;
                            typeArr[1] = fly3Arr[0];
                        }
                    }
                    if (flag1 && flag2) {// 只要首尾有能连上的就不会进入这个条件 例如333/444/555/888也是三带一飞机
                        flag = false;
                    }
                }
                if (flag) {
                    typeArr[0] = '飞机1';
                    return typeArr;
                }
            }
        }
        // ------------------------飞机2(三带对子飞机)-------------------------
        if (tangZiValues.length % 5 == 0 && tangZiValues.length != 0) {
            let flag = true;
            // 三带2飞机判断
            let fly3 = 0;
            // 保存3张牌的出现判断是否连子
            const fly3Arr = [];
            // 带的牌是对子出现的次数
            let fly2 = 0;
            // 初始化准备
            for (const iterator of chongFuWrapArr) {
                if (iterator.pname == '2') {
                    flag = false;
                }
                if (iterator.ciShu == 3) {
                    fly3++;
                    fly3Arr.push(iterator.bijiao);
                }
                if (iterator.ciShu == 2) {
                    fly2++;
                }
            }
            if (tangZiValues.length - fly3 * 3 == fly2 * 2) {
                fly3Arr.sort((a, b) => a - b);
                for (let i = 0; i < fly3Arr.length - 1; i++) {
                    if (fly3Arr[i] + 1 != fly3Arr[i + 1]) {
                        flag = false;
                    }
                }
                if (flag) {
                    typeArr[0] = '飞机2';
                    typeArr[1] = fly3Arr[0];
                    typeArr[2] = fly3Arr.length;
                    return typeArr;
                }
            }
        }
        // ------------------------连对-------------------------
        if (tangZiValues.length % 2 == 0 && tangZiValues.length > 5) {
            let flag = true;
            // 保存对子的出现
            const douBle2Arr = [];
            // 初始化准备
            for (const iterator of chongFuWrapArr) {
                if (iterator.pname == '2') {
                    flag = false;
                }
                if (iterator.ciShu == 2) {
                    douBle2Arr.push(iterator.bijiao);
                }
            }
            if (tangZiValues.length - douBle2Arr.length * 2 == 0) {
                douBle2Arr.sort((a, b) => a - b);
                for (let i = 0; i < douBle2Arr.length - 1; i++) {
                    if (douBle2Arr[i] + 1 != douBle2Arr[i + 1]) {
                        flag = false;
                    }
                }
                if (flag) {
                    typeArr[0] = '连对';
                    typeArr[1] = douBle2Arr[0];
                    typeArr[2] = douBle2Arr.length;
                    return typeArr;
                }
            }
        }
        // ------------------------四带二-------------------------
        if (tangZiValues.length == 6) {
            for (const iterator of chongFuWrapArr) {
                if (iterator.ciShu == 4) {
                    typeArr[0] = '四带二';
                    typeArr[1] = iterator.bijiao;
                    return typeArr;
                }
            }
        }
        // ------------------------四带二大飞机-------------------------
        if (tangZiValues.length % 6 == 0 && tangZiValues.length > 5) {
            let flag = true;
            let flagBoom = true;
            // 炸弹出现判断连号
            const boomArr = [];
            // 初始化准备
            for (const iterator of chongFuWrapArr) {
                if (iterator.pname == '2') {
                    flag = false;
                }
                if (iterator.ciShu == 4) {
                    boomArr.push(iterator.bijiao);
                }
            }
            if (flag && ((tangZiValues.length - (boomArr.length - 1) * 4 == (boomArr.length - 1) * 2 && tangZiValues.length > 11) || tangZiValues.length - boomArr.length * 4 == boomArr.length * 2)) {
                boomArr.sort((a, b) => a - b);
                let flag1 = false, flag2 = false;

                if (boomArr.length < 3) {
                    typeArr[1] = boomArr[0];
                    typeArr[2] = boomArr.length;
                    for (let i = 0; i < boomArr.length - 1; i++) {
                        if (boomArr[i] + 1 != boomArr[i + 1]) {
                            flagBoom = false;
                        }
                    }
                }
                if (boomArr.length >= 3) {
                    typeArr[2] = boomArr.length - 1;
                    for (let i = 0; i < boomArr.length - 2; i++) {
                        if (boomArr[i] + 1 != boomArr[i + 1]) {
                            typeArr[1] = boomArr[1];
                            flag1 = true;
                        }
                    }
                    for (let i = 1; i < boomArr.length - 1; i++) {
                        if (boomArr[i] + 1 != boomArr[i + 1]) {
                            typeArr[1] = boomArr[0];
                            flag2 = true;
                        }
                    }
                    if (flag1 && flag2) {// 同理三带一飞机
                        flagBoom = false;
                    }
                }
                if (flagBoom) {
                    typeArr[0] = '四带二大飞机';
                    return typeArr;
                }
            }
        }

        return 0;
    }
    // 手牌查询(获取可出牌区桥接数组)
    //                     手牌  牌型  最小牌值    连号量(可选)
    function shouPaiChaXun(arr, type, bijiao = 0, more) {
        // 手牌重复检索
        const chongFuWrapArr = getChongFu(arr);
        chongFuWrapArr.reverse();
        // 可出牌区桥接数组
        const canIPlay = [];
        // 有无双王判断
        let jokerFlag = false;
        let bigJoker = false, smallJoker = false;
        for (const iterator of chongFuWrapArr) {
            if (iterator.bijiao == 14) {
                smallJoker = true;
            }
            if (iterator.bijiao == 15) {
                bigJoker = true;
            }
        }
        if (bigJoker && smallJoker) {
            jokerFlag = true;
        }
        // 王炸查询
        function haveJoker() {
            if (jokerFlag) {
                let pname = '王';
                let bijiao = 20;
                let ciShu = 1;
                canIPlay.push({ pname, ciShu, bijiao });
            }
        }
        // ---------------------------------------------------
        // 单牌查询 用于三带一
        function getOneCard() {
            for (const iterator of chongFuWrapArr) {
                if (iterator.ciShu == 1 && iterator.bijiao < 14) {
                    for (let i = 0; i < arr.length; i++) {
                        if (iterator.pname == arr[i].pname) {
                            return 1;
                        }
                    }
                }
            }
            for (const iterator of chongFuWrapArr) {
                if (iterator.ciShu == 2) {
                    for (let i = 0; i < arr.length; i++) {
                        if (iterator.pname == arr[i].pname) {
                            return 1;
                        }
                    }
                }
            }
            return 0;
        }
        // 单牌、对子查询 用于四带二
        function getDoubleCard() {
            let num = 0;
            for (const iterator of chongFuWrapArr) {
                if (iterator.ciShu == 1 && iterator.bijiao < 14) {
                    for (let i = 0; i < arr.length; i++) {
                        if (iterator.pname == arr[i].pname) {
                            num++;
                            if (num == 2) {
                                return 1;
                            }
                        }
                    }
                }
            }
            for (const iterator of chongFuWrapArr) {
                if (iterator.ciShu == 2) {
                    for (let i = 0; i < arr.length; i++) {
                        if (iterator.pname == arr[i].pname) {
                            return 1;
                        }
                    }
                }
            }
            return 0;
        }
        function getDuiZiCard() {
            for (const iterator of chongFuWrapArr) {
                if (iterator.ciShu == 2) {
                    for (let i = 0; i < arr.length; i++) {
                        if (iterator.pname == arr[i].pname) {
                            return 1;
                        }
                    }
                }
            }
            return 0;
        }
        switch (type) {
            case '单牌':
                for (const iterator of chongFuWrapArr) {
                    if (iterator.ciShu == 1 && iterator.bijiao > bijiao) {
                        if (jokerFlag) { // 有双王的话就不要拆单
                            if (iterator.bijiao < 14) {
                                canIPlay.push(iterator);
                            }
                        }else {
                            canIPlay.push(iterator);
                        }
                    }
                }
                for (const iterator of chongFuWrapArr) {
                    if (iterator.ciShu == 2 && iterator.bijiao > bijiao) {
                        canIPlay.push(iterator);
                    }
                }
                for (const iterator of chongFuWrapArr) {
                    if (iterator.ciShu == 3 && iterator.bijiao > bijiao) {
                        canIPlay.push(iterator);
                    }
                }
                for (const iterator of chongFuWrapArr) {
                    if (iterator.ciShu == 4) {
                        canIPlay.push(iterator);
                    }
                }
                haveJoker();
                break;
            case '对子':
                for (const iterator of chongFuWrapArr) {
                    if (iterator.ciShu == 2 && iterator.bijiao > bijiao) {
                        canIPlay.push(iterator);
                    }
                }
                for (const iterator of chongFuWrapArr) {
                    if (iterator.ciShu == 3 && iterator.bijiao > bijiao) {
                        canIPlay.push(iterator);
                    }
                }
                for (const iterator of chongFuWrapArr) {
                    if (iterator.ciShu == 4) {
                        canIPlay.push(iterator);
                    }
                }
                haveJoker();
                break;
            case '三不带':
                for (const iterator of chongFuWrapArr) {
                    if (iterator.ciShu == 3 && iterator.bijiao > bijiao) {
                        canIPlay.push(iterator);
                    }
                }
                for (const iterator of chongFuWrapArr) {
                    if (iterator.ciShu == 4) {
                        canIPlay.push(iterator);
                    }
                }
                haveJoker();
                break;
            case '三带一':
                for (const iterator of chongFuWrapArr) {
                    if (iterator.ciShu == 3 && iterator.bijiao > bijiao) {
                        if (getOneCard()) {
                            canIPlay.push(iterator);
                        }
                    }
                }
                for (const iterator of chongFuWrapArr) {
                    if (iterator.ciShu == 4) {
                        canIPlay.push(iterator);
                    }
                }
                haveJoker();
                break;
            case '炸弹':
                for (const iterator of chongFuWrapArr) {
                    if (iterator.ciShu == 4 && iterator.bijiao > bijiao) {
                        canIPlay.push(iterator);
                    }
                }
                haveJoker();
                break;
            case '四带二':
                for (const iterator of chongFuWrapArr) {
                    if (iterator.ciShu == 4 && iterator.bijiao > bijiao) {
                        if (getDoubleCard()) {
                            iterator.can4 = '可压';
                            canIPlay.push(iterator);
                        }
                    }
                }
                for (const iterator of chongFuWrapArr) {
                    if (iterator.ciShu == 4) {
                        canIPlay.push(iterator);
                    }
                }
                haveJoker();
                break;
            case '三带对子':
                    for (const iterator of chongFuWrapArr) {
                        if (iterator.ciShu == 3 && iterator.bijiao > bijiao) {
                            if (getDuiZiCard()) {
                                canIPlay.push(iterator);
                            }
                        }
                    }
                    for (const iterator of chongFuWrapArr) {
                        if (iterator.ciShu == 4) {
                            canIPlay.push(iterator);
                        }
                    }
                    haveJoker();
                    break;
            case '连对':
                let tempArr = [];
                let flagt1 = true, flagt2 = true, flagt3 = false;
                for (const iterator of chongFuWrapArr) {
                    if (iterator.ciShu >= 2 && iterator.bijiao > bijiao && iterator.ciShu < 4 && iterator.bijiao < 13) {
                        tempArr.push(iterator);
                    }
                }
                if (tempArr.length >= more) {
                    for (let i = 0; i < more - 1; i++) {
                        if (tempArr[i].bijiao + 1 != tempArr[i + 1].bijiao) {
                            flagt1 = false;
                        }
                    }
                    for (let i = tempArr.length - more; i < tempArr.length - 1; i++) {
                        if (tempArr[i].bijiao + 1 != tempArr[i + 1].bijiao) {
                            flagt2 = false;
                        }
                    }
                    if (tempArr.length - more == 2 && tempArr.length > 4) {
                        flagt3 = true;
                        for (let i = 1; i < more; i++) {
                            if (tempArr[i].bijiao + 1 != tempArr[i + 1].bijiao) {
                                flagt3 = false;
                            }
                        }
                    }
                    if (flagt1) {
                        let tarr = tempArr.slice(0, more);
                        tarr.unshift(true);
                        canIPlay.push(tarr);
                    }else if (flagt2) {
                        let tarr = tempArr.slice(tempArr.length - more, tempArr.length);
                        tarr.unshift(true);
                        canIPlay.push(tarr);
                    }else if (flagt3) {
                        let tarr = tempArr.slice(1, tempArr.length - 1);
                        tarr.unshift(true);
                        canIPlay.push(tarr);
                    }
                }
                for (const iterator of chongFuWrapArr) {
                    if (iterator.ciShu == 4) {
                        canIPlay.push(iterator);
                    }
                }
                haveJoker();
                break;
            case '连子':
                {
                    let tempArr = [];
                    let flagt1 = true, flagt2 = true, flagt3 = false;
                    for (const iterator of chongFuWrapArr) {
                        if (iterator.ciShu >= 1 && iterator.bijiao > bijiao && iterator.ciShu < 4 && iterator.bijiao < 13) {
                            tempArr.push(iterator);
                        }
                    }
                    if (tempArr.length >= more) {
                        for (let i = 0; i < more - 1; i++) {
                            if (tempArr[i].bijiao + 1 != tempArr[i + 1].bijiao) {
                                flagt1 = false;
                            }
                        }
                        for (let i = tempArr.length - more; i < tempArr.length - 1; i++) {
                            if (tempArr[i].bijiao + 1 != tempArr[i + 1].bijiao) {
                                flagt2 = false;
                            }
                        }
                        if (tempArr.length - more == 2 && tempArr.length > 6) {
                            flagt3 = true;
                            for (let i = 1; i < more; i++) {
                                if (tempArr[i].bijiao + 1 != tempArr[i + 1].bijiao) {
                                    flagt3 = false;
                                }
                            }
                        }
                        if (flagt1) {
                            let tarr = tempArr.slice(0, more);
                            tarr.unshift(true);
                            canIPlay.push(tarr);
                        }else if (flagt2) {
                            let tarr = tempArr.slice(tempArr.length - more, tempArr.length);
                            tarr.unshift(true);
                            canIPlay.push(tarr);
                        }else if (flagt3) {
                            let tarr = tempArr.slice(1, tempArr.length - 1);
                            tarr.unshift(true);
                            canIPlay.push(tarr);
                        }
                    }
                    for (const iterator of chongFuWrapArr) {
                        if (iterator.ciShu == 4) {
                            canIPlay.push(iterator);
                        }
                    }
                    haveJoker();
                }
                break;
            case '王炸':
                break;
            default:
                break;
        }

        return canIPlay;
    }
    // 获取待出牌     arr:shouPaiChaXun的返回值,player:玩家手牌,index:shouPaiChaXun的返回值数组的下标(往下可依次提示),type:牌型
    function getTempCardArr(arr, player, index, type) {
        let cardObj = {};
        // 获取单牌,供三带一
        function getOneCard() {
            const chongFuWrapArr = getChongFu(player);
            chongFuWrapArr.reverse();
            for (const iterator of chongFuWrapArr) {
                if (iterator.ciShu == 1 && iterator.bijiao < 14) {
                    for (let i = 0; i < player.length; i++) {
                        if (iterator.pname == player[i].pname) {
                            let tempObj = {};
                            tempObj[i] = player[i];
                            return tempObj;
                        }
                    }
                }
            }
            for (const iterator of chongFuWrapArr) {
                if (iterator.ciShu == 2) {
                    for (let i = 0; i < player.length; i++) {
                        if (iterator.pname == player[i].pname) {
                            let tempObj = {};
                            tempObj[i] = player[i];
                            return tempObj;
                        }
                    }
                }
            }
            return 0;
        }
        // 获取2张单牌或对子,供四带二
        function getDoubleCard() {
            const chongFuWrapArr = getChongFu(player);
            chongFuWrapArr.reverse();
            let num = 0;
            let tempObj = {};
            for (const iterator of chongFuWrapArr) {
                if (iterator.ciShu == 1 && iterator.bijiao < 14) {
                    for (let i = 0; i < player.length; i++) {
                        if (iterator.pname == player[i].pname) {
                            num++;
                            tempObj[i] = player[i];
                            if (num == 2) {
                                return tempObj;
                            }
                        }
                    }
                }
            }
            for (const iterator of chongFuWrapArr) {
                if (iterator.ciShu == 2) {
                    for (let i = 0; i < player.length; i++) {
                        if (iterator.pname == player[i].pname) {
                            num++;
                            tempObj[i] = player[i];
                            if (num == 2) {
                                return tempObj;
                            }
                        }
                    }
                }
            }
            return 0;
        }
        // 获取对子,供三带对子
        function getDuiZiCard() {
            const chongFuWrapArr = getChongFu(player);
            chongFuWrapArr.reverse();
            let num = 0;
            let tempObj = {};
            for (const iterator of chongFuWrapArr) {
                if (iterator.ciShu == 2) {
                    for (let i = 0; i < player.length; i++) {
                        if (iterator.pname == player[i].pname) {
                            num++;
                            tempObj[i] = player[i];
                            if (num == 2) {
                                return tempObj;
                            }
                        }
                    }
                }
            }
            return 0;
        }
        switch (type) {
            case '单牌':
                for (let i = 0; i < player.length; i++) {
                    if (arr[index].pname == player[i].pname) {
                        if (arr[index].ciShu != 4) {
                            cardObj[i] = player[i];
                            return cardObj;
                        }else if (arr[index].ciShu == 4) {
                            cardObj[i] = player[i];
                        }
                    }else if(arr[index].pname == '王' && player[i].bijiao >= 14) {
                        cardObj[i] = player[i];
                    }
                }
                return cardObj;
            case '对子':
                for (let i = 0; i < player.length; i++) {
                    if (arr[index].pname == player[i].pname) {
                        if (arr[index].ciShu != 4) {
                            cardObj[i] = player[i];
                            if (Object.keys(cardObj).length == 2) {
                                return cardObj;
                            }
                        }else if (arr[index].ciShu == 4) {
                            cardObj[i] = player[i];
                        }
                    }else if(arr[index].pname == '王' && player[i].bijiao >= 14) {
                        cardObj[i] = player[i];
                    }
                }
                return cardObj;
            case '三不带':
                for (let i = 0; i < player.length; i++) {
                    if (arr[index].pname == player[i].pname) {
                        if (arr[index].ciShu != 4) {
                            cardObj[i] = player[i];
                            if (Object.keys(cardObj).length == 3) {
                                return cardObj;
                            }
                        }else if (arr[index].ciShu == 4) {
                            cardObj[i] = player[i];
                        }
                    }else if(arr[index].pname == '王' && player[i].bijiao >= 14) {
                        cardObj[i] = player[i];
                    }
                }
                return cardObj;
            case '三带一':
                for (let i = 0; i < player.length; i++) {
                    if (arr[index].pname == player[i].pname) {
                        if (arr[index].ciShu != 4) {
                            cardObj[i] = player[i];
                            if (Object.keys(cardObj).length == 3) {
                                let oneCard = getOneCard();
                                cardObj[Object.keys(oneCard)[0]] = Object.values(oneCard)[0];
                                return cardObj;
                            }
                        }else if (arr[index].ciShu == 4) {
                            cardObj[i] = player[i];
                        }
                    }else if(arr[index].pname == '王' && player[i].bijiao >= 14) {
                        cardObj[i] = player[i];
                    }
                }
                return cardObj;
            case '炸弹':
                for (let i = 0; i < player.length; i++) {
                    if (arr[index].pname == player[i].pname) {
                        cardObj[i] = player[i];
                    }else if(arr[index].pname == '王' && player[i].bijiao >= 14) {
                        cardObj[i] = player[i];
                    }
                }
                return cardObj;
            case '四带二':
                for (let i = 0; i < player.length; i++) {
                    if (arr[index].pname == player[i].pname) {
                        if (arr[index].can4 == '可压') {
                            cardObj[i] = player[i];
                            if (Object.keys(cardObj).length == 4) {
                                let doubleCard = getDoubleCard();
                                cardObj[Object.keys(doubleCard)[0]] = Object.values(doubleCard)[0];
                                cardObj[Object.keys(doubleCard)[1]] = Object.values(doubleCard)[1];
                                return cardObj;
                            }
                        }else if (arr[index].ciShu == 4) {
                            cardObj[i] = player[i];
                        }
                    }else if(arr[index].pname == '王' && player[i].bijiao >= 14) {
                        cardObj[i] = player[i];
                    }
                }
                return cardObj;
            case '三带对子':
                for (let i = 0; i < player.length; i++) {
                    if (arr[index].pname == player[i].pname) {
                        if (arr[index].ciShu != 4) {
                            cardObj[i] = player[i];
                            if (Object.keys(cardObj).length == 3) {
                                let duiZiObj = getDuiZiCard();
                                cardObj[Object.keys(duiZiObj)[0]] = Object.values(duiZiObj)[0];
                                cardObj[Object.keys(duiZiObj)[1]] = Object.values(duiZiObj)[1];
                                return cardObj;
                            }
                        }else if (arr[index].ciShu == 4) {
                            cardObj[i] = player[i];
                        }
                    }else if(arr[index].pname == '王' && player[i].bijiao >= 14) {
                        cardObj[i] = player[i];
                    }
                }
                return cardObj;
            case '连对':
                let num = 0;
                let j = 1;
                if (arr[index][0]) {
                    arr[index].reverse();
                    arr[index].unshift(arr[index][arr[index].length - 1]);
                    arr[index].pop();
                }
                for (let i = 0; i < player.length; i++) {
                    if (arr[index].pname == player[i].pname || arr[index][0]) {
                        if (arr[index][0]) {
                            if (arr[index][j].pname == player[i].pname) {
                                cardObj[i] = player[i];
                                if (++num == 2) {
                                    num = 0;
                                    j++;
                                }
                                if (Object.keys(cardObj).length == (arr[index].length - 1) * 2) {
                                    return cardObj;
                                }
                            }
                        }else if (arr[index].ciShu == 4) {
                            cardObj[i] = player[i];
                        }
                    }else if(arr[index].pname == '王' && player[i].bijiao >= 14) {
                        cardObj[i] = player[i];
                    }
                }
                return cardObj;
            case '连子':
                {
                    let j = 1;
                    if (arr[index][0]) {
                        arr[index].reverse();
                        arr[index].unshift(arr[index][arr[index].length - 1]);
                        arr[index].pop();
                    }
                    for (let i = 0; i < player.length; i++) {
                        if (arr[index].pname == player[i].pname || arr[index][0]) {
                            if (arr[index][0]) {
                                if (arr[index][j].pname == player[i].pname) {
                                    cardObj[i] = player[i];
                                    j++;
                                    if (Object.keys(cardObj).length == arr[index].length - 1) {
                                        return cardObj;
                                    }
                                }
                            }else if (arr[index].ciShu == 4) {
                                cardObj[i] = player[i];
                            }
                        }else if(arr[index].pname == '王' && player[i].bijiao >= 14) {
                            cardObj[i] = player[i];
                        }
                    }
                }
                return cardObj;
            default:
                break;
        }
    }
    console.log(shouPaiChaXun(player3, '单牌'));

    console.log(getTempCardArr(shouPaiChaXun(player3, '单牌'), player3, 0, '单牌'));


    // 随机获取牌型(用于人机无敌后自动出牌型)
    function getChuShenMePaiNe(whatPlayer, suijima = false) {
        let key = 100;
        if (suijima) {// 优化算法,规定算法也无法选牌则进行switch随机选牌
            key = parseInt(Math.random() * 7);
        }else {
            const chongFuWrapArr = getChongFu(whatPlayer);
            chongFuWrapArr.reverse();
            let oneArr = [];
            let twoArr = [];
            let threeArr = [];
            for (const iterator of chongFuWrapArr) {
                if (iterator.ciShu == 1) {
                    oneArr.push(iterator);
                }else if (iterator.ciShu == 2) {
                    twoArr.push(iterator);
                }else if (iterator.ciShu == 3) {
                    threeArr.push(iterator);
                }
            }
            // -----------------这里人机作弊,监视偷看我报单或报双的牌,注释掉即可关闭作弊-------------
            if (player3.length == 2 && whatPlayer.length > 2) {
                let typeCard = [];
                let renjikey;
                if (player3[0].bijiao == player3[1].bijiao) {
                    renjikey = parseInt(Math.random() * 6);
                    typeCard = renjizuobi(renjikey);
                    let canTemp = shouPaiChaXun(whatPlayer, typeCard[0], typeCard[1], typeCard[2]);
                    let num = 0;
                    while (true) {
                        if (canTemp.length > 0 || ++num == 30) {
                            break;
                        }else {
                            renjikey = parseInt(Math.random() * 6);
                            typeCard = renjizuobi(renjikey);
                            canTemp = shouPaiChaXun(whatPlayer, typeCard[0], typeCard[1], typeCard[2]);
                        }
                    }
                    return typeCard;
                }
                function renjizuobi(key) {
                    switch (key) {
                        case 0:
                            return ['单牌', 0];
                        case 1:
                            return ['三带一', 0];
                        case 2:
                            return ['三带对子', 0];
                        case 3:
                            return ['连对', 0, 3];
                        case 4:
                            return ['连子', 0, 5];
                        case 5:
                            return ['对子', player3[0].bijiao - 1];
                        default:
                            break
                    }
                }
            }else if (player3.length == 1 && whatPlayer.length > 1) {
                let typeCard = [];
                let renjikey;
                renjikey = parseInt(Math.random() * 6);
                typeCard = renjizuobi(renjikey);
                let canTemp = shouPaiChaXun(whatPlayer, typeCard[0], typeCard[1], typeCard[2]);
                let num = 0;
                while (true) {
                    if (canTemp.length > 0 || ++num == 30) {
                        break;
                    }else {
                        renjikey = parseInt(Math.random() * 6);
                        typeCard = renjizuobi(renjikey);
                        canTemp = shouPaiChaXun(whatPlayer, typeCard[0], typeCard[1], typeCard[2]);
                    }
                }
                return typeCard;
                function renjizuobi(key) {
                    switch (key) {
                        case 0:
                            return ['单牌', player3[0].bijiao - 1];
                        case 1:
                            return ['三带一', 0];
                        case 2:
                            return ['三带对子', 0];
                        case 3:
                            return ['连对', 0, 3];
                        case 4:
                            return ['连子', 0, 5];
                        case 5:
                            return ['对子', 0];
                        default:
                            break
                    }
                }
            }
            // ------------------------------------------------------------------------------
            if (oneArr.length > 4) {
                let flagL = true;
                for (let i = 0; i < 4; i++) {
                    if (oneArr[i].bijiao + 1 != oneArr[i + 1].bijiao) {
                        flagL = false;
                    }
                }
                if (flagL) {
                    return ['连子', 0, 5];
                }
            }
            if (twoArr.length > 2) {
                let flagL = true;
                for (let i = 0; i < 2; i++) {
                    if (twoArr[i].bijiao + 1 != twoArr[i + 1].bijiao) {
                        flagL = false;
                    }
                }
                if (flagL) {
                    return ['连对', 0, 3];
                }
                if (twoArr.length > 3) {
                    let flagL = true;
                    for (let i = 1; i < 3; i++) {
                        if (twoArr[i].bijiao + 1 != twoArr[i + 1].bijiao) {
                            flagL = false;
                        }
                    }
                    if (flagL) {
                        return ['连对', 0, 3];
                    }
                }
            }
            if (threeArr.length > 0 && whatPlayer.length > 6 && threeArr[0].bijiao < 9) { // 手里有三张的,手牌大于6张,三张的小于J
                if (oneArr.length < twoArr.length) {
                    return ['三带对子', 0];
                }else {
                    return ['三带一', 0];
                }
            }
            if (threeArr.length > 0 && whatPlayer.length <= 6) {
                return ['三带一', 0];
            }
            if (twoArr.length >= oneArr.length) {
                return ['对子', 0];
            }
            if (twoArr.length < oneArr.length) {
                return ['单牌', 0];
            }
        }
        switch (key) {
            case 0:
                return ['单牌', 0];
            case 1:
                return ['对子', 0];
            case 2:
                return ['三不带', 0];
            case 3:
                return ['三带一', 0];
            case 4:
                return ['三带对子', 0];
            case 5:
                return ['连对', 0, 3];
            case 6:
                return ['连子', 0, 5];
            case 7:
            case 8:
            case 9:
            case 10:
            case 11:
            case 12:
            case 13:
            case 14:
            case 15:
            case 16:
            case 17:
            case 18:
            case 19:
            case 20:
            case 21:
        
            default:
                break;
        }
        return ['王炸', 20];
    }
    // 人机1出牌
    function renJiPlay(whatPlayer, p, guo, isWuDi, danpai) { // p:true人机1, guo:true人机过,用于不误伤队友,isWuDi:true人机无敌进入随机出牌
        let typeCard; // 可出牌区桥接数组
        if (isWuDi) {
            typeCard = getChuShenMePaiNe(whatPlayer);
            while (true) {
                if (shouPaiChaXun(whatPlayer, typeCard[0], typeCard[1], typeCard[2]).length > 0) {
                    break;
                }else {
                    typeCard = getChuShenMePaiNe(whatPlayer, true);
                }
            }
            if (danpai == '单牌') {
                typeCard = ['单牌', 0];
            }
            console.log('当前随机获取牌--------------------------------',typeCard);
        }else {
            typeCard = getTangZiPaiType(); // 牌型
        }
        let canTemp = shouPaiChaXun(whatPlayer, typeCard[0], typeCard[1], typeCard[2]);
        console.log('可出牌区桥接数组',canTemp);
        if (canTemp.length == 0 || guo) {
            if (p == 'p1') {
                alert1('过', 300, 10, 'left');
            }else if (p == 'p2') {
                alert1('过', 300, 10, 'right');
            }
            otherYinXiao('过');
            return true;
        }
        let cardObj = getTempCardArr(canTemp, whatPlayer, 0, typeCard[0]); // 根据可出牌区桥接数组获取待出牌
        for (const key in cardObj) {
            whatPlayer[key] = '0';
        }
        for (let i = 0; i < whatPlayer.length; ) {
            if (whatPlayer[i] == '0') {
                whatPlayer.splice(i, 1);
            }else {
                i++;
            }
        }
        diPai = Object.values(cardObj);
        if (diPai.length == 4) {
            let isZhaDan = true;
            for (let i = 0; i < diPai.length - 1; i++) {
                if (diPai[i].pname != diPai[i + 1].pname) {
                    isZhaDan = false;
                }
            }
            if (isZhaDan) {
                nowBeiShu *= 2;
                wanduoda[1].children[0].innerHTML = `倍数: ${nowBeiShu}`;
            }
        }else if (diPai.length == 2) {
            let isZhaDan = true;
            for (let i = 0; i < diPai.length; i++) {
                if (diPai[i].bijiao < 14) {
                    isZhaDan = false;
                }
            }
            if (isZhaDan) {
                nowBeiShu *= 2;
                wanduoda[1].children[0].innerHTML = `倍数: ${nowBeiShu}`;
            }
        }
        tangZi = diPai;
        console.log(tangZi);
        let srcAudio = getTangZiPaiType();
        yinXiaoZhuangTaiChange(srcAudio);
        shuaXinTangZi();
        if (p == 'p1') {
            userBox[0].querySelector('span').innerHTML = `剩余牌数:${whatPlayer.length}`;
            if (whatPlayer.length < 3) {
                userBox[0].querySelector('div').style.display = 'block';
                if (whatPlayer.length == 2) {
                    userBox[0].querySelector('div > h6').innerHTML = '报双';
                    otherYinXiao('报双');
                }else if (whatPlayer.length == 1) {
                    userBox[0].querySelector('div > h6').innerHTML = '报单';
                    otherYinXiao('报单');
                }
            }
            chuPaiLeJianTouShow(1);
            isP1 = true;
            isP3 = isP2 = false;
        }else if (p == 'p2') {
            if (whatPlayer.length < 3) {
                userBox[1].querySelector('div').style.display = 'block';
                if (whatPlayer.length == 2) {
                    userBox[1].querySelector('div > h6').innerHTML = '报双';
                    otherYinXiao('报双');
                }else if (whatPlayer.length == 1) {
                    userBox[1].querySelector('div > h6').innerHTML = '报单';
                    otherYinXiao('报单');
                }
            }
            userBox[1].querySelector('span').innerHTML = `剩余牌数:${whatPlayer.length}`;
            chuPaiLeJianTouShow(2);
            isP2 = true;
            isP1 = isP3 = false;
        }
        return false;
    }
});

在这里插入图片描述
完整代码下载地址:单机版斗地主游戏源代码

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_42756970/article/details/128000251