此代码输出每个猪出每张牌后的情况。
#include<iostream>
#include<algorithm>
#include<vector>
#include<map>
#include<exception>
using std::cin; using std::cout;
const int maxPig = 13, startCardNum = 4, deskCardMax = 2007, maxHP = 4, drawNum = 2;
int n, m, FPnum, curcard = 1;
enum class Card: char {
null='\0', tao='P', sha='K', shan='D', zhugeliannu='Z', juedou = 'F', nanman = 'N', wanjian = 'W', wuxie = 'J'
};
enum class PigKind {
notknow, zhu, zhong, fan, leifan
};
Card deskCards[deskCardMax];
struct GameOver : public std::exception {};
void outputCards(std::ostream&);
class Pig {
public:
Pig(Card *initialCards, PigKind kind) {
healthPoint = maxHP;
dead = false; isputsha = false;
equipment = Card::null;
for (int i = 1; i <= startCardNum; i++) {
cards.push_back(initialCards[i]);
isout.push_back(false);
}
roleFromMP = PigKind::notknow;
realRole = kind;
}
void setpre(Pig *pre) {
this->pre = pre;
}
void setnxt(Pig *nxt) {
this->nxt = nxt;
}
void inputCard(int num) {
for (int i = 1; i <= num; i++) {
cards.push_back(deskCards[curcard]);
isout.push_back(false);
curcard++;
if (curcard > m)
curcard = m;
}
}
void outputCard(std::ostream &os) {
if (dead)
os << "DEAD\n";
else {
for (int i = 0; i < cards.size(); i++)
if (!isout[i])
os << static_cast<char>(cards[i]) << " ";
os << "\n";
}
}
bool isdead() {
return dead;
}
void clear() {
cards.clear(), isout.clear();
equipment = Card::null;
}
void playCard() {
clearUsedCard();
isputsha = false;
for (int i = 0; i < cards.size(); i++)
if (!isout[i] && canplay(cards[i])) {
isout[i] = true;
playOneCard(cards[i]);
if (dead)
return;
i = -1;
}
}
// returns the position of the card. returns card.size() if didn't find the card.
int findCard(Card card) {
for (int i = 0; i < cards.size(); i++)
if (!isout[i] && cards[i] == card)
return i;
return cards.size();
}
Pig *getnxt() {
return nxt;
}
int getHP() {
return healthPoint;
}
virtual ~Pig() {}
PigKind roleFromMP, realRole;
protected:
int healthPoint;
std::vector<Card> cards;
std::vector<int> isout;
bool dead, isputsha;
Card equipment;
Pig *pre, *nxt;
std::map<Card, Card> reactCard {
{Card::sha, Card::shan},
{Card::juedou, Card::sha},
{Card::nanman, Card::sha},
{Card::wanjian, Card::shan}
};
void clearUsedCard() {
std::vector<Card> tmpCards; std::vector<int> tmpIsOut;
for (int i = 0; i < cards.size(); i++)
if (!isout[i]) {
tmpCards.push_back(cards[i]);
tmpIsOut.push_back(false);
}
std::swap(tmpCards, cards); std::swap(tmpIsOut, isout);
}
bool canSha() {
return isenemy(nxt) && (!isputsha || equipment == Card::zhugeliannu);
}
bool canTao() {
return healthPoint != maxHP;
}
bool canJuedou() {
Pig *pig = nxt;
while (pig != this) {
if (isenemy(pig))
return true;
pig = pig->nxt;
}
return false;
}
bool canplay(Card card) {
bool play = false;
switch (card) {
case Card::tao: play = canTao(); break;
case Card::sha: play = canSha(); break;
case Card::juedou: play = canJuedou(); break;
case Card::zhugeliannu: case Card::nanman: case Card::wanjian: play = true; break;
default:;
}
return play;
}
void Tao() {
healthPoint++;
}
void Zhuge() {
equipment = Card::zhugeliannu;
}
void Sha() {
isputsha = true;
nxt->setenemy(this);
nxt->react(Card::sha, this);
}
void Juedou() {
Pig *pig = nxt;
if (realRole == PigKind::fan) {
while (pig->realRole != PigKind::zhu)
pig = pig->nxt;
pig->setenemy(this);
if (Wuxie(pig, true))
pig->react(Card::juedou, this);
}
else {
while (pig != this) {
if (isenemy(pig)) {
pig->setenemy(this);
if (Wuxie(pig, true))
pig->react(Card::juedou, this);
return;
}
pig = pig->nxt;
}
}
}
void Nanman() {
Pig *pig = nxt;
while (pig != this) {
if (Wuxie(pig, true))
pig->react(Card::nanman, this);
pig = pig->nxt;
}
}
void Wanjian() {
Pig *pig = nxt;
while (pig != this) {
if (Wuxie(pig, true))
pig->react(Card::wanjian, this);
pig = pig->nxt;
}
}
bool askwuxie(Pig *aim, bool effect) {
if ((!effect && isenemy(aim)) || (effect && isfriend(aim))) {
int cardpos = findCard(Card::wuxie);
if (cardpos == cards.size())
return false;
roleFromMP = realRole;
isout[cardpos] = true;
return true;
}
return false;
}
bool Wuxie(Pig *aim, bool effect) {
Pig *pig = this;
do {
if (pig->askwuxie(aim, effect)) {
effect ^= 1;
effect = pig->Wuxie(aim, effect);
}
pig = pig->nxt;
} while (pig != this);
return effect;
}
void playOneCard(Card card) {
switch (card) {
case Card::tao: Tao(); break;
case Card::zhugeliannu: Zhuge(); break;
case Card::sha: Sha(); break;
case Card::juedou: Juedou(); break;
case Card::nanman: Nanman(); break;
case Card::wanjian: Wanjian(); break;
default:;
}
outputCards(std::cerr);
}
void getDamage(Pig *hurtPig, Card card) {
healthPoint--;
if (card == Card::nanman || card == Card::wanjian)
setleifan(hurtPig);
if (healthPoint <= 0)
eatEnoughTao();
if (healthPoint <= 0) {
dead = true;
nxt->pre = pre, pre->nxt = nxt;
bedead(hurtPig);
clear();
}
}
void react(Card card, Pig *source) {
if (realRole == PigKind::zhong && source->realRole == PigKind::zhu && card == Card::juedou) {
getDamage(source, card);
return;
}
int cardpos = findCard(reactCard[card]);
if (cardpos == cards.size())
getDamage(source, card);
else {
isout[cardpos] = true;
if (card == Card::juedou)
source->react(card, this);
}
}
void eatEnoughTao() {
while (healthPoint <= 0) {
int pos = findCard(Card::tao);
if (pos != cards.size()) {
isout[pos] = true;
healthPoint++;
}
else
return;
}
}
virtual void bedead(Pig *hurtPig) {}
virtual bool isenemy(Pig *pig) = 0;
virtual void setenemy(Pig *pig) = 0;
virtual void setleifan(Pig *pig) {}
virtual bool isfriend(Pig *pig) = 0;
};
Pig *pigs[maxPig];
class MPig: public Pig {
public:
MPig(Card *cards, PigKind kind): Pig(cards, kind) {
roleFromMP = PigKind::zhu;
}
private:
void bedead(Pig *hurtPig) override {
throw GameOver{};
}
bool isenemy(Pig *pig) override {
return pig->roleFromMP == PigKind::fan || pig->roleFromMP == PigKind::leifan;
}
void setenemy(Pig *pig) override {
if (pig->roleFromMP == PigKind::notknow || pig->roleFromMP == PigKind::leifan)
pig->roleFromMP = PigKind::fan;
}
void setleifan(Pig *pig) override {
if (pig->roleFromMP == PigKind::notknow || pig->roleFromMP == PigKind::leifan)
pig->roleFromMP = PigKind::leifan;
}
bool isfriend(Pig *pig) override {
return pig->roleFromMP == PigKind::zhu || pig->roleFromMP == PigKind::zhong;
}
};
class ZPig: public Pig {
public:
using Pig::Pig;
private:
void bedead(Pig *hurtPig) override {
if (hurtPig->roleFromMP == PigKind::zhu)
hurtPig->clear();
}
bool isenemy(Pig *pig) override {
return pig->roleFromMP == PigKind::fan;
}
void setenemy(Pig *pig) override {
if (pig->roleFromMP == PigKind::notknow || pig->roleFromMP == PigKind::leifan)
pig->roleFromMP = PigKind::fan;
}
bool isfriend(Pig *pig) override {
return pig->roleFromMP == PigKind::zhu || pig->roleFromMP == PigKind::zhong;
}
};
class FPig: public Pig {
public:
using Pig::Pig;
private:
void bedead(Pig *hurtPig) override {
FPnum--;
if (FPnum != 0)
hurtPig->inputCard(3);
else
throw GameOver{};
}
bool isenemy(Pig *pig) override {
return pig->roleFromMP == PigKind::zhong || pig->roleFromMP == PigKind::zhu;
}
void setenemy(Pig *pig) override {
if (pig->roleFromMP == PigKind::notknow || pig->roleFromMP == PigKind::leifan)
pig->roleFromMP = PigKind::zhong;
}
bool isfriend(Pig *pig) override {
return pig->roleFromMP == PigKind::fan;
}
};
void createPig(int pos, char role, Card *cards) {
switch (role) {
case 'M': pigs[pos] = new MPig(cards, PigKind::zhu); break;
case 'Z': pigs[pos] = new ZPig(cards, PigKind::zhong); break;
case 'F': pigs[pos] = new FPig(cards, PigKind::fan); break;
}
if (role == 'F')
FPnum++;
}
void inputPig() {
for (int i = 1; i <= n; i++) {
char role[3];
Card cards[startCardNum+1];
cin >> role;
for (int j = 1; j <= startCardNum; j++) {
char ch;
cin >> ch;
cards[j] = static_cast<Card>(ch);
}
createPig(i, role[0], cards);
}
for (int i = 1; i <= n; i++)
if (i != 1)
pigs[i]->setpre(pigs[i-1]);
else
pigs[i]->setpre(pigs[n]);
for (int i = 1; i <= n; i++)
if (i != n)
pigs[i]->setnxt(pigs[i+1]);
else
pigs[i]->setnxt(pigs[1]);
}
void inputDeskCard() {
for (int i = 1; i <= m; i++) {
char card;
cin >> card;
deskCards[i] = static_cast<Card>(card);
}
}
void init() {
inputPig();
inputDeskCard();
}
void outputCards(std::ostream &os) {
for (int i = 1; i <= n; i++) {
std::cerr << pigs[i]->getHP() << " ";
pigs[i]->outputCard(os);
}
std::cerr << "\n";
}
void play() {
Pig *cur = pigs[1];
while (true) {
std::cerr << "new Pig\n";
cur->inputCard(drawNum);
outputCards(std::cerr);
cur->playCard();
cur = cur->getnxt();
}
}
void output() {
if (pigs[1]->isdead())
cout << "FP\n";
else
cout << "MP\n";
outputCards(cout);
}
void end() {
for (int i = 1; i <= n; i++)
delete pigs[i];
}
int main() {
cin >> n >> m;
init();
try {
play();
} catch (GameOver &e) {}
output();
end();
return 0;
}