保存表格

USERNAME

发消息  去主页

这里是游戏详情页,你可以查阅游戏规则和样例程序,也可以在下方找到与该游戏相关的比赛。

Mahjong-GB 详情

国标麻将

如果加载界面出现异常,建议尝试刷新

规则:http://mj.lianzhong.com/gbmj/home/teaching_new_rule1

提供Python和C++的算番库Mahjong-GB-20180521-11.zip

标准国标麻将一局有十六桌,本游戏简化为一桌,每次随机风圈

麻将牌的表示

所有麻将牌均以“大写字母+数字”组合表示。

如:“W4”表示“四万”,“B6”表示“六筒”,“T8”表示“8条”

“F1”~“F4”表示“东南西北”,“J1”~“J3”表示“中发白”,“H1”~“H8”表示“春夏秋冬梅兰竹菊”

玩家位置的表示

游戏桌按逆时针分别为“东南西北”,编号依次为0~3,如图所示。
0:东
1:南
2:西
3:北

Bot输入输出

输入输出格式参考:https://wiki.botzone.org/index.php?title=Bot

支持JSON交互和简单交互

玩家输入request每条为空格隔开的字符串数组,其格式及样例如下:

编号 信息格式 样例 说明
0 0 playerID quan 0 1 2 该信息只会出现在第一回合,playerID表示你的位置(门风),quan表示当前风圈。
1 1 hua0 hua1 hua2 hua3 Card1 Card2 ... Card13 HCard01 ... HCard0hua1 ... HCard31 ... HCard3hua3 1 1 2 1 1 W1 B1 ... T3 H1 H4 H2 H3 H6 该信息只会出现在第二回合,hua0~hua3表示四个玩家摸到的花牌数,Card1~Card13表示初始手牌,后面的hua0+...+hua3张牌表示所有人摸到的花牌。 保证Card1~Card13没有花牌,后面的均为花牌。
2 2 Card1 2 T6 表示玩家摸牌摸到Card1,保证Card1不是花牌。
3 3 playerID BUHUA Card1 3 2 BUHUA H7 该消息会发送给所有玩家,表示玩家摸牌摸到花牌Card1,并补花。
4 3 playerID DRAW 3 2 DRAW 表示其他玩家进行了摸牌操作。
5 3 playerID PLAY Card1 3 2 PLAY T1 该消息会发送给所有玩家,表示玩家摸牌后,直接打出了Card1。
6 3 playerID PENG Card1 3 2 PENG Card1 该消息会发送给所有玩家,表示玩家进行了碰牌操作,碰的牌为上一回合打出的牌,并打出了Card1。
7 3 playerID CHI Card1 Card2 3 2 CHI T2 W3 该消息会发送给所有玩家,表示玩家进行了吃牌操作,吃牌后的顺子,中间牌为Card1,并打出Card2。
8 3 playerID GANG 3 2 GANG 该消息会发送给所有玩家,表示玩家进行了杠牌操作,若上一回合为摸牌,表示进行暗杠,否则杠上回合打出的牌。
9 3 playerID BUGANG Card1 3 2 BUGANG W3 该消息会发送给所有玩家,表示玩家进行了补杠操作,补杠Card1。

玩家输出response每条为空格隔开的字符串数组,编号对应request,其格式及样例如下:

编号 信息格式 样例 说明
0 PASS PASS 表示Bot成功获得位置和风圈信息。
1 PASS PASS 表示Bot成功获得初始手牌信息。
2 PLAY Card1 PLAY T6 表示玩家摸牌后,直接打出Card1。
GANG Card1 GANG T6 表示玩家摸牌后,手牌存在四张Card1,进行杠牌,成功后会再次摸牌。
BUGANG BUGANG 表示玩家摸牌摸到一张牌,之前碰过这张牌,进行补杠,成功后会再次摸牌。
HU HU 表示玩家进行和牌,此命令后无论是否和牌,游戏结束。
3 PASS PASS 表示Bot成功获得补花信息。
4 PASS PASS 表示Bot成功获得其他玩家摸牌信息。
5 6 7 PASS PASS 表示Bot成功获得打牌信息,玩家自己的吃、碰、杠牌操作是否成功,请在此处判断。
PENG Card1 PENG T6 表示玩家手牌中有2张上一回合其他玩家打出的牌,想要进行碰牌,并打出Card1。
CHI Card1 Card2 CHI T2 T5 需要上回合为玩家上家出牌,表示玩家手牌加上上一回合其他玩家打出的牌能组成的顺子,中间牌为Card1,想要进行吃牌,并打出Card2。
GANG GANG 表示玩家手牌中有3张上一回合其他玩家打出的牌,想要进行杠牌,成功后,下回合由该玩家开始摸牌。
HU HU 表示玩家想要和牌,此命令后无论是否和牌,游戏结束。
8 PASS PASS 表示Bot成功获得杠牌信息。
9 PASS PASS 表示Bot成功获得补杠信息。
HU HU 表示玩家想要抢杠和,此命令后无论是否和牌,游戏结束。

评判方法

对于5 6 7号操作,由于和牌、吃牌、碰/杠牌可能同时出现,现规定其优先级如下:

和牌 > 碰/杠牌 > 吃牌

碰/杠牌、吃牌只可能有一个人出现,当多人和牌时,按“东南西北”顺序进行判定。

由于5 6 7操作可能失败,需要玩家自行通过下一回合的输入判断操作是否成功。

若Bot在游戏过程中发生错误,返回的操作不合法,和牌时不是和牌牌型或未到8番错和,发生错误的玩家-30分,其余玩家+10分,游戏结束。若有多个玩家同时出错,按“东南西北”的顺序判定第一个出错玩家。

样例代码

#include <iostream>
#include <string>
#include <sstream>
#include <vector>
#include <algorithm>

#ifdef _BOTZONE_ONLINE
#include "jsoncpp/json.h"
#else
#include <json/json.h>
#endif

#define SIMPLEIO 1
//由玩家自己定义,0表示JSON交互,1表示简单交互。

using namespace std;

vector<string> request, response;
vector<string> hand;

int main()
{
    int turnID;
    string stmp;
#if SIMPLEIO
    cin >> turnID;
    turnID--;
    getline(cin, stmp, '\n');
    for(int i = 0; i < turnID; i++) {
        getline(cin, stmp, '\n');
        request.push_back(stmp);
        getline(cin, stmp, '\n');
        response.push_back(stmp);
    }
    cin >> stmp;
    request.push_back(stmp);
#else
    Json::Value inputJSON;
    cin >> inputJSON;
    turnID = inputJSON["responses"].size();
    for(int i = 0; i < turnID; i++) {
        request.push_back(inputJSON["requests"][i].asString());
        response.push_back(inputJSON["responses"][i].asString());
    }
    request.push_back(inputJSON["requests"][turnID].asString());
#endif

    if(turnID < 2) {
        response.push_back("PASS");
    } else {
        int itmp, myPlayerID, quan;
        ostringstream sout;
        istringstream sin;
        sin.str(request[0]);
        sin >> itmp >> myPlayerID >> quan;
        sin.clear();
        sin.str(request[1]);
        for(int j = 0; j < 5; j++) sin >> itmp;
        for(int j = 0; j < 13; j++) {
            sin >> stmp;
            hand.push_back(stmp);
        }
        for(int i = 2; i < turnID; i++) {
            sin.clear();
            sin.str(request[i]);
            sin >> itmp;
            if(itmp == 2) {
                sin >> stmp;
                hand.push_back(stmp);
                sin.clear();
                sin.str(response[i]);
                sin >> stmp >> stmp;
                hand.erase(find(hand.begin(), hand.end(), stmp));
            }
        }
        sin.clear();
        sin.str(request[turnID]);
        sin >> itmp;
        if(itmp == 2) {
            random_shuffle(hand.begin(), hand.end());
            sout << "PLAY " << *hand.rbegin();
            hand.pop_back();
        } else {
            sout << "PASS";
        }
        response.push_back(sout.str());
    }

#if SIMPLEIO
    cout << response[turnID] << endl;
#else
    Json::Value outputJSON;
    outputJSON["response"] = response[turnID];
    cout << outputJSON << endl;
#endif
    return 0;
}

未完待续

相关的比赛开始时间
没有开放的比赛
?