仪征麻将3.4版

本次更新内容

一,修复普通胡牌模式下有对子、杠时的胡牌公示错误
二,修复了可以弃置一张没有的牌的错误
三,将随机化牌堆的起始点位设为随机变量,增加公平性
四,增加系统判断玩家能否开杠
五,优化操作界面,且配子显示在左边,方便玩家统筹全局
六,新增一局游戏结束后可以进行下一局游戏
七,新增对对胡,浑一色,杠后炮判定
八,新增仪征麻将规则:当其他人打出一张牌,拿过这张牌你可以胡,但你的胡牌方式为不是对对胡,不是浑一色,有配子,普通方式(即不是七对),你不能拿过这张牌
九,新增庄家玩法,让玩家体验投掷筛子过程,更加原汁原味
十,当前版本,不再需要手动更改mt19937 rnd()里的随机数,简化操作

代码

#include <iostream>
using namespace std;
#include <set>
#include <algorithm>
#include <cmath>
#include <map>
#include <cstdio>
#include <string>
#include <cstring>
#include <string.h>
#include <stdlib.h>
#include <iomanip>
#include <fstream>
#include <stdio.h>
#include <stack>
#include <queue>
#include <ctype.h>
#include <vector>
#include <random>
#define ll long long
#define pb push_back
#define rep(i, a, n) for (int i = a; i <= n; i++)
#define per(i, a, n) for (int i = n; i >= a; i--)
#define pii pair<int, int>
#define pli pair<ll, int>
#define pil pair<int, ll>
#define endl '\n'
const double pai = acos(-1);
ll extend_gcd(ll a, ll b, ll& x, ll& y)
{
    if (b == 0)
    {
        x = 1;
        y = 0;
        return a;
    }
    ll d = extend_gcd(b, a % b, y, x);
    y -= a / b * x;
    return d;
}
ll fastpow(ll a, ll n, ll mod)
{
    ll ans = 1;
    a %= mod;
    while (n)
    {
        if (n & 1)
            ans = (ans * a) % mod;
        a = (a * a) % mod;
        n >>= 1;
    }
    return ans;
}
int dir[4][2] =
{
    {0, 1}, {0, -1}, {1, 0}, {-1, 0} };

const int inf = 100000000;
const ll mod = 1e9 + 7;
const int N = 1e5 + 10, M = 5000 + 10;

// 变量设定区
int sum = 84;                    // 记录剩余的麻将数
multiset<int> all;               // 存所有牌(临时数组)
set<int> duizi[5], gang[5];      // 存每个人已经打出的对子和杠(对子和杠不算手牌)
int card[5][35];                 // 存每个人现有手牌
int ever[35], every_ever[5][35]; // 存全部玩家和单个玩家曾经打出的牌(包括对子和杠)
bool flag[5];                    // 记录单个玩家是否还符合"七对"成牌条件(即打出至少一个对子或杠则不满足"七对")
int paidui[69][3];               // 存每一个位置的牌
bool vis[69][3];                 // 存每一个位置的牌有无被摸过
int firs;                        // 目前抓牌的垒数
int now;                         // 目前抓牌的层数
int lastt;                       // 最后一张牌的位置(开杠摸牌专用)
int peizi;                       // 配子的数字号
int temp;//场上现在打出的牌
int noww;//当前打出牌的人
int a[20];//判定能否成牌的数组
bool viss[20];//dfs搜索成牌的数组
bool flag2;
int bb[20];
int zhanshi[20];
bool ifzhengchangkaigang = 0, ifzhuijiakaigang = 0;
bool out;//记录当局游戏是否结束
int qipairen;//弃牌人
bool hunyise = 0, duiduihu = 0;
ll money[5];//记录每个玩家的钱
bool winner[5];//记录每个玩家是否胡牌
int zhuangjia[500];//记录庄家是谁
//

mt19937 rnd(1783);//改动rnd()里面的那个数字,即是一次全新的牌局,这个是随机种子

void dfs(int ceng)
{
    if (ceng != 1 && (ceng - 1) % 3 == 0)
    {
        if ((a[ceng - 3] == a[ceng - 2] && a[ceng - 2] == a[ceng - 1])
            || (a[ceng - 3] == a[ceng - 2] && a[ceng - 1] == peizi) || (a[ceng - 3] == a[ceng - 1] && a[ceng - 2] == peizi) || (a[ceng - 2] == a[ceng - 1] && a[ceng - 3] == peizi)
            || (a[ceng - 3] == peizi && a[ceng - 2] == peizi) || (a[ceng - 1] == peizi && a[ceng - 2] == peizi)
            || (a[ceng - 3] == peizi && a[ceng - 1] == peizi)
            || (a[ceng - 3] + 1 == a[ceng - 2] && a[ceng - 2] + 1 == a[ceng - 1] && (a[ceng - 3] <= 7 || (10 <= a[ceng - 3] && a[ceng - 3] <= 16) || (19 <= a[ceng - 3] && a[ceng - 3] <= 25)))
            || (a[ceng - 3] == peizi && a[ceng - 2] + 1 == a[ceng - 1] && (a[ceng - 2] <= 8 || (10 <= a[ceng - 2] && a[ceng - 2] <= 17) || (19 <= a[ceng - 2] && a[ceng - 2] <= 26)))
            || (a[ceng - 2] == peizi && a[ceng - 3] + 2 == a[ceng - 1] && (a[ceng - 3] <= 7 || (10 <= a[ceng - 3] && a[ceng - 3] <= 16) || (19 <= a[ceng - 3] && a[ceng - 3] <= 25)))
            || (a[ceng - 1] == peizi && a[ceng - 3] + 1 == a[ceng - 2] && (a[ceng - 3] <= 8 || (10 <= a[ceng - 3] && a[ceng - 3] <= 17) || (19 <= a[ceng - 3] && a[ceng - 3] <= 26))))
        {

        }
        else
        {
            /*
            rep(i, 1, 14)
            {
                cout << a[i] << " ";
            }
            cout << endl;
            */
            return;
        }
    }
    
    if (ceng == 15)
    {
        if (a[13] == a[14] ||a[13]==peizi || a[14]==peizi )//胡牌
        {
            //浑一色判定
            int f = 0, g = 0, h = 0;//有无万,有无条,有无饼
            rep(i, 1, 14)
            {
                zhanshi[i] = a[i];
                if (1<=a[i]&&a[i]<=9)
                {
                    f = 1;
                }
                else if (10 <= a[i] && a[i] <= 18)
                {
                    g = 1;
                }
                else if (19 <= a[i] && a[i] <= 27)
                {
                    h = 1;
                }
            }
            if (f + g + h <= 1)
            {
                hunyise = 1;
            }
            //
            
            //对对胡判定
            int duidui = 0;
            for (int i = 4; i <= 13; i += 3)
            {
                if ((a[i - 3] == a[i - 2] && a[i - 2] == a[i - 1])
                    || (a[i - 3] == a[i - 2] && a[i - 1] == peizi) || (a[i - 3] == a[i - 1] && a[i - 2] == peizi) || (a[i - 2] == a[i - 1] && a[i - 3] == peizi)
                    || (a[i - 3] == peizi && a[i - 2] == peizi) || (a[i - 1] == peizi && a[i - 2] == peizi)
                    || (a[i - 3] == peizi && a[i - 1] == peizi))
                {
                    duidui++;
                }
            }
            if (duidui == 4)
            {
                duiduihu = 1;
            }
            //

            flag2 = 1;
        }
        return;
    }
    rep(i, 1, 14)
    {
        if (viss[i] == 0)
        {
            viss[i] = 1;
            a[ceng] = bb[i];
            dfs(ceng + 1);
            viss[i] = 0;
        }
    }
}

int ifsucceed(int x)
{
    if (flag[x]) //自动检测能否七对胡牌
    {
        //统计除了配子外有多少组两张牌
        int num_two = 0;
        rep(i, 1, 34)
        {
            if (i == peizi)
            {
                continue;
            }
            num_two += card[x][i] / 2;
        }
        if (num_two + card[x][peizi] >= 7)//ok
        {
            return 2;
        }
    }
    //dfs搜索检测能否常规成牌
    int cnt = 0;
    for (auto i : duizi[x])
    {
        rep(j, 1, 3)
        {
            bb[++cnt] = i;
        }
    }
    for (auto i : gang[x])
    {
        rep(j, 1, 3)
        {
            bb[++cnt] = i;
        }
    }
    rep(i, 1, 34)
    {
        rep(j, 1, card[x][i])
        {
            bb[++cnt] = i;
        }
    }
    flag2 = 0;
    fill(viss + 1, viss + 15, 0);
    fill(a + 1, a + 15, 0);
    hunyise = duiduihu = 0;
    dfs(1);
    if (flag2)
    {
        return 1;
    }
    return 0;
}

void showw(int x);

void hupai(int x,int method)
{
    winner[x] = 1;
    out = 1;
    cout << x << "号玩家的胡牌模式公示:" << endl<<endl;
    rep(i, 1, 14)
    {
        showw(zhanshi[i]);
    }
    cout << endl << endl;
    cout << "恭喜" << x << "号玩家";
    if (method == 1)
    {
        cout << "普通方式";
        if (duiduihu)
        {
            cout << " 对对胡 ";
        }
        if (hunyise)
        {
            cout << " 浑一色 ";
        }
        cout<<"胡牌" << endl;
    }
    else
    {
        cout << "七对方式胡牌" << endl;
    }
    cout << "祝您龙年大吉,在龙年打出属于你的独特的王者龙耀" << endl<<endl;
}

int print_feng(int x)
{
    cout << "本局游戏的配子是: ";
    if (x % 4 == 1)
    {
        cout << "东风";
        cout << endl;
        return x;
    }
    else if (x % 4 == 2)
    {
        cout << "南风";
        cout << endl;
        return x + 17;
    }
    else if (x % 4 == 3)
    {
        cout << "西风";
        cout << endl;
        return x + 34;
    }
    else if (x % 4 == 0)
    {
        cout << "北风";
        cout << endl;
        return x + 51;
    }
}

void showw(int i)
{
    if (i <= 9)
    {
        cout << "  " << i << "万  ";
    }
    else if (i <= 18)
    {
        cout << "  " << i - 9 << "条  ";
    }
    else if (i <= 27)
    {
        cout << "  " << i - 18 << "饼  ";
    }
    else if (i == 28)
    {
        cout << " 东风  ";
    }
    else if (i == 29)
    {
        cout << " 南风  ";
    }
    else if (i == 30)
    {
        cout << " 西风  ";
    }
    else if (i == 31)
    {
        cout << " 北风  ";
    }
    else if (i == 32)
    {
        cout << " 红中  ";
    }
    else if (i == 33)
    {
        cout << " 白皮  ";
    }
    else if (i == 34)
    {
        cout << " 发财  ";
    }
}

void show(int x)//展示x号玩家手牌
{
    cout << "第" << x << "号玩家的牌为:" << endl<<endl;
    cout << "序列号:            ";
    rep(j, 1, card[x][peizi])
    {
        cout << "  ";
        cout << setw(2) << peizi;
        cout << "   ";
    }
    cout << "   ";
    rep(i, 1, 34)
    {
        if (i == peizi)
        {
            continue;
        }
        rep(j, 1, card[x][i])
        {
            cout << "  ";
            cout << setw(2) << i;
            cout << "   ";
        }
        if (i % 9 == 0)
        {
            cout << "   ";
        }
    }
    cout << endl << endl;
    cout << "牌名:              ";
    rep(j, 1, card[x][peizi])
    {
        showw(peizi);
    }
    cout << "   ";
    rep(i, 1, 34)
    {
        if (i == peizi)
        {
            continue;
        }
        rep(j, 1, card[x][i])
        {
            showw(i);
        }
        if (i % 9 == 0)
        {
            cout << "   ";
        }
    }
    cout << endl << endl;
    cout << "场上已打出张数:    ";
    rep(j, 1, card[x][peizi])
    {
        cout << "  ";
        cout << setw(2) << ever[peizi];
        cout << "   ";
    }
    cout << "   ";
    rep(i, 1, 34)
    {
        if (i == peizi)
        {
            continue;
        }
        rep(j, 1, card[x][i])
        {
            cout << "  ";
            cout << setw(2) << ever[i];
            cout << "   ";
        }
        if (i % 9 == 0)
        {
            cout << "   ";
        }
    }

    cout << endl << endl;
    cout << "对子为 ";
    for (auto i : duizi[x])
    {
        showw(i);
    }
    cout << endl << endl;
    cout << "杠为 ";
    for (auto i : gang[x])
    {
        showw(i);
    }
    cout << endl
        << endl;
    cout << "本局配子是";
    showw(peizi);
    cout << endl<<endl<<endl;
}

void huangzhuang()
{
    cout << "荒庄,所有牌已被摸完,游戏结束。感谢您的参与" << endl;
    exit(0);
}

int kaigang() // 开杠后最后摸一张牌并打一张牌,返回摸的那张牌的序列号
{
    if (sum == 0)
    {
        huangzhuang();
    }
    sum--;
    if (vis[lastt][1] == 0)
    {
        vis[lastt][1] = 1;
        return paidui[lastt][1];
    }
    else
    {
        if (vis[lastt][2] == 0)
        {
            vis[lastt][2] = 1;
            return paidui[lastt][2];
        }
        else//这垒牌已经打掉,到前一垒牌搜索
        {
            lastt--;
            if (lastt == 0)
            {
                lastt = 68;
            }
            if (vis[lastt][1] == 0)
            {
                vis[lastt][1] = 1;
                return paidui[lastt][1];
            }
            else
            {
                vis[lastt][2] = 1;
                return paidui[lastt][2];
            }
        }
    }
}

void showthrow(int x)
{
    if (x == 0)
    {
        cout << "现在场上已打出手牌为:" << endl << endl;
        rep(i, 1, 34)
        {
            showw(i);
            if (i % 9 == 0)
            {
                cout << endl << endl;
                rep(j, i - 8, i)
                {
                    cout << "  ";
                    cout << setw(2) << ever[j];
                    cout << "   ";
                }
                cout << endl << endl;
            }
        }
        cout << endl << endl;
        rep(j, 28, 34)
        {
            cout << "  ";
            cout << setw(2) << ever[j];
            cout << "   ";
        }
        cout << endl << endl;
    }
    else
    {
        rep(i, 1, 34)
        {
            showw(i);
            if (i % 9 == 0)
            {
                cout << endl << endl;
                rep(j, i - 8, i)
                {
                    cout << "  ";
                    cout << setw(2) << every_ever[x][j];
                    cout << "   ";
                }
                cout << endl << endl;
            }
        }
        cout << endl << endl;
        rep(j, 28, 34)
        {
            cout << "  ";
            cout << setw(2) << every_ever[x][j];
            cout << "   ";
        }
        cout << endl << endl;
    }
    
}


void phase(int x);

void getcard(int x)
{
    do
    {
        if (now == 2)
        {
            firs++;
            if (firs == 69)
            {
                firs = 1;
            }
        }
        now = 3 - now;
    } while (vis[firs][now]);
    vis[firs][now] = 1;
    card[x][paidui[firs][now]]++; // 牌抓进来
    cout << "您抓的牌是";
    showw(paidui[firs][now]);
    cout << endl;
}

void getcard2(int x)
{
    cout << "您抓的牌是";
    int tee = kaigang();//注:vis标记在kaigang()函数里
    card[x][tee]++;
    showw(tee);
    cout << endl;
}

void take(int x);
void throwcard(int x,int y);

void judgekaigang(int x)
{
    ifzhengchangkaigang = 0, ifzhuijiakaigang = 0;
    //提示该玩家能否开杠
    rep(i, 1, 34)
    {
        if (card[x][i] == 4)
        {
            cout << endl << endl;
            cout << "对于";
            showw(i);
            cout << ",您可以正常开杠(暗杠)" << endl;
            ifzhengchangkaigang = 1;
        }
        if (card[x][i] && duizi[x].count(i))
        {
            cout << endl << endl;
            cout << "对于";
            showw(i);
            cout << ",您可以追加对子开杠" << endl;
            ifzhuijiakaigang = 1;
        }
    }
    if (ifzhengchangkaigang == 0 && ifzhuijiakaigang == 0)
    {
        return;
    }
}

void ask(int x)//问x号玩家是否需要temp这张牌
{
    if (out)
    {
        return;
    }
    bool b = 0, c = 0;
    if (card[x][temp] >= 2)
    {
        b = 1;
    }
    if (card[x][temp] >= 3)
    {
        c = 1;
    }
    if (b == 0 && c == 0)
    {
        return;
    }
    system("cls");
    show(x);
    cout << noww << "号玩家,对于您的";
    int tem = noww;
    tem++;
    if (tem == 5)
    {
        tem = 1;
    }
    if (tem == qipairen)
    {
        cout << "下家";
    }
    tem++;
    if (tem == 5)
    {
        tem = 1;
    }
    if (tem == qipairen)
    {
        cout << "对面";
    }
    tem++;
    if (tem == 5)
    {
        tem = 1;
    }
    if (tem == qipairen)
    {
        cout << "上家";
    }
    cout << qipairen << "号";
    cout<<"打出的这张牌";
    showw(temp);
    if (b)
    {
        cout << "对对子请按2 ";
    }
    if (c)
    {
        cout << "开杠请按3 ";
    }
    cout << "不需要请按0"<<endl;
    int te;
    cin >> te;
    if (te == 0)
    {
        return;
    }
    if (te == 2&&b)
    {
            flag[x] = 0;//失去七对条件
            system("cls");
            cout << "对对子成功" << endl;
            card[x][temp] -= 2;
            duizi[x].insert(temp);
            ever[temp] += 3;
            every_ever[x][temp] += 3;
            // 接着x玩家需要打出一张牌
            show(x);
            throwcard(x, 0);
    }
    if (te == 3&&c )
    {
        flag[x] = 0;//失去七对条件
            system("cls");
            cout << "开杠成功" << endl;
            card[x][temp] -= 3;
            gang[x].insert(temp);
            ever[temp] += 4;
            every_ever[x][temp] += 4;
            getcard2(x);//牌堆最后摸一张
            show(x);
            int win = ifsucceed(x);
            if (win)
            {
                cout << "您已达成胡牌条件,并且是 杠后炮 ,直接胡牌请按1,放弃请按2:" << endl;
                int ch;
                cin >> ch;
                if (ch == 1)
                {
                    cout << "恭喜你杠后炮胡牌,大吉大利,今晚吃鸡" << endl<<endl;
                    hupai(x, win);
                    return;
                }
            }
            throwcard(x, 0);
    }
}

void throwcard(int x,int number)//x号玩家弃牌阶段
{
    if (out)
    {
        return;
    }
    qipairen = x;
    if (number == 0)
    {
        showthrow(0);
        t1:
        do
        {
            cout << "请弃置一张牌" << endl<<endl;
            cin >> temp;
        } while (temp < 1 || temp>34 || card[x][temp] == 0);

        if (temp == peizi)
        {
            cout << "这张牌是配子,坚持弃牌请按1,重新弃牌请按2" << endl;
            int ch;
            cin >> ch;
            if (ch == 2)
            {
                goto t1;
            }
        }
    }
    else
    {
        temp = number;
    }
    card[x][temp]--;
    noww = x;
    //优先考虑是否有玩家这张能成牌,考虑至少两个玩家同时成牌的情况
    bool flaggg = 0;
    rep(i, 1, 3)
    {
        noww++;
        if (noww == 5)
        {
            noww = 1;
        }
        card[noww][temp]++;
        int win = ifsucceed(noww);
        card[noww][temp]--;
        if (win&&!(win==1&&card[noww][peizi]&&duiduihu==0&&hunyise==0))
        {
            cout << endl;
            show(noww);
            cout << noww << "号玩家,拿过";
            showw(temp);
            cout<<"这张牌您可以胡牌,拿取请按1,不拿请按0:" << endl;
            int te;
            cin >> te;
            if (te == 1)
            {
                hupai(noww, win);
                flaggg = 1;
            }
        }
    }
    if (flaggg)
    {
        cout << "游戏结束" << endl;
        return;
    }

    noww = x;
    rep(i, 1, 3)
    {
        noww++;
        if (noww == 5)
        {
            noww = 1;
        }
        ask(noww);//询问
    }
    // temp这张牌别人没拿,是x自己打出的
    ever[temp]++;
    every_ever[x][temp]++;
    if (x == 4)
    {
        phase(1);
    }
    else
    {
        phase(x + 1);
    }
}

void phase(int x)
{
    if (out)
    {
        return;
    }
    system("cls");
    if (sum == 0)
    {
        huangzhuang();
    }
    sum--;
    cout << "现在是" << x << "号玩家的回合:"<<endl;
    // 抓牌
    getcard(x);
    //展示手牌
    show(x);

    int win = ifsucceed(x);
    if (win)
    {
        cout << "您已达成胡牌条件,直接胡牌请按1,放弃请按2:" << endl;
        int ch;
        cin >> ch;
        if (ch == 1)
        {
            hupai(x, win);
            return;
        }
    }
    showthrow(0);
    judgekaigang(x);

p1:
    int te;
    do
    {
        cout << "正常弃牌按序列号,";
        if (ifzhengchangkaigang || ifzhuijiakaigang)
        {
            cout << "开杠按35,";
        }
        cout<<"查询单个选手已打过手牌分别按41, 42, 43, 44" << endl<<endl;
        cin >> te;
    } while (te < 1 || te>44 || (36 <= te && te <= 40)||(ifzhengchangkaigang==0&&ifzhuijiakaigang==0&&te==35));
    if (1 <= te && te <= 34 && card[x][te] == 0)
    {
        cout << "您没有这张牌,请重新弃牌" << endl;
        goto p1;
    }

    if (te >= 41)//查询功能
    {
        cout << endl;
        cout << te - 40 << "号玩家已经打出的手牌为:" << endl << endl;
        showthrow(te - 40);
        goto p1;
    }
    else if (te == 35)
    {
        cout << "正常开杠请按1,追加对子开杠请按2:" << endl;
        int ch;
        cin >> ch;
        if (ch == 1)
        {
            cout << "请输入开杠的牌的序列号:" << endl;
            int tem;
            cin >> tem;
            if (card[x][tem] == 4)
            {
                flag[x] = 0;
                gang[x].insert(tem);
                card[x][tem] = 0;
                ever[tem] = 4;
                every_ever[x][tem] = 4;
                cout << "开杠成功" << endl;
                getcard2(x);
                show(x);
                throwcard(x,0);
            }
            else
            {
                cout << "不符合开杠条件" << endl;
                goto p1;
            }
        }
        else
        {
            cout << "请输入开杠的序列号:" << endl;
            int tem;
            cin >> tem;
            if (duizi[x].count(tem) && card[x][tem])
            {
                card[x][tem] = 0;
                ever[tem]++;
                every_ever[x][tem]++;
                duizi[x].erase(tem);
                gang[x].insert(tem);
                cout << "开杠成功" << endl;
                getcard2(x);
                show(x);
                throwcard(x,0);
            }
            else
            {
                cout << "不符合开杠条件" << endl;
                goto p1;
            }
        }
    }
    temp = te;
    if (temp == peizi)
    {
        cout << "这张牌是配子,坚持弃牌请按1,重新弃牌请按2" << endl;
        int ch;
        cin >> ch;
        if (ch == 2)
        {
            goto p1;
        }
    }

    //正常回合结束
    
    throwcard(x, temp);
}
int main()
{
    cout << "尊敬的玩家,你们好,仪征麻将欢迎您的光临!" << endl << endl;
    cout << "仪征麻将不可以吃,有配子,配子可以当做任意牌" << endl << endl;
    cout << "当其他人打出一张牌,拿过这张牌你可以胡,但如果你有配子,且胡牌方式为不是对对胡,不是浑一色,普通方式(即不是七对),你不能拿过这张牌" << endl << endl;
    int lunci = 0;
    
    //确定第一个庄家
    cout << "由1号玩家投掷筛子来确定第一个庄家,请输入两个整数(不要太大)" << endl<<endl;
    int e, f;
    cin >> e >> f;
    zhuangjia[1] = (e * f + rnd()) % 4 + 1;
m1:
    fill(winner + 1, winner + 5, 0);
    out = 0;
    lunci++;
    if (lunci >= 2)
    {
        system("cls");
    }
    cout << "这是第" << lunci << "局游戏" << endl;
    cout << "庄家是第" << zhuangjia[lunci] << "号玩家" << endl;
    if (zhuangjia[lunci] == zhuangjia[lunci - 1])
    {
        cout << "恭喜他连庄,目前势如破竹" << endl;
    }
    cout<<"请输入两个整数(不要太大)作为投掷筛子的随机种子" << endl;
    cin >> e >> f;
    rep(i, 1, 4)
    {
        rep(j, 1, 34)
        {
            card[i][j] =every_ever[i][j]= 0;
        }
        duizi[i].clear();
        gang[i].clear();
    }
    fill(ever + 1, ever + 35, 0);
    fill(flag + 1, flag + 5, 1); //"七对"成牌条件初始设定为真
    rep(i, 1, 34)
    {
        rep(j, 1, 4)
        {
            all.insert(i);
        }
    }
    
    // 初始化牌堆麻将
    int temp = 136;
    int cnt = (rnd()*lunci)%68+1;
    while (temp)
    {
        cnt++;
        if (cnt == 69)
        {
            cnt = 1;
        }
        int suiji = rnd() % temp;
        auto it = all.begin();
        rep(i, 1, suiji)
        {
            it++;
        }
        paidui[cnt][1] = *it;//1为牌堆上层
        all.erase(it);
        temp--;
        suiji = rnd() % temp;
        it = all.begin();
        rep(i, 1, suiji)
        {
            it++;
        }
        paidui[cnt][2] = *it;//2为牌堆下层
        all.erase(it);
        temp--;
    }
    //

    int shai_first = (e+rnd()) % 6 + 1, shai_second = (f*rnd()) % 6 + 1;
    cout << "投掷骰子的点数分别是" << shai_first << " " << shai_second << endl;
    firs = print_feng(shai_first + shai_second); // 告知玩家是什么配子,算出起始敦数减1
    firs += 17 * (zhuangjia[lunci] - 1);
    while (firs > 68)
    {
        firs -= 68;
    }
    lastt = firs;//最后的敦数,预留给开杠牌
    peizi = shai_first + shai_second;
    while (peizi > 4)
    {
        peizi -= 4;
    }
    peizi += 27;//确定本局配子的序号数

    // 发牌
    rep(ii, 1, 3)
    {
        rep(i, 1, 4) // 四个人
        {
            rep(j, 1, 2) // 两垒牌
            {
                firs++;
                if (firs == 69) // 越界
                {
                    firs = 1;
                }
                rep(k, 1, 2) // 两层
                {
                    int now = paidui[firs][k];
                    card[i][now]++;
                    vis[firs][k] = 1;
                }
            }
        }
    }
    now = 2;
    rep(i, 1, 4) // 四个人补齐最后一张牌
    {

        if (now == 2)//这垒牌已经摸完了
        {
            firs++;
        }
        now = 3 - now;
        card[i][paidui[firs][now]]++;
        vis[firs][now] = 1;
    }
    cout << "游戏已准备就绪!\n按1开始游戏" << endl;
    int tt;
    cin >> tt;
    phase(1);
    cout << "开始下一局游戏请按1,退出游戏请按0" << endl << endl;
    cin >> tt;
    if (tt == 1)
    {
        if (winner[zhuangjia[lunci]])
        {
            zhuangjia[lunci + 1] = zhuangjia[lunci];
        }
        else
        {
            if (zhuangjia[lunci] == 4)
            {
                zhuangjia[lunci + 1] = 1;
            }
            else
            {
                zhuangjia[lunci + 1] = zhuangjia[lunci]+1;
            }
        }
        goto m1;
    }
    else
    {
        cout << "游戏结束,我们下次再会~" << endl;
    }
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值