[洛谷P2482][SDOI2010]猪国杀

题目大意:猪国杀,有一道大模拟题

题解:模拟,对于一个没有玩过三国杀的人来说,一堆细节不知道,写的十分吃力

卡点:无数,不想说什么了,这告诉我要多玩游戏

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;
} 

  

猜你喜欢

转载自www.cnblogs.com/Memory-of-winter/p/9857191.html