提供一个方便大家调试的代码
查看原帖
提供一个方便大家调试的代码
670677
MichaellgHelloWorld楼主2024/3/1 14:20

此代码输出每个猪出每张牌后的情况。

#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;
}
2024/3/1 14:20
加载中...