题目大意:猪国杀,又一道大模拟题
题解:模拟,对于一个没有玩过三国杀的人来说,一堆细节不知道,写的十分吃力
卡点:无数,不想说什么了,这告诉我要多玩游戏
C++ Code:
#include <algorithm> #include <cstdlib> #include <cstdio> #include <iostream> #include <map> #include <queue> #include <vector> //#define DEBUG #define Main_Pig 1 using std::string; namespace Debug { std::map<string, string> Name; inline void init() { Name[""] = "无"; Name["P"] = "桃"; Name["K"] = "杀"; Name["D"] = "闪"; Name["F"] = "决斗"; Name["N"] = "南猪入侵"; Name["W"] = "万箭齐发"; Name["J"] = "无懈可击"; Name["Z"] = "猪哥连弩"; Name["MP"] = "主猪"; Name["ZP"] = "忠猪"; Name["FP"] = "反猪"; } } const string NONE = ""; //基本牌 const string PEACH = "P", KILL = "K", DODGE = "D"; //锦囊牌 const string JD = "F", NZRQ = "N", WJQF = "W", WXKJ = "J"; //装备牌 const string ZGLN = "Z"; //猪 const string MP = "MP", ZP = "ZP", FP = "FP"; //主猪,跳忠,不知,类反猪,跳反 const int TM = 2, TZ = 1, UK = 0, Similar_FZ = -1, TF = -2; int Pigs_Num; struct Card { std::string type; inline Card(string __type = NONE) {type = __type;} friend std::istream & operator >> (std::istream &Fin, Card &card) { string __card; Fin >> __card; card = Card(__card); return Fin; } friend std::ostream & operator << (std::ostream &Fout, Card &card) { string __type = card.type; #ifdef DEBUG Fout << Debug::Name[__type]; #else Fout << __type; #endif return Fout; } inline bool is_kill() {return type == KILL;} inline bool is_peach() {return type == PEACH;} inline bool is_dodge() {return type == DODGE;} inline bool is_jd() {return type == JD;} inline bool is_nzrq() {return type == NZRQ;} inline bool is_wjqf() {return type == WJQF;} inline bool is_wxkj() {return type == WXKJ;} inline bool is_zgln() {return type == ZGLN;} }; struct Card_Pool { std::queue<Card> cards; Card get_card(bool Empty = false) { //抽牌 if (cards.empty()) return NONE; Card __card = cards.front(); if (cards.size() > 1 || Empty) cards.pop(); return __card; } bool empty() { return cards.empty(); } void insert(string __card) {cards.push(Card(__card));} //牌堆加牌 void insert(Card __card) {cards.push(__card);} //牌堆加牌 friend std::ostream & operator << (std::ostream &Fout, Card_Pool &__Pool) { //从上到下输出牌堆的牌 std::queue<Card> tmp; while (!__Pool.empty()) { Card __card = __Pool.get_card(true); tmp.push(__card); #ifdef DEBUG Fout << Debug::Name[__card.type]; #else Fout << __card.type; #endif } while (!tmp.empty()) { __Pool.insert(tmp.front()); tmp.pop(); } return Fout; } } Pool; struct Pig { string type; int Jump, Max_HP, HP, Pos; bool AK_47, dead; std::vector<Card> cards; inline std::vector<Card>::iterator begin() {return cards.begin();} inline std::vector<Card>::iterator end() {return cards.end();} inline Pig(string __type = NONE, int __pos = 0) { Pos = __pos; type = __type; if (__type == MP) Jump = TM; else Jump = UK; Max_HP = HP = 4; AK_47 = dead = false; cards.clear(); } inline void clear() { cards.clear(); AK_47 = false; } void insert_zgln(std::vector<Card>::iterator it) { cards.erase(it); AK_47 = true; } void insert(string __card) { //把一张牌加入手牌 cards.push_back(Card(__card)); } void insert(Card __card) { //把一张牌加入手牌 cards.push_back(__card); } inline bool max_hp() {return Max_HP <= HP;} //是否满血 friend std::ostream & operator << (std::ostream &Fout, Pig pig) { if (pig.dead) { Fout << "DEAD"; return Fout; } for (std::vector<Card>::iterator it = pig.begin(); it != pig.end(); it++) { Fout << *it << " "; } return Fout; } std::vector<Card>::iterator find_peach() { //找桃,并返回位置 for (std::vector<Card>::iterator it = cards.begin(); it != cards.end(); it++) { if (it -> is_peach()) return it; } return cards.end(); } bool use_peach() { //使用桃 if (max_hp()) return false; std::vector<Card>::iterator it = find_peach(); if (it == cards.end()) return false; HP++; cards.erase(it); #ifdef DEBUG std::cout << std::endl; std::cout << type << ":" << Pos << "用了一个桃,现在血量为" << HP << std::endl; std::cout << "现在拥有的牌 :" << *this << std::endl; #endif return true; } std::vector<Card>::iterator find_kill() { //找杀,并返回位置 for (std::vector<Card>::iterator it = cards.begin(); it != cards.end(); it++) { if (it -> is_kill()) return it; } return cards.end(); } bool use_kill() { //使用闪 std::vector<Card>::iterator it = find_kill(); if (it == cards.end()) return false; cards.erase(it); #ifdef DEBUG std::cout << std::endl; std::cout << type << ":" << Pos << "用了一个杀" << std::endl; std::cout << "现在拥有的牌 :" << *this << std::endl; #endif return true; } std::vector<Card>::iterator find_dodge() { //找闪,并返回位置 for (std::vector<Card>::iterator it = cards.begin(); it != cards.end(); it++) { if (it -> is_dodge()) return it; } return cards.end(); } bool use_dodge() { //使用闪 std::vector<Card>::iterator it = find_dodge(); if (it == cards.end()) return false; cards.erase(it); #ifdef DEBUG std::cout << std::endl; std::cout << type << ":" << Pos << "用了一个闪" << std::endl; std::cout << "现在拥有的牌 :" << *this << std::endl; #endif return true; } std::vector<Card>::iterator find_wxkj() { //找无懈可击,并返回位置 for (std::vector<Card>::iterator it = cards.begin(); it != cards.end(); it++) { if (it -> is_wxkj()) return it; } return cards.end(); } bool use_wxkj() { //使用无懈可击 std::vector<Card>::iterator it = find_wxkj(); if (it == cards.end()) return false; cards.erase(it); #ifdef DEBUG std::cout << std::endl; std::cout << type << ":" << Pos << "用了无懈可击" << std::endl; std::cout << "现在拥有的牌 :" << *this << std::endl; #endif return true; } bool hurt(int num = 1) { //收到伤害 HP -= num; #ifdef DEBUG std::cout << std::endl; std::cout << type << ":" << Pos << "收到" << num << "点伤害,现在血量为" << HP << std::endl; #endif if (HP <= 0) { #ifdef DEBUG std::cout << type << ":" << Pos << "进入濒死状态" << std::endl; #endif if (!use_peach()) { this -> clear(); #ifdef DEBUG std::cout << type << ":" << Pos << "死亡" << std::endl; #endif dead = true; return true; } } return false; } } Pigs[20]; int nxt_pig(int now) { //找下一头猪 int nxt = now; while (true) { nxt = nxt % Pigs_Num + 1; if (!Pigs[nxt].dead) return nxt; } return 0; } int nxt_pig(Pig now) { //找下一头猪 return nxt_pig(now.Pos); } inline int game_over() { //判断游戏是否结束 if (Pigs[1].dead) return -1; int FP_Num = 0; for (int i = 1; i <= Pigs_Num; i++) { #ifdef DEBUG std::cout << std::endl; std::cout << "第" << i << "只猪是" << Pigs[i].type << ",是否死亡:" << Pigs[i].dead << std::endl; #endif if (!Pigs[i].dead) FP_Num += (Pigs[i].type == FP); } #ifdef DEBUG std::cout << "现在反猪有" << FP_Num << "只" << std::endl; #endif return !FP_Num; } void end_game() { //输出 int situation = game_over(); if (situation == 1) puts("MP"); else puts("FP"); for (int i = 1; i <= Pigs_Num; i++) std::cout << Pigs[i] << std::endl; exit(0); } namespace Action { void result(int From, int To) { //奖励与惩罚(主猪杀忠猪,杀反猪) #ifdef DEBUG std::cout << std::endl; std::cout << Pigs[From].type << ":" << Pigs[From].Pos << "杀死了" << Pigs[To].type << ":" << Pigs[To].Pos << std::endl; #endif if (game_over()) end_game(); if (Pigs[To].type == FP) { for (int i = 0; i < 3; i++) Pigs[From].insert(Pool.get_card()); #ifdef DEBUG std::cout << std::endl; std::cout << Pigs[From].type << ":" << Pigs[From].Pos << "杀死反猪,获得三张牌" << std::endl; std::cout << "现在的牌:" << Pigs[From] << std::endl; #endif } if (Pigs[To].type == ZP) { if (Pigs[From].type == MP) { Pigs[From].clear(); #ifdef DEBUG std::cout << std::endl; std::cout << "主猪杀死忠猪丢弃所有牌" << std::endl; #endif } } } void enemies(int From, int To, bool aoe = false) { //from对to表敌意,是否是范围伤害 #ifdef DEBUG std::cout << std::endl; std::cout << Pigs[From].type << ":" << Pigs[From].Pos << "对" << Pigs[To].type << ":" << Pigs[To].Pos << "表敌意" << std::endl; if (aoe) std::cout << "是范围伤害" << std::endl; #endif if (aoe) { if (Pigs[From].Jump == UK) { if (Pigs[To].Jump == TM) { Pigs[From].Jump = Similar_FZ; #ifdef DEBUG std::cout << Pigs[From].type << ":" << Pigs[From].Pos << "类反猪" << std::endl; #endif return ; } } return ; } if (Pigs[From].Jump == UK || Pigs[From].Jump == Similar_FZ) { if (Pigs[To].Jump == TF) { Pigs[From].Jump = TZ; #ifdef DEBUG std::cout << Pigs[From].type << ":" << Pigs[From].Pos << "跳忠" << std::endl; #endif return ; } if (Pigs[To].Jump > UK) { Pigs[From].Jump = TF; #ifdef DEBUG std::cout << Pigs[From].type << ":" << Pigs[From].Pos << "跳反" << std::endl; #endif return ; } } } void friends(int From, int To) { //from对to献殷勤 #ifdef DEBUG std::cout << std::endl; std::cout << Pigs[From].type << ":" << Pigs[From].Pos << "对" << Pigs[To].type << ":" << Pigs[To].Pos << "献殷勤" << std::endl; #endif if (Pigs[From].Jump == UK || Pigs[From].Jump == Similar_FZ) { if (Pigs[To].Jump == TF) { Pigs[From].Jump = TF; #ifdef DEBUG std::cout << Pigs[From].type << ":" << Pigs[From].Pos << "跳反" << std::endl; #endif return ; } if (Pigs[To].Jump > UK) { Pigs[From].Jump = TZ; #ifdef DEBUG std::cout << Pigs[From].type << ":" << Pigs[From].Pos << "跳忠" << std::endl; #endif return ; } } } bool hurt(int From, int To, bool aoe = false, bool jd = false) { //from对to造成伤害,是否是范围伤害,是否是决斗 #ifdef DEBUG std::cout << std::endl; std::cout << Pigs[From].type << ":" << Pigs[From].Pos << "对" << Pigs[To].type << ":" << Pigs[To].Pos << "造成伤害" << std::endl; #endif if (jd || aoe || !Pigs[To].use_dodge()) { if (Pigs[To].hurt()) result(From, To); } if (!jd) enemies(From, To, aoe); return false; } void kill(int From, int To, std::vector<Card>::iterator it) { //杀 Pigs[From].cards.erase(it); #ifdef DEBUG std::cout << std::endl; std::cout << Pigs[From].type << ":" << Pigs[From].Pos << "对" << Pigs[To].type << ":" << Pigs[To].Pos << "使用杀" << std::endl; #endif hurt(From, To); } bool query_wxkj(int start, int Now, bool friends) { //询问是否使用无懈可击,开始的猪,目标猪,是否献殷勤 #ifdef DEBUG std::cout << std::endl; std::cout << "询问无懈可击,对象:" << Pigs[Now].type << ":" << Pigs[Now].Pos << std::endl; #endif if (friends) { int i = start; do { if (Pigs[i].type == ZP) { if (Pigs[Now].Jump > UK) { if (Pigs[i].use_wxkj()) { #ifdef DEBUG std::cout << std::endl; std::cout << Pigs[i].type << ":" << Pigs[i].Pos << "对" << Pigs[Now].type << ":" << Pigs[Now].Pos << "使用无懈可击" << std::endl; #endif Action::friends(i, Now); return !query_wxkj(i, i, false); } } } if (Pigs[i].type == MP) { if (Pigs[Now].Jump > UK) { if (Pigs[i].use_wxkj()) { #ifdef DEBUG std::cout << std::endl; std::cout << Pigs[i].type << ":" << Pigs[i].Pos << "对" << Pigs[Now].type << ":" << Pigs[Now].Pos << "使用无懈可击" << std::endl; #endif Action::friends(i, Now); return !query_wxkj(i, i, false); } } } if (Pigs[i].type == FP) { if (Pigs[Now].Jump == TF) { if (Pigs[i].use_wxkj()) { #ifdef DEBUG std::cout << std::endl; std::cout << Pigs[i].type << ":" << Pigs[i].Pos << "对" << Pigs[Now].type << ":" << Pigs[Now].Pos << "使用无懈可击" << std::endl; #endif Action::friends(i, Now); return !query_wxkj(i, i, false); } } } i = nxt_pig(i); } while (i != start); return false; } else { int i = start; do { if (Pigs[i].type == ZP) { if (Pigs[Now].Jump == TF) { if (Pigs[i].use_wxkj()) { #ifdef DEBUG std::cout << std::endl; std::cout << Pigs[i].type << ":" << Pigs[i].Pos << "对" << Pigs[Now].type << ":" << Pigs[Now].Pos << "使用无懈可击" << std::endl; #endif enemies(i, Now); return !query_wxkj(i, i, false); } } } if (Pigs[i].type == MP) { if (Pigs[Now].Jump < UK) { if (Pigs[i].use_wxkj()) { #ifdef DEBUG std::cout << std::endl; std::cout << Pigs[i].type << ":" << Pigs[i].Pos << "对" << Pigs[Now].type << ":" << Pigs[Now].Pos << "使用无懈可击" << std::endl; #endif enemies(i, Now); return !query_wxkj(i, i, false); } } } if (Pigs[i].type == FP) { if (Pigs[Now].Jump > UK) { if (Pigs[i].use_wxkj()) { #ifdef DEBUG std::cout << std::endl; std::cout << Pigs[i].type << ":" << Pigs[i].Pos << "对" << Pigs[Now].type << ":" << Pigs[Now].Pos << "使用无懈可击" << std::endl; #endif enemies(i, Now); return !query_wxkj(i, i, false); } } } i = nxt_pig(i); } while (i != start); return false; } } void jd(int From, int To, std::vector<Card>::iterator it) { //决斗 Pigs[From].cards.erase(it); #ifdef DEBUG std::cout << std::endl; std::cout << Pigs[From].type << ":" << Pigs[From].Pos << "对" << Pigs[To].type << ":" << Pigs[To].Pos << "使用决斗" << std::endl; #endif enemies(From, To, false); if (query_wxkj(From, To, true)) return ; int Now = From, Past = To; while (true) { std::swap(Now, Past); if (Pigs[Now].type == ZP && Pigs[Past].type == MP) break; if (!Pigs[Now].use_kill()) break; } #ifdef DEBUG std::cout << std::endl; std::cout << Pigs[Now].type << ":" << Pigs[Now].Pos << "没有出杀,收到伤害" << std::endl; #endif hurt(Past, Now, false, true); } void nzrq(int From) { //南猪入侵 #ifdef DEBUG std::cout << std::endl; std::cout << Pigs[From].type << ":" << Pigs[From].Pos << "使用南猪入侵" << std::endl; #endif for (int i = nxt_pig(From); i != From; i = nxt_pig(i)) { if (query_wxkj(From, i, true)) continue; if (!Pigs[i].use_kill()) { #ifdef DEBUG std::cout << std::endl; std::cout << Pigs[i].type << ":" << Pigs[i].Pos << "没有出杀,收到伤害" << std::endl; #endif hurt(From, i, true); } } } void wjqf(int From) { //万箭齐发 #ifdef DEBUG std::cout << std::endl; std::cout << Pigs[From].type << ":" << Pigs[From].Pos << "使用万箭齐发" << std::endl; #endif for (int i = nxt_pig(From); i != From; i = nxt_pig(i)) { if (query_wxkj(From, i, true)) continue; if (!Pigs[i].use_dodge()) { #ifdef DEBUG std::cout << std::endl; std::cout << Pigs[i].type << ":" << Pigs[i].Pos << "没有出闪,收到伤害" << std::endl; #endif hurt(From, i, true); } } } } namespace Turn { bool use_kill(int Now, std::vector<Card>::iterator it) { //尝试使用杀 int Nxt = nxt_pig(Now); #ifdef DEBUG std::cout << std::endl; std::cout << Pigs[Now].type << ":" << Pigs[Now].Pos << "尝试使用杀" << std::endl; std::cout << "下一只猪:" << Pigs[Nxt].type << ":" << Pigs[Nxt].Pos << std::endl; #endif if (Now == Nxt) return false; if (Pigs[Now].type == MP) { if (Pigs[Nxt].Jump < UK) { Action::kill(Now, Nxt, it); return true; } else return false; } if (Pigs[Now].type == ZP) { if (Pigs[Nxt].Jump == TF) { Action::kill(Now, Nxt, it); return true; } else return false; } if (Pigs[Now].type == FP) { if (Pigs[Nxt].Jump > UK) { Action::kill(Now, Nxt, it); return true; } else return false; } return 0; } bool use_jd(int Now, std::vector<Card>::iterator it) { //尝试使用决斗 #ifdef DEBUG std::cout << std::endl; std::cout << Pigs[Now].type << ":" << Pigs[Now].Pos << "尝试使用决斗" << std::endl; #endif if (Pigs[Now].type == MP) { for (int i = nxt_pig(Now); i != Now; i = nxt_pig(i)) if (Pigs[i].Jump < UK) { Action::jd(Now, i, it); return true; } else return false; } if (Pigs[Now].type == ZP) { for (int i = nxt_pig(Now); i != Now; i = nxt_pig(i)) { if (Pigs[i].Jump == TF) { Action::jd(Now, i, it); return true; } } return false; } if (Pigs[Now].type == FP) { Action::jd(Now, Main_Pig, it); return true; } return 0; } void turn(int Now) { //进行回合 for (int i = 0; i < 2; i++) Pigs[Now].insert(Pool.get_card()); #ifdef DEBUG std::cout << std::endl; std::cout << "现在轮到" << Pigs[Now].type << ":" << Pigs[Now].Pos << " :" << std::endl; std::cout << "现在血量:" << Pigs[Now].HP << std::endl; std::cout << "现在拥有的牌:" << Pigs[Now] << std::endl; #endif bool Can_Use_Kill = true; bool used = true; while (used) { used = false; for (std::vector<Card>::iterator it = Pigs[Now].begin(); it != Pigs[Now].end(); it++) { if (it -> is_zgln()) { //猪哥连弩 Pigs[Now].insert_zgln(it); used = true; break; } if (it -> is_peach()) { //桃 if (Pigs[Now].use_peach()) { used = true; break; } } if (it -> is_kill()) { //杀 if ((Can_Use_Kill || Pigs[Now].AK_47)) { if (use_kill(Now, it)) { Can_Use_Kill = false; used = true; break; } } } if (it -> is_jd()) { //决斗 if (use_jd(Now, it)) { used = true; break; } } if (it -> is_nzrq()) { //南猪入侵 Pigs[Now].cards.erase(it); Action::nzrq(Now); used = true; break; } if (it -> is_wjqf()) { //万箭齐发 Pigs[Now].cards.erase(it); Action::wjqf(Now); used = true; break; } } } } } namespace Game { using std::cin; using std::cout; int Cards_Num; void start() { std::cin >> Pigs_Num >> Cards_Num; for (int i = 1; i <= Pigs_Num; i++) { string __type; cin >> __type; Pigs[i] = Pig(__type, i); for (int j = 0; j < 4; j++) { cin >> __type; Pigs[i].insert(__type); } } for (int i = 1; i <= Cards_Num; i++) { string __type; cin >> __type; Pool.insert(__type); } for (int i = Main_Pig; !game_over(); i = nxt_pig(i)) if (!Pigs[i].dead) Turn::turn(i); end_game(); } } int main() { #ifdef DEBUG Debug::init(); freopen("LG2482.log", "w", stdout); #endif Game::start(); return 0; }