P2482 [SDOI2010] 猪国杀

//----------------------------------------------------------------------------------------------------------

        这道猪国杀写了好久

        之前过的,但是因为期末复习耽误了好久也没整理出来

        毕竟是第一道刷过的大模拟 纪念一下

​
#include<bits/stdc++.h>
using namespace std;

//----------系统-------------
//TODO : 系统设定
class System{
public:
    System(){
        ZPnum=0, FPnum=0;
        gameworking = 1;
        livepeo = 0;
        updata = 0;
    }
    int ZPnum, FPnum;
    bool gameworking;
    int livepeo;
    int updata;
    list<int> People_List; // id
    //找到下一个人 
    int Sys_F_getnextpeople(int peoid);//找到自己表示没有找到合适的目标
    int Sys_K_getnextpeople(int peoid);//找到自己表示没有找到合适的目标
    //是否死亡
    bool Sys_Deadenough(int xid);
    //死亡奖励以及惩罚
    void Sys_result(int pe, int de);
    // sys链表搜索 所有人出杀
    void Sys_Nfind(int xid);
    // sys链表搜索 所有人出闪
    void Sys_Wfind(int xid);
    //  无懈可击
    bool Sys_Jfind(int op ,int xid, int user);
    //  sys找到下一个人 不断出杀(sys特别进行单独运行) 决斗;
    int Sys_F_able(int pid);
    void Sys_F(int pid,int aim);
    //  找到下一个对他进行杀
    int Sys_K_able(int pid);
    void Sys_K(int pid,int aim);
    // 身份标识的更新  
    void Sys_Ident_update(int pid , int xid,int op);//1同2反

    // 类身份更新;
    void Sys_MPident_update(int xid,int op);
    //  阵营判断
    int Sys_check_army(int op1, int op2);
    //游戏结束
    void Sys_gameover();
} sys;

//----------手牌类型-----------
struct NODE{
    char type;
    bool isused;
    NODE(char a){
        type = a;
        isused = 0;
    }
};

//----------牌库 -------------
//TODO : 牌库设定
class CardLib{
private:
    list<NODE> CardLib_ls;
public:
    CardLib(){
        Libsiz = 0;
    }
public:
    int Libsiz;//lib的大小

    void initCardLib(int n){
        char tmpchar;
        for (int i = 1; i <= n;i++){
            scanf(" %c", &tmpchar);
            CardLib_ls.push_back({tmpchar});
        }
        Libsiz = n;
    }

    char get_card(){//发牌反馈
        char CardLib_ls_return_card = CardLib_ls.front().type;
        if(Libsiz >1){
            CardLib_ls.pop_front();
            Libsiz--;
        }
        return CardLib_ls_return_card;
    }
}manager;//初始化牌库


//--------------手牌---------------
//TODO : 手牌设定
class HandCard{
public:
    list<NODE> HandCard_ls;
    int Handsiz;//lib的大小
public:
    HandCard(char a , char b,char c,char d){
        HandCard_ls = {{a}, {b}, {c}, {d}};
        Handsiz = 4;
    }

    void showcard(){
        for (auto it = HandCard_ls.begin(); it != HandCard_ls.end();it++){
            if(!((*it).isused))
                cout << (*it).type<< " ";
        }
        cout << "\n";
    }

    bool FandU_J(){
        for (auto it = HandCard_ls.begin(); it != HandCard_ls.end();it++){
            if((*it).isused)
                continue;
            if((*it).type == 'J'){
                (*it).isused = 1;
                Handsiz--;
                return 1;
            }
        }
        return 0;
    }
    
    bool FandU_K(){
        for (auto it = HandCard_ls.begin(); it != HandCard_ls.end();it++){
            if((*it).isused)
                continue;
            if((*it).type == 'K'){
                (*it).isused = 1;
                Handsiz--;
                return 1;
            }
        }
        return 0;
    }
    
    bool FandU_D(){
        for (auto it = HandCard_ls.begin(); it != HandCard_ls.end();it++){
            if((*it).isused)
                continue;
            if((*it).type == 'D'){
                (*it).isused = 1;
                Handsiz--;
                return 1;
            }
        }
        return 0;
    }
};


//---------------人物--------------------
//TODO :人物设定
class PeopleAttr{
    friend class System;
private:
    string ident;//决定 自己的行为 MP,ZP,FP
    HandCard *hd;
    int peoid;

public:
    PeopleAttr(int id,string identt, char a, char b, char c, char d)
    {
        hd = new HandCard({a},{b},{c},{d});
        ident = identt;
        heart = 4;
        peoid = id;
        islive = 1;
        outident = "-1";
        MPoutident = "-1";
        iszhuge = 0;
    }

    ~PeopleAttr(){
        delete hd;
        hd = nullptr;
    }

public:
    bool islive;
    string outident;//决定别人的反应
    int heart;
    string MPoutident;//主公认为的 身份
    bool iszhuge;

public:
    void get_card_time();
    void using_card_time();
    void delete_card_time();
    //----------------
};


//---------------实现部分---------------
//TODO :   实现部分 
map<int, PeopleAttr *> tpeo;

void PeopleAttr::delete_card_time(){
    for (auto it = hd->HandCard_ls.begin(); it != hd->HandCard_ls.end();){
        if((*it).isused){
            hd->HandCard_ls.erase(it++);
        }
        else{
            it++;
        }
    }
}
void PeopleAttr::get_card_time(){//摸牌阶段
        if(!islive){
            return;
        }
        hd->HandCard_ls.push_back({manager.get_card()});
        hd->HandCard_ls.push_back({manager.get_card()});
        hd->Handsiz += 2;
}

void PeopleAttr::using_card_time(){
        int atk = 1;
        if(iszhuge){
            atk = -1;
        }
        while(1){
            for (auto it = hd->HandCard_ls.begin(); it != hd->HandCard_ls.end();it++){
                if(!sys.gameworking || hd->HandCard_ls.empty()){
                    return;
                }
                if(!islive){
                    return;
                }
                if((*it).isused){
                    continue;
                }
                if(sys.updata){
                    break;
                }
                char opnow = (*it).type;
                switch (opnow)
                {
                case 'P':
                    if(heart<4){
                        heart++;
                        it->isused = 1;
                        hd->Handsiz--;
                    }
                    break;
                case 'K':
                    if(atk == 0){
                        break;
                    }
                    if(int aim = sys.Sys_K_able(peoid)){
                        if(atk == 1){
                            atk = 0;
                        }
                        hd->Handsiz--;
                        it->isused = 1;
                        sys.Sys_K(peoid,aim);
                    }
                    break;
                case 'F':
                    if(int aim =sys.Sys_F_able(peoid)){
                        hd->Handsiz--;
                        it->isused = 1;
                        sys.Sys_F(peoid, aim);
                    }
                    break;
                case 'N':
                    hd->Handsiz--;
                    it->isused = 1;
                    sys.Sys_Nfind(peoid);
                    break;
                case 'W':
                    hd->Handsiz--;
                    it->isused = 1;
                    sys.Sys_Wfind(peoid);
                    break;
                case 'Z':
                    iszhuge = 1;
                    it->isused = 1;
                    hd->Handsiz--;
                    atk = -1;
                    sys.updata = 1;
                    break;
                default:
                    break;
                }
            }
            if(sys.updata){
                sys.updata = 0;
                continue;
            }else{
                break;
            }
        }
    };
    
int System::Sys_check_army(int op1, int op2){//阵营检测 1-->2;
    string id1 = tpeo[op1]->ident;
    string id2 = tpeo[op2]->outident;
    string Mid2 = tpeo[op2]->MPoutident;
    
    if(id1 == "MP"){
        if( Mid2=="-1"){
            return 0;
        }
        else if (Mid2 == "FP"){
            return -1;
        }else{
            return 1;
        }
    }
    if(id2=="-1"){
        return 0;
    }
    if(id1 == "ZP" && id2 == "FP"){
        return -1;
    }
    if(id1 == "FP" && (id2 == "ZP" ||id2 == "MP") ){
        return -1;
    }
    return 1;
}

void System::Sys_MPident_update(int xid,int op){
    if(tpeo[xid]->outident == "MP"){
        return;
    }
    sys.updata = 1;
    if(op == 1){
        tpeo[xid]->MPoutident = "ZP";
    }else{
        tpeo[xid]->MPoutident = "FP";
    }
}

void System::Sys_Ident_update(int xid ,int pid ,  int op){ //x->p 进行了 op的行为进而引发的更新 身份
    if(tpeo[pid]->outident == "-1"){
        return;
    }
    if(tpeo[xid]->outident == "MP"){
        return;
    }
    sys.updata = 1;
    if(op == 1){
        if(tpeo[pid]->outident == "ZP"|| tpeo[pid]->outident == "MP"){
            tpeo[xid]->outident = "ZP";
            Sys_MPident_update(xid, 1);
        }else{
            tpeo[xid]->outident = "FP";
            Sys_MPident_update(xid, 2);
        }
    }else{
        if(tpeo[pid]->outident == "FP"){
            tpeo[xid]->outident = "ZP";
            Sys_MPident_update(xid, 1);
        }else{
            tpeo[xid]->outident = "FP";
            Sys_MPident_update(xid, 2);
        }
    }
}

int System::Sys_K_getnextpeople(int xnow ){
    for (auto it = People_List.begin(); it != People_List.end();it++){
        if((*it) <= xnow){
            continue;
        }
        if(!tpeo[(*it)]->islive){
            continue;
        }
        if(sys.Sys_check_army(xnow , *it) == -1){
            return *it;
        }else{
            return -1;
        }
    }
    for (auto it = People_List.begin(); it != People_List.end();it++){
        if((*it) >= xnow){
            continue;
        }
        if(!tpeo[(*it)]->islive){
            continue;
        }
        if(sys.Sys_check_army(xnow , *it) == -1){
            return *it;
        }else{
            return -1;
        }
    }
    return -1;
}

int System::Sys_F_getnextpeople(int xnow ){
    for (auto it = People_List.begin(); it != People_List.end();it++){
        if((*it) <= xnow){
            continue;
        }
        if(!tpeo[(*it)]->islive){
            continue;
        }
        if(sys.Sys_check_army(xnow , *it) != -1){
            continue;
        }else{
            return *it;
        }
    }
    for (auto it = People_List.begin(); it != People_List.end();it++){
        if(!tpeo[(*it)]->islive){
            continue;
        }
        if(sys.Sys_check_army(xnow , *it) != -1){
            continue;
        }else{
            return *it;
        }
    }
    return -1;
}

bool System::Sys_Deadenough(int xid){
    bool islive = 0;
    for (auto it = tpeo[xid]->hd->HandCard_ls.begin(); it != tpeo[xid]->hd->HandCard_ls.end();it++){
        if(it->isused)
            continue;
        if((*it).type == 'P'){
            tpeo[xid]->heart++;
            tpeo[xid]->hd->Handsiz--;
            it->isused = 1;
            islive = 1;
            break;
        }
    }
    sys.livepeo--;
    return islive;
}

void System::Sys_result(int pe, int de){
    string deide = tpeo[de]->ident;
    string peide = tpeo[pe]->ident;
    tpeo[de]->islive = 0;
    if(deide == "FP"){
        if(--sys.FPnum == 0){
            sys.Sys_gameover();
        }
        tpeo[pe]->hd->HandCard_ls.push_back({manager.get_card()});
        tpeo[pe]->hd->HandCard_ls.push_back({manager.get_card()});
        tpeo[pe]->hd->HandCard_ls.push_back({manager.get_card()});
        tpeo[pe]->hd->Handsiz += 3;
    }
    else if((deide == "ZP") && peide == "MP"){
        tpeo[pe]->hd->HandCard_ls.clear();
        tpeo[pe]->iszhuge = 0;
    }
    else if(deide == "MP"){
        sys.Sys_gameover();
    }
}

void System::Sys_gameover(){
    sys.gameworking = 0;
    if(sys.FPnum == 0){
        cout << "MP" << endl;
    }else{
        cout << "FP" << endl;
    }
    for (auto it = sys.People_List.begin(); it != sys.People_List.end();it++){
        if(!tpeo[*it]->islive){
            cout << "DEAD" << endl;
        }else{
            tpeo[*it]->hd->showcard();
        }
    }
}

bool System::Sys_Jfind(int op ,int pos ,int user){
    bool isused = 0;
    int helper = 0;
    if(op==1)
    {
        for (auto it = sys.People_List.begin(); it != sys.People_List.end();it++){
            if((*it)<user){
                continue;
            }
            if(tpeo[*it]->islive == 0){
                continue;
            }
            if(sys.Sys_check_army(*it , pos) == 1){
                if(tpeo[*it]->hd->FandU_J()){
                    sys.Sys_Ident_update(*it ,pos , 1);
                    helper = *it;
                    isused = 1;
                    break;
                }
            }
        }
        if(!isused){
            for (auto it = sys.People_List.begin(); it != sys.People_List.end();it++){
                if(*it>=user){
                    break;
                }
                if(tpeo[*it]->islive == 0){
                    continue;
                }
                if(sys.Sys_check_army( *it,pos ) == 1){
                    if(tpeo[*it]->hd->FandU_J()){
                        sys.Sys_Ident_update(*it , pos , 1);
                        helper = *it;
                        isused = 1;
                        break;
                    }
                }
            }
        }
    }else if(op==2){
        for (auto it = sys.People_List.begin(); it != sys.People_List.end();it++){
            if((*it)<user){
                continue;
            }
            if(tpeo[*it]->islive == 0){
                continue;
            }
            if(sys.Sys_check_army(  *it,pos) == -1){
                if(tpeo[*it]->hd->FandU_J()){
                    sys.Sys_Ident_update(*it,pos , 2);
                    isused = 1;
                    helper = *it;
                    break;
                }
            }
        }
        if(!isused){
            for (auto it = sys.People_List.begin(); it != sys.People_List.end();it++){
                if(*it>=user){
                    break;
                }
                if(tpeo[*it]->islive == 0){
                    continue;
                }
                if(sys.Sys_check_army(*it , pos ) == -1){
                    if(tpeo[*it]->hd->FandU_J()){
                        sys.Sys_Ident_update(*it , pos , 2);
                        isused = 1;
                        helper = *it;
                        break;
                    }
                }
            }
        }
    }
    if(isused == 0){
        return 0;
    }
    else {
        if(!Sys_Jfind(2 , helper, helper)){//易错
            return isused;
        }
        else{
            return 1 - isused;
        }
    }
}

void System::Sys_Wfind(int xid){
    for (auto it = sys.People_List.begin(); it != sys.People_List.end();it++){
        if(!sys.gameworking){
            return;
        }
        if((*it)<=xid){
            continue;
        }
        if(tpeo[*it]->islive == 0){
            continue;
        }
        if(!sys.Sys_Jfind(1,*it,xid)){
            if(! tpeo[(*it)]->hd->FandU_D()){
                if(--tpeo[(*it)]->heart == 0){
                    if(!sys.Sys_Deadenough(*it)){
                        sys.Sys_result(xid, *it);
                    }
                }
                if(tpeo[*it]->ident == "MP"){
                    if(tpeo[xid]->MPoutident == "-1"){
                        sys.Sys_MPident_update(xid, 2);
                    }
                }
            }
        }
    }
    for (auto it = sys.People_List.begin(); it != sys.People_List.end();it++){
        if(!sys.gameworking){
            return;
        }
        if(*it>=xid){
            break;
        }
        if(tpeo[*it]->islive == 0){
            continue;
        }
        if(!sys.Sys_Jfind(1,*it,xid)){
            if(! tpeo[(*it)]->hd->FandU_D()){
                if(--tpeo[(*it)]->heart == 0){
                    if(!sys.Sys_Deadenough(*it)){
                        sys.Sys_result(xid, *it);
                    }
                }
                if(tpeo[*it]->ident == "MP"){
                    if(tpeo[xid]->MPoutident == "-1"){
                        sys.Sys_MPident_update(xid, 2);
                    }
                }
            }
        }
    }
}

void System::Sys_Nfind(int xid){
    for (auto it = sys.People_List.begin(); it != sys.People_List.end();it++){
        if(!sys.gameworking){
            return;
        }
        if((*it)<=xid){
            continue;
        }
        if(tpeo[*it]->islive == 0){
            continue;
        }
        if(!sys.Sys_Jfind(1,*it,xid)){
            if(! tpeo[(*it)]->hd->FandU_K()){
                if(--tpeo[(*it)]->heart == 0){
                    if(!sys.Sys_Deadenough(*it)){
                        sys.Sys_result(xid, *it);
                    }
                    
                }
                if(tpeo[*it]->ident == "MP"){
                    if(tpeo[xid]->MPoutident == "-1"){
                        sys.Sys_MPident_update(xid, 2);
                    }
                }
            }
        }
    }
    for (auto it = sys.People_List.begin(); it != sys.People_List.end();it++){
        if(!sys.gameworking){
            return;
        }
        if(*it>=xid){
            break;
        }
        if(tpeo[*it]->islive == 0){
            continue;
        }
        if(!sys.Sys_Jfind(1,*it,xid)){
            if(! tpeo[(*it)]->hd->FandU_K()){
                if(--tpeo[(*it)]->heart == 0){
                    if(!sys.Sys_Deadenough(*it)){
                        sys.Sys_result(xid, *it);
                    }
                }
                if(tpeo[*it]->ident == "MP"){
                    if(tpeo[xid]->MPoutident == "-1"){
                        sys.Sys_MPident_update(xid, 2);
                    }
                }
            }
        }
    }
}

int System::Sys_F_able(int pid){
    if(tpeo[pid]->ident == "FP"){
        return 1;
    }
    int aim = sys.Sys_F_getnextpeople(pid);
    if(aim == -1){
        return 0;
    }
    return aim;
}

void System::Sys_F(int pid,int aim){
    sys.Sys_Ident_update(pid, aim, 2);
    if(sys.Sys_Jfind(1,aim,pid)){
        return;
    }
    while(1){
        if((tpeo[pid]->ident == "MP" && tpeo[aim]->ident=="ZP") || !tpeo[aim]->hd->FandU_K()){
            if(--(tpeo[aim]->heart)==0){
                if(!sys.Sys_Deadenough(aim)){
                    sys.Sys_result(pid, aim);
                }
            }
            return;
        }
        if(!tpeo[pid]->hd->FandU_K()){
            if(--(tpeo[pid]->heart)==0){
                if(!sys.Sys_Deadenough(pid)){
                    sys.Sys_result(aim, pid);
                }
            }
            return;
        }
    }
}

int System::Sys_K_able(int pid){
    if(tpeo[pid]->ident == "FP"){
        if(sys.livepeo ==3 || sys.livepeo == 2)
            return 1;
    }
    int aim = sys.Sys_K_getnextpeople(pid);
    if(aim == -1){
        return 0;
    }
    return aim;
}

void System::Sys_K(int pid,int aim){
    sys.Sys_Ident_update(pid, aim, 2);
    if(!tpeo[aim]->hd->FandU_D()){
        if(--(tpeo[aim]->heart) == 0){
            if(!sys.Sys_Deadenough(aim)){
                sys.Sys_result(pid, aim);
            }
        }
    }
}

//----------运行-------------
/*
3 10
MP D D F F
ZP N N N D
FP J J J J
F F D D J J F F K D
*/
//对应表 



int main(){//TODO :运行设置
    //-----------------系统配置 
    int peonum, libnum;
    scanf("%d%d", &peonum, &libnum);

    for (int i = 1; i <= peonum;i++){
        string nametmp;
        char s[5];
        cin >> nametmp;
        if(nametmp == "ZP")
            sys.ZPnum++;
        if(nametmp == "FP")
            sys.FPnum++;
        for (int j = 1; j <= 4;j++){
            cin >> s[j];
        }
        tpeo[i] = new PeopleAttr(i,nametmp, s[1], s[2], s[3], s[4]);
        sys.People_List.push_back(i);
    }
    tpeo[1]->outident = "MP";
    tpeo[1]->MPoutident = "MP";
    manager.initCardLib(libnum);
    sys.livepeo = peonum;
    //-----------------系统配置 
    //    cout << "ok" << endl;
    while(sys.gameworking){
        for (auto it = sys.People_List.begin(); it != sys.People_List.end();it++){
            if(!sys.gameworking){
                break;
            }
            if(tpeo[*it]->islive == 0){
                continue;
            }
            tpeo[*it]->get_card_time();
            tpeo[*it]->using_card_time();
            tpeo[*it]->delete_card_time();
        }
    }
    // cout << ok<<endl;
    return 0;
}

​

像这样的大模拟 我觉得面向对象 debug起来更方便一点吧 就用的c++写的 哪里有问题可以私信到我 留下点走过的弯路给大家避避坑

//pig kill debug
// 相互调用问题 : 类外定义 
 

问题1:决斗无视距离  
问题2:无懈可击可对决斗使用 1
问题3:无懈可击击无懈可击 1
问题4:决斗没有改变外在身份 1
问题5:手牌数量的动态更新 1
问题6:万箭齐发 和 蛮族入侵 单张 1
问题7:决斗优先 主公 1
问题8:三个人的情况下 杀 优先主公 1



问题9:决斗时自己死亡的情况  1
问题10:攻击失败时 向下位 1 


问题11:**erase 调用函数之后迭代器失效的问题 1
问题12:决斗的死亡判断 移到外侧  1


问题13:关于无懈可击的修正 1
问题14:无懈可击引发的迭代器段错误 //--!!大更新 添加新阶段 重构 手牌检查 对于isused的手牌进行删除  1


问题15:无懈可击的轮次问题 1
问题16:两人的时候 直接返回对方为杀的目标 1
问题17:卡牌 updata 1
 

         凡是新的事情在起头总是这样一来的,起初热心的人很多,而不久就冷淡下去,撒手不做了,因为他已经明白,不经过一番苦工是做不成的,而只有想做的人,才忍得过这番痛苦。                                                                                        

                                                                                                        ——陀思妥耶夫斯基

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值