[洛谷P2482][SDOI2010]猪国杀

2023-05-04,,

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

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

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

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

  

[洛谷P2482][SDOI2010]猪国杀的相关教程结束。

《[洛谷P2482][SDOI2010]猪国杀.doc》

下载本文的Word格式文档,以方便收藏与打印。