#include <iostream>
#include <vector>
#include <string>
#include <cstdlib>
#include <ctime>
#include <algorithm>
#include <windows.h>
using namespace std;
enum CardType {
ATTACK,
DEFENSE,
HEAL,
STUN,
DRAW,
TAUNT,
POISON,
BUFF
};
struct Card {
string name;
CardType type;
int value;
string desc;
string job;
Card(string n, CardType t, int v, string d, string j = "all")
: name(n), type(t), value(v), desc(d), job(j) {}
};
class Player {
private:
string name;
string job;
int hp;
int maxHp;
int shield;
int attackBuff;
bool isStunned;
bool isPoisoned;
int poisonTurn;
vector<Card> deck;
vector<Card> hand;
public:
Player(string n, string j, int mhp)
: name(n), job(j), maxHp(mhp), hp(mhp), shield(0),
attackBuff(0), isStunned(false), isPoisoned(false), poisonTurn(0) {}
int getHp() const { return hp; }
int getShield() const { return shield; }
bool getStun() const { return isStunned; }
bool getPoison() const { return isPoisoned; }
string getName() const { return name; }
string getJob() const { return job; }
void setJob(string j) { job = j; }
void setHp(int h) { hp = max(0, h); }
void setShield(int s) { shield = max(0, s); }
void setStun(bool s) { isStunned = s; }
void setPoison(bool p, int turn = 2) {
isPoisoned = p;
poisonTurn = turn;
}
void addBuff(int a) { attackBuff += a; }
void takeDamage(int dmg) {
dmg += attackBuff;
if (shield >= dmg) {
shield -= dmg;
} else {
dmg -= shield;
shield = 0;
hp = max(0, hp - dmg);
}
}
void poisonDamage() {
if (isPoisoned && poisonTurn > 0) {
hp = max(0, hp - 2);
cout << getName() << " 中毒损失2点HP!\n";
poisonTurn--;
if (poisonTurn <= 0) isPoisoned = false;
}
}
void initAllCards(vector<Card>& all) {
all.clear();
all.emplace_back("挥砍", ATTACK, 2, "造成2点伤害", "all");
all.emplace_back("护盾", DEFENSE, 3, "获得3点护盾", "all");
all.emplace_back("疗伤", HEAL, 3, "恢复3点生命", "all");
all.emplace_back("眩晕击", STUN, 1, "眩晕敌人1回合", "all");
all.emplace_back("抽卡", DRAW, 1, "抽1张牌", "all");
all.emplace_back("猛击", ATTACK, 6, "造成6点伤害", "warrior");
all.emplace_back("嘲讽", TAUNT, 0, "强制敌人攻击", "warrior");
all.emplace_back("战争怒吼", BUFF, 2, "本回合攻击+2", "warrior");
all.emplace_back("火球", ATTACK, 8, "造成8点伤害", "mage");
all.emplace_back("冰冻", STUN, 1, "眩晕敌人", "mage");
all.emplace_back("奥术抽卡", DRAW, 2, "抽2张牌", "mage");
all.emplace_back("连射", ATTACK, 4, "造成4点伤害", "ranger");
all.emplace_back("搜索", DRAW, 3, "抽3张牌", "ranger");
all.emplace_back("毒箭", POISON, 2, "使敌人中毒2回合", "ranger");
all.emplace_back("神圣打击", ATTACK, 5, "造成5点伤害", "priest");
all.emplace_back("治愈", HEAL, 6, "恢复6点生命", "priest");
all.emplace_back("群体治疗", HEAL, 4, "恢复4点生命", "priest");
all.emplace_back("背刺", ATTACK, 7, "造成7点伤害", "assassin");
all.emplace_back("剧毒", POISON, 3, "敌人中毒3回合", "assassin");
all.emplace_back("突袭", DRAW, 2, "抽2张牌", "assassin");
all.emplace_back("爪击", ATTACK, 5, "造成5点伤害", "druid");
all.emplace_back("自然护盾", DEFENSE, 5, "获得5点护盾", "druid");
all.emplace_back("自然愈合", HEAL, 5, "恢复5点生命", "druid");
}
void buildDeck() {
vector<Card> all;
initAllCards(all);
deck.clear();
cout << "\n【卡组构筑:选择12张卡牌】\n";
int i = 1;
for (auto& c : all) {
if (c.job == job || c.job == "all") {
cout << i << ". " << c.name << " | " << c.desc << "\n";
i++;
}
}
for (int cnt = 0; cnt < 12; ) {
int c;
cout << "选择卡牌" << cnt+1 << ": ";
cin >> c;
int real = 0;
bool ok = false;
for (auto& card : all) {
if (card.job == job || card.job == "all") {
real++;
if (real == c) {
deck.push_back(card);
cnt++;
ok = true;
break;
}
}
}
if (!ok) cout << "无效选择!\n";
}
random_shuffle(deck.begin(), deck.end());
cout << "卡组构筑完成!\n";
}
void draw(int n = 1) {
for (int i = 0; i < n; ++i) {
if (deck.empty()) return;
hand.push_back(deck.front());
deck.erase(deck.begin());
}
}
void showHand() {
cout << "\n【手牌】\n";
for (int i = 0; i < hand.size(); i++)
cout << i+1 << ". " << hand[i].name << " | " << hand[i].desc << "\n";
}
Card play(int idx) {
if (idx < 0 || idx >= hand.size())
return Card("空", ATTACK, 0, "无");
Card c = hand[idx];
hand.erase(hand.begin() + idx);
deck.push_back(c);
return c;
}
int getHandCount() { return hand.size(); }
int aiChoose(Player& enemy) {
if (hand.empty()) return -1;
if (hp < 12) {
for (int i = 0; i < hand.size(); i++)
if (hand[i].type == HEAL) return i;
}
if (isPoisoned) {
for (int i = 0; i < hand.size(); i++)
if (hand[i].type == HEAL || hand[i].type == DEFENSE) return i;
}
if (enemy.getStun()) {
for (int i = 0; i < hand.size(); i++)
if (hand[i].type == ATTACK) return i;
}
int maxAtk = -1, id = 0;
for (int i = 0; i < hand.size(); i++) {
if (hand[i].type == ATTACK && hand[i].value > maxAtk) {
maxAtk = hand[i].value;
id = i;
}
}
return id;
}
};
class CardGame {
private:
Player player;
Player ai;
bool gameOver;
int level;
void anim(int ms = 500) { Sleep(ms); }
void sound() { Beep(550,120); Sleep(80); Beep(700,120); }
void soundWin() { Beep(800,100); Beep(900,100); Beep(1000,200); }
void soundLose() { Beep(300,200); Beep(200,200); Beep(100,300); }
void printStatus() {
cout << "\n====================================\n";
cout << player.getName() << " HP:" << player.getHp()
<< " 护盾:" << player.getShield()
<< (player.getStun()?" 【眩晕】":"")
<< (player.getPoison()?" 【中毒】":"") << "\n";
cout << ai.getName() << " HP:" << ai.getHp()
<< " 护盾:" << ai.getShield()
<< (ai.getStun()?" 【眩晕】":"")
<< (ai.getPoison()?" 【中毒】":"") << "\n";
cout << "====================================\n";
}
void apply(Card c, Player& from, Player& to) {
sound();
cout << "\n? " << from.getName() << " 使用:" << c.name << "\n";
anim();
switch (c.type) {
case ATTACK:
cout << "造成" << c.value << "点伤害!\n";
to.takeDamage(c.value);
break;
case DEFENSE:
from.setShield(from.getShield() + c.value);
cout << "获得" << c.value << "点护盾!\n";
break;
case HEAL:
from.setHp(from.getHp() + c.value);
cout << "恢复" << c.value << "点生命!\n";
break;
case STUN:
to.setStun(true);
cout << to.getName() << "被眩晕!\n";
break;
case DRAW:
from.draw(c.value);
cout << "抽" << c.value << "张牌!\n";
break;
case TAUNT:
cout << "强制攻击!\n";
break;
case POISON:
to.setPoison(true, c.value);
cout << to.getName() << "中毒!\n";
break;
case BUFF:
from.addBuff(c.value);
cout << "攻击提升!\n";
break;
}
printStatus();
}
bool check() {
if (player.getHp() <= 0) {
soundLose();
cout << "\n?? 你倒下了... 黑暗吞噬了一切\n";
gameOver = true;
return true;
}
if (ai.getHp() <= 0) {
soundWin();
cout << "\n?? 胜利!你击败了敌人!\n";
if (level == 3) {
cout << "\n? 最终胜利!你拯救了王国,成为传说卡牌大师!\n";
}
gameOver = true;
return true;
}
return false;
}
public:
CardGame() : player("冒险者","",35), ai("敌人","all",30), gameOver(false), level(1) {
srand(time(0));
}
void storyIntro() {
cout << "===== 战略卡牌传说 · 终极版 =====\n\n";
cout << "故事开始:\n";
anim();
cout << "黑暗军团入侵王国,唯有卡牌之力能阻挡邪恶...\n";
anim();
cout << "你,一位年轻的冒险者,踏上拯救世界的征途!\n";
anim();
cout << "选择你的职业,构筑卡组,战胜所有敌人!\n\n";
}
void selectJob() {
cout << "===== 选择你的职业 =====\n";
cout << "1. 战士 2. 法师 3. 游侠\n";
cout << "4. 牧师 5. 刺客 6. 德鲁伊\n";
int c; cin >> c;
string j;
if (c==1) j="warrior";
else if (c==2) j="mage";
else if (c==3) j="ranger";
else if (c==4) j="priest";
else if (c==5) j="assassin";
else j="druid";
player.setJob(j);
cout << "你选择了:" << (c==1?"战士":c==2?"法师":c==3?"游侠":c==4?"牧师":c==5?"刺客":"德鲁伊") << "\n";
}
void start() {
storyIntro();
selectJob();
player.buildDeck();
while (level <= 3) {
gameOver = false;
if (level == 1) {
cout << "\n==== 第一关:守卫士兵 ====\n";
ai = Player("士兵","warrior",30);
} else if (level == 2) {
cout << "\n==== 第二关:黑暗法师 ====\n";
ai = Player("法师","mage",35);
} else {
cout << "\n==== 最终关:魔王 ====\n";
ai = Player("魔王","all",45);
}
player.draw(5);
ai.draw(5);
printStatus();
while (!gameOver) {
playerTurn();
if (gameOver) break;
aiTurn();
check();
}
if (player.getHp() <= 0) break;
level++;
}
}
void playerTurn() {
cout << "\n===== 你的回合 ====\n";
anim();
player.poisonDamage();
if (check()) return;
if (player.getStun()) {
cout << "你被眩晕,无法行动!\n";
player.setStun(false);
return;
}
player.draw(1);
player.showHand();
int c; cout << "出牌:"; cin >> c;
Card card = player.play(c-1);
apply(card, player, ai);
}
void aiTurn() {
cout << "\n===== 敌方回合 ====\n";
anim();
ai.poisonDamage();
if (check()) return;
if (ai.getStun()) {
cout << "敌人被眩晕!\n";
ai.setStun(false);
return;
}
ai.draw(1);
int idx = ai.aiChoose(player);
if (idx < 0 || idx >= ai.getHandCount()) return;
Card c = ai.play(idx);
apply(c, ai, player);
}
};
int main() {
CardGame game;
game.start();
return 0;
}