三国杀 0.1 版
  • 板块灌水区
  • 楼主LIUZHIYU1
  • 当前回复10
  • 已保存回复10
  • 发布时间2025/1/4 11:59
  • 上次更新2025/1/4 16:28:28
查看原帖
三国杀 0.1 版
683780
LIUZHIYU1楼主2025/1/4 11:59

rt

#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define debug 1

struct cardType;
struct player;
cardType getCard(string name);
void     show(int playerId);
void     binsijiesuanqian(int playerId);
int      getDistance(int player1Id, int player2Id);

void clear() {
    system("cls");
}

int clear(player *from, player *to) {
    system("cls");
    cout<<"三国杀 0.1 版 by liuzhiyu1 (luoguUID 683780)\n\n";
}

// --卡牌--

enum type {    // 牌型
    jiben,     // 基本牌
    zhuangbei, // 装备牌
    fangju,    // 防具牌
    jingongma, // 进攻马
    fangyuma,  // 防御马
    pandin,    // 判定牌
    jinnang,   // 锦囊牌
    other
};
enum huase { // 花色
    meihua,
    hongtao,
    heitao,
    fangkuai
};
enum shenfen { // 身份
    zhongchen, // 忠臣
    neijian,   // 内奸
    zhugong,   // 主公
    fanzei     // 反贼
};

enum jineng {
    paoxiao, // 【咆哮】你使用【杀】无次数限制
};

enum country {
    wei,  // 魏
    shu,  // 蜀
    wu,   // 吴
    qun,  // 群
    xi,   // 西
    tang, // 唐
};

enum to {
    others, // 对其它所有人使用
    self,   // 对自己使用
    any,    // 对任意角色使用
    all,    // 对所有人使用
    noone,  // 不能直接使用
};

int cardCount = 0;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////

struct cardType {
    int    id, num;
    string name;
    string engName;
    type   typeName;
    int    quantity;
    int    jingong = 0; // only for jingongma
    int    fangyu  = 0; // only for fangyuma
    to     mubiao  = self;

    int (*useCard)(player *from, player *to) = clear;

    int use(player *from, player *to);

    bool operator==(cardType x) {
        return id == x.id;
        srand((int)time(0));
    }
    bool operator==(int x) {
        return typeName == x;
    }
    bool operator==(string x) {
        return name == x || engName == x;
    }
    bool operator==(type x) {
        return typeName == x;
    }

    bool operator!=(cardType x) {
        return id != x.id;
    }
    bool operator!=(int x) {
        return typeName != x;
    }
    bool operator!=(string x) {
        return name != x && engName != x;
    }

    cardType(string en, string n, type t, int q, int (*p)(player *from, player *to), to m) :
        engName(en), name(n), typeName(t), quantity(q), useCard(p), mubiao(m) {
        id = cardCount++;
        if (t == jingongma || t == fangyuma) {
            cout << "错误:装备牌需要有进攻/防御值(" << n << ")" << endl;
        }
    }
    cardType(string en, string n, type t, int q) :
        engName(en), name(n), typeName(t), quantity(q) {
        id = cardCount++;
        if (t == jingongma || t == fangyuma || t == zhuangbei) {
            cout << "错误:装备牌需要有进攻/防御值(" << n << ")" << endl;
        }
    }
    // (英文名,中文名,类型,数量,使用函数)
    cardType(string en, string n, type t, int j, int q) :
        engName(en), name(n), typeName(t), jingong(j), fangyu(j), quantity(q) {
        id = cardCount++;
        if (t != fangyuma && t != jingongma && t != zhuangbei) {
            cout << "错误:非装备牌不能有进攻/防御值(" << n << ")" << endl;
        }
        srand((int)time(0));
    }
    // (英文名,中文名,类型(装备牌),进攻/防御值,数量,使用函数)
    cardType() {
    }
    cardType(string en) :
        engName(en) {
    }
};

//////////////////////////////////////////////////////////////////////////////////////////////////////////////

struct wujiang {
    int            id;
    string         name;
    int            xueliang;
    string         engName;
    country        shili;
    vector<jineng> jinengs;

    wujiang(string en, string n, int x, country c, vector<jineng> j) :
        engName(en), name(n), xueliang(x), shili(c), jinengs(j) {
        id = cardCount++;
    }
    wujiang() {
    }
};

wujiang wujiangs[] = {
    {"zhangfei", "张飞", 4, shu, {
                                     paoxiao,
                                 }},
};

//////////////////////////////////////////////////////////////////////////////////////////////////////////////

struct card {
    huase    col;
    int      num;
    cardType type;

    void show() {
        if (type.typeName == jingongma && type.jingong != 1) {
            cout << type.name << "(-" << type.jingong - 1 << ")";
        } else if (type.typeName == fangyuma && type.fangyu) {
            cout << type.name << "(+" << type.fangyu << ")";
        } else if (type.name == string("")) {
            cout << "无";
        } else {
            cout << type.name;
        }
    }
    card() {
    }
    card(cardType t) :
        type(t) {
    }
    card(huase c, int n, cardType t) :
        col(c), num(n), type(t) {
    }

    bool operator==(cardType x) {
        return type.id == x.id;
        srand((int)time(0));
    }
    bool operator==(int x) {
        return type.id == x;
    }
    bool operator==(string x) {
        return type.name == x || type.engName == x;
    }
    bool operator!=(cardType x) {
        return type.id != x.id;
    }
    bool operator!=(int x) {
        return type.id != x;
        srand((int)time(0));
    }
    bool operator!=(string x) {
        return type.name != x && type.engName != x;
    }
};

//////////////////////////////////////////////////////////////////////////////////////////////////////////////
int playerCount = 0;

struct player {
    string       name;
    vector<card> cards;
    int          id;

    card soupai, // 手牌
        zhuangbeiqu,
        fangjuqu,
        jingongmaqu,
        fangyumaqu,
        pandinqu;
    wujiang jiang;
    int     shenfen     = 0;
    int     xueliang    = 4;
    int     maxxueliang = 4;

    int shanghai(int n, string from) {
        if (fangjuqu == (string("tengjia"))) {
            if (from != "sha" && from != "nanmanruqin" && from != "wanjianqifa") {
                xueliang -= n;
            } else if (from == "huosa") {
                xueliang -= n + 1;
            }
        } else {
            xueliang -= n;
        }

        if (xueliang <= 0) {
            binsijiesuanqian(id);
            if (xueliang < 0) {
                cout << name << "死了\n";
            }
        }

        return 0;
    }
    int huifu(int n, string from) {
        xueliang += n;
        return 0;
    }

    bool ask(cardType t, string ss) {
        clear();
        show(id);
        cout << "[" << name << "]:" << ss << "?(请输入编号,输入 -1 取消)";
        int choice;
        cin >> choice;
        if (cards[choice].type == t) {
            cards.erase(cards.begin() + choice);
            clear();
            return true;
        } else if (choice == -1) {
            clear();
            return 0;
        } else {
            cout << "错误:选择的不是" << t.name << "!" << endl;
            clear();
            return ask(t, ss);
        }
    }
    int useCard(int n, player *to) {
        card tmp;
        if (cards[n].type == jingongma) {
            tmp         = jingongmaqu;
            jingongmaqu = cards[n];
            cards[n]    = tmp;
            if (cards[n].type == "") {
                cards.erase(cards.begin() + n);
            }
            return 0;
        } else if (cards[n].type == fangyuma) {
            tmp        = fangyumaqu;
            fangyumaqu = cards[n];
            cards[n]   = tmp;
            if(cards[n].type==""){
                cards.erase(cards.begin() + n);
            }
            return 0;
        } else if (cards[n].type == pandin) {
            tmp      = pandinqu;
            pandinqu = cards[n];
            cards[n] = tmp;
            if (cards[n].type == "") {
                cards.erase(cards.begin() + n);
            }
            return 0;
        } else if (cards[n].type == fangju) {
            tmp      = fangjuqu;
            fangjuqu = cards[n];
            cards[n] = tmp;
            if (cards[n].type == "") {
                cards.erase(cards.begin() + n);
            }
            return 0;
        } else if (cards[n].type == zhuangbei) {
            tmp         = zhuangbeiqu;
            zhuangbeiqu = cards[n];
            cards[n]    = tmp;
            if (cards[n].type == "") {
                cards.erase(cards.begin() + n);
            }
            return 0;
        } else if (cards[n].type.use(this, to) == 0) {
            cards.erase(cards.begin() + n);
            return 0;
        }
        return 1;
    }
    void showCards(bool soupai, bool tab) {
        if (!soupai) {
            for (int i = 0; i < cards.size(); i++) {
                cout << "[" << i << "]";
                cards[i].show();
                cout << '\t';
            }
            cout << endl;
        } else {
            cout << '\t';
        }
        if (tab) {
            cout << '\t';
        }
        cout << "判定区:";
        pandinqu.show();
        cout << "\t进攻马:";
        jingongmaqu.show();
        cout << "\t防御马:";
        fangyumaqu.show();
        cout << "\t防具:";
        fangjuqu.show();
        cout << "\t装备:";
        zhuangbeiqu.show();
        cout << "\n";
    }

    bool hasJineng(jineng j) {
        for (int i = 0; i < jiang.jinengs.size(); i++) {
            if (jiang.jinengs[i] == j) {
                return true;
            }
        }
        return false;
    }

    player(string n, int x) :
        name(n), xueliang(x), id(playerCount++), maxxueliang(x) {
    }
    player() :
        id(playerCount++) {
    }
};

//////////////////////////////////////////////////////////////////////////////////////////////////////////////
struct cardStack {
    vector<card> stack;
    card         getCard() { // 获取一张牌
        if (stack.empty()) {
            cout << "错误:牌堆为空" << endl;
            return card();
        }
        card c = stack.back();
        stack.pop_back();
        return c;
    }
    void putCards();
    void xipai() { // 洗牌
        random_shuffle(stack.begin(), stack.end());
    }
};

//////////////////////////////////////////////////////////////////////////////////////////////////////////////

cardStack      deck; // 牌堆
vector<player> players = {
    // 玩家
    {"玩家1", 4},
    {"玩家2", 4},
    {"玩家3", 4},
    {"玩家4", 4},
    {"玩家5", 4},
};
int playerNum = 5; // 玩家数量

//////////////////////////////////////////////////////////////////////////////////////////////////////////////

int sha(player *from, player *to) { // 杀
    if (getDistance(from->id, to->id) - from->jingongmaqu.type.jingong - from->zhuangbeiqu.type.jingong <= 1) {
        if ((*to).ask(getCard("shan"), from->name + "对你使用杀,是否使用闪")) {
            clear();
            cout << (*to).name << "使用闪挡住了你的杀" << endl;
        } else {
            (*to).shanghai(1, "sha");
        }

        return 0;
    } else {
        cout << "你与" << to->name << "距离过远" << endl;
        return 1;
    }
}
int leisha(player *from, player *to) { // 雷杀
    if ((*to).ask(getCard("shan"), from->name + "对你使用雷杀,是否使用闪")) {
        clear();
        cout << (*to).name << "使用闪挡住了你的雷杀" << endl;
    } else {
        (*to).shanghai(1, "leisha");
    }

    return 0;
}
int huosha(player *from, player *to) { // 火杀
    if ((*to).ask(getCard("shan"), from->name + "对你使用火杀,是否使用闪")) {
        clear();
        cout << (*to).name << "使用闪挡住了你的火杀" << endl;
    } else {
        (*to).shanghai(1, "huosha");
    }

    return 0;
}
int shan(player *from, player *to) { // 闪
    cout << "不能直接使用闪!" << endl;
    return 1;
}
int jiu(player *from, player *to) { // 酒
    if ((*to).xueliang < 1) {
        (*to).huifu(1, "jiu");
    }
    return 0;
}
int ZANWEIFU(player *from, player *to) { // 占位符
    if (debug)
        cout << "错误:卡牌行为未定义\n";
    else
        cout << "错误" << endl;
    return 1;
}
int tao(player *from, player *to) { // 桃
    (*to).huifu(1, "tao");
    return 0;
}
int none(player *from, player *to) { // 空牌
    if (debug) {
        cout << "使用了一张空牌" << endl;
    }
    return 1;
}
int wuzhongshengyou(player *from, player *to) { // 无中生有
    for (int i = 0; i < 2; i++) {
        (*to).cards.push_back(deck.getCard());
    }
    return 0;
}
int unuseable(player *from, player *to) { // 不能直接使用的牌
    cout << "不能直接使用该牌!" << endl;
    return 1;
}

// (英文名,中文名,类型,数量,使用函数)
// (英文名,中文名,类型(装备牌),进攻/防御值,数量,使用函数)
cardType cardTypes[10000] = {
    {"sha", "杀", jiben, 30, sha, others},
    {"leisha", "雷杀", jiben, 9, leisha, others},
    {"huosha", "火杀", jiben, 5, huosha, others},
    {"tao", "桃", jiben, 12, any},
    {"shan", "闪", jiben, 24, shan, noone},
    {"jiu", "酒", jiben, 5, jiu, self},

    {"wuxiekeji", "无懈可击", jinnang, 7},
    {"wuzhongshengyou", "无中生有", jinnang, 4, wuzhongshengyou, self},

    {"sandian", "闪电", pandin, 2, ZANWEIFU, others},

    {"zugeliannu", "诸葛连弩", zhuangbei, 1, 2},

    {"tengjia", "藤甲", fangju, 2},

    {"dilu", "的卢", fangyuma, 1, 1},
    {"jueyin", "绝影", fangyuma, 1, 1},
    {"dawan", "大宛", jingongma, 1, 1},
    {"chitu", "赤兔", jingongma, 1, 1},

    {"__end", "__保持此项在最后", other, 0}};

//////////////////////////////////////////////////////////////////////////////////////////////////////////////

void cardStack::putCards() { // 生成牌堆
    cardType temp;
    int      i = 0;
    while (temp != "__end") {
        temp = cardTypes[i];
        for (int j = 0; j < temp.quantity; j++) {
            stack.push_back(card(cardTypes[i]));
        }

        i++;
    }
}

cardType getCard(string name) {
    cardType temp;
    int      i = 0;
    while (temp != "__end") {
        temp = cardTypes[i++];
        if (temp == name) {
            return temp;
        }
    }
    if (debug) {
        cout << "错误:未找到卡牌类型" << name << endl;
    }
    return cardType();
}

// --定义--

//////////////////////////////////////////////////////////////////////////////////////////////////////////////

// --游戏流程--

int cardType::use(player *from, player *to) {
    if (typeName == jinnang) {
        for (int i = to->id; i < playerNum; i++) {
            if (players[i].ask(getCard("wuxiekeji"), from->name + "对" + to->name + "使用" + name + ",是否使用无懈可击")) {
                clear();
                cout << players[i].name << "使用无懈可击挡住了你的" << name << endl;
                return 0;
            }
        }
        for (int i = 0; i < to->id; i++) {
            if (players[i].ask(getCard("wuxiekeji"), from->name + "对" + to->name + "使用" + name + ",是否使用无懈可击")) {
                clear();
                cout << players[i].name << "使用无懈可击挡住了你的" << name << endl;
                return 0;
            }
        }
    }

    return useCard(from, to);
}

int getDistance(int player1Id, int player2Id) { // 计算两个玩家之间的距离,玩家编号从0开始,返回值为正数,玩家首尾相接
    return min(abs(player1Id - player2Id), playerNum - abs(player1Id - player2Id)) + players[player1Id].fangyumaqu.type.fangyu;
}

void show(int playerId) {
    cout << "你(" << players[playerId].name << "):\n";
    cout << "\t血量:" << players[playerId].xueliang << "\t手牌数:" << players[playerId].cards.size() << "\n\t";
    players[playerId].showCards(0, 1);
    cout << "\n其他玩家:\n";

    for (int j = 0; j < playerNum; j++) {
        if (j != playerId) {
            cout << '\t' << players[j].name << "\t血量:" << players[j].xueliang;
            cout << "\t手牌数:" << players[j].cards.size() << "\n\t";
            players[j].showCards(1, 0);
        }
    }
}
void init() {
    srand((int)time(NULL));
}
void showPlayers(int playerId) {
    cout << '\n';
    for (int j = 0; j < playerNum; j++) {
        cout << "\t[" << j << "] " << players[j].name << "\t血量:" << players[j].xueliang;
        cout << "\t手牌数:" << players[j].cards.size();
        cout << "\t与你的距离:" << getDistance(playerId, j) << "\n\t";
        players[j].showCards(1, 0);
    }
}
void start() {
    deck.putCards();
    deck.xipai();
    for (int i = 0; i < 4; i++) {
        for (int j = 0; j < playerNum; j++) {
            players[j].cards.push_back(deck.getCard());
        }
    }
}
void startPandin() {
}

void binsijiesuanqian(int playerId) {
    for (int i = playerId; i < playerNum; i++) {
        clear();
        show(i);
        players[i].ask(getCard("tao"), players[playerId].name + "处于濒死状态,是否对其使用桃");
    }
    for (int i = 0; i < playerId; i++) {
        clear();
        show(i);
        cout << players[playerId].name << "处于濒死状态";
        players[i].ask(getCard("tao"), players[playerId].name + "处于濒死状态,是否对其使用桃");
    }
}
void chupai(int i) {
    int shaCount = 0;
    while (1) {
        show(i);

        cout << "\n"
             << players[i].name << (debug ? "请出牌(-1 跳过,-2 直接获取):" : "请出牌(-1 跳过):");
        int choice;
        cin >> choice;
        clear();
        if (choice == -1) {
            break;
        } else if (choice == -2 && debug) {
            string choice;
            clear();
            cout << "[测试模式] 请输入你想获取的牌名:";
            cin >> choice;
            players[i].cards.push_back(card(getCard(choice)));
        } else if (choice < 0 || choice >= players[i].cards.size()) {
            cout << "错误:卡牌编号超出范围\n"
                 << endl;
        } else {
            if (players[i].cards[choice].type == "sha" || players[i].cards[choice].type == "leisha" || players[i].cards[choice].type == "huosha") {
                if (shaCount >= 1 && !players[i].hasJineng(paoxiao) && players[i].zhuangbeiqu.type != "zugeliannu" && players[i].zhuangbeiqu.type != "liannu") {
                    clear();
                    cout << "你已达到使用杀的上限\n";
                    continue;
                } else if (shaCount >= 4 && !players[i].hasJineng(paoxiao) && players[i].zhuangbeiqu.type != "zugeliannu" && players[i].zhuangbeiqu.type != "liannu") {
                    clear();
                    cout << "你已达到使用杀的上限\n";
                    continue;
                }
            }
            clear();
            if (players[i].cards[choice].type.mubiao == any || players[i].cards[choice].type.mubiao == others) {
                cout << "请选择使用目标";
                showPlayers(i);
                int targetPlayer;
                cin >> targetPlayer;
                if (targetPlayer < 0 || targetPlayer >= playerNum) {
                    cout << "错误:编号超出范围\n"
                         << endl;
                } else {
                    clear();
                    if (players[i].cards[choice].type == "sha") {
                        int a = players[i].useCard(choice, &players[targetPlayer]);
                        if (a == 0) {
                            shaCount++;
                        }
                    } else {
                        players[i].useCard(choice, &players[targetPlayer]);
                    }
                }
            } else if (players[i].cards[choice].type.mubiao == self) {
                clear();
                players[i].useCard(choice, &players[i]);
            } else if (players[i].cards[choice].type.mubiao == all) {
                if (debug) {
                    clear();
                    cout << "未完成";
                }
            } else if (players[i].cards[choice].type.mubiao == noone) {
                clear();
                cout << "不能直接使用" << players[i].cards[choice].type.name << endl;
            }
        }
    }
}

void qipai(int playerId) {
    clear();
    show(playerId);
    int a = players[playerId].cards.size(), b = players[playerId].maxxueliang;
    if (a > b) {
        cout << "你的手牌数大于血量上限,请输入弃牌数量(最大 " << a << " 张,最小 " << a - b << " 张):";
        int choice;
        cin >> choice;
        if (choice < a - b || choice > a) {
            cout << "错误:弃牌数量超出范围\n"
                 << endl;
            qipai(playerId);
            return;
        }
        cout << "请弃牌(输入手牌编号,用空格分隔):";
        for (int i = 0; i < choice; i++) {
            int choice;
            cin >> choice;
            if (choice < 0 || choice >= players[playerId].cards.size()) {
                cout << "错误:卡牌编号超出范围\n"
                     << endl;
            } else {
                players[playerId].cards.erase(players[playerId].cards.begin() + choice);
            }
        }
    }
}

void fapai(int playerId) {
    for (int i = 0; i < 2; i++) {
        players[playerId].cards.push_back(deck.getCard());
    }
}
void newterm() {
    clear();
    startPandin();

    for (int i = 0; i < playerNum; i++) {
        fapai(i);
        clear();
        chupai(i);
        qipai(i);
        clear();
    }
}

// --主函数--

int main() {
    init();
    start();
    while (1) {
        newterm();
    }
}
2025/1/4 11:59
加载中...