//----------------------------------------------------------------------------------------------------------
这道猪国杀写了好久
之前过的,但是因为期末复习耽误了好久也没整理出来
毕竟是第一道刷过的大模拟 纪念一下
#includeusing 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 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 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 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 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) 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) 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); } } } } //----------运行------------- //对应表 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< 像这样的大模拟 我觉得面向对象 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
凡是新的事情在起头总是这样一来的,起初热心的人很多,而不久就冷淡下去,撒手不做了,因为他已经明白,不经过一番苦工是做不成的,而只有想做的人,才忍得过这番痛苦。
——陀思妥耶夫斯基


![P2482 [SDOI2010] 猪国杀 P2482 [SDOI2010] 猪国杀](http://www.mshxw.com/aiimages/31/969056.png)
