- js24012 的博客
Kards(c++版)
- @ 2026-7-24 11:30:23
代码:
#include <iostream>
#include <vector>
#include <algorithm>
#include <random>
#include <string>
#include <iomanip>
#include <unordered_map>
using namespace std;
// ============ 兵种分类 ============
enum UnitCategory {
INFANTRY, // 步兵
TANK, // 坦克
ARTILLERY, // 炮兵
FIGHTER, // 战斗机
BOMBER // 轰炸机
};
enum CardType {
UNIT,
ORDER
};
// 战线
enum BattleZone {
SUPPORT_LINE,
FRONT_LINE
};
// 稀有等级
enum Rarity {
IRON, // 铁卡:单张卡牌本局最多抽4张
COPPER, // 铜卡:单张卡牌本局最多抽3张
SILVER, // 银卡:单张卡牌本局最多抽2张
ELITE // 精英:单张卡牌本局最多抽1张
};
string getRarityName(Rarity r)
{
if(r == IRON) return "【铁卡】";
if(r == COPPER) return "【铜卡】";
if(r == SILVER) return "【银卡】";
if(r == ELITE) return "【精英】";
return "【未知】";
}
int getMaxDrawNum(Rarity r)
{
if(r == IRON) return 4;
if(r == COPPER) return 3;
if(r == SILVER) return 2;
if(r == ELITE) return 1;
return 0;
}
struct Card {
string name;
string nation;
CardType type;
UnitCategory category;
BattleZone zone;
Rarity rarity;
int deployCost;
int opCost;
int attack;
int health;
int maxHealth;
string keyword;
bool hasMoved;
bool hasAttacked;
bool shockUsed;
bool hasSmoke;
bool suppressed;
bool inhibited;
Card(string n, string nat, UnitCategory cat, Rarity rar, int dc, int oc, int a, int h, string kw)
: name(n), nation(nat), type(UNIT), category(cat), zone(SUPPORT_LINE), rarity(rar),
deployCost(dc), opCost(oc), attack(a), health(h), maxHealth(h), keyword(kw),
hasMoved(false), hasAttacked(false), shockUsed(false), hasSmoke(false), suppressed(false), inhibited(false) {}
Card(string n, string nat, Rarity rar, int dc, string kw)
: name(n), nation(nat), type(ORDER), category(INFANTRY), zone(SUPPORT_LINE), rarity(rar),
deployCost(dc), opCost(0), attack(0), health(0), maxHealth(0), keyword(kw),
hasMoved(false), hasAttacked(false), shockUsed(false), hasSmoke(false), suppressed(false), inhibited(false) {}
};
class Player {
public:
string name;
int hqHP;
int credit;
int maxCreditSlot;
vector<Card> deck;
vector<Card> hand;
vector<Card> supportLine;
vector<Card> frontLine;
mt19937 rng;
unordered_map<string,int> cardDrawCount;
Player(string n) : name(n), hqHP(20), credit(0), maxCreditSlot(0)
{
random_device rd;
rng.seed(rd());
}
void shuffleDeck() {
shuffle(deck.begin(), deck.end(), rng);
}
bool reachCardLimit(const string& cardName, Rarity rar)
{
int already = 0;
if(cardDrawCount.find(cardName) != cardDrawCount.end())
already = cardDrawCount[cardName];
return already >= getMaxDrawNum(rar);
}
void addCardCount(const string& cardName)
{
cardDrawCount[cardName]++;
}
void drawCard() {
if (deck.empty())
{
cout << "\n>>> " << name << "牌库已经耗尽,无法继续抽牌!\n";
return;
}
if (hand.size() >= 9)
{
Card c = deck.back();
deck.pop_back();
cout << ">>> " << name << "手牌已满9张,抽到【" << c.name << "】直接销毁\n";
return;
}
Card drawn = deck.back();
deck.pop_back();
if(drawn.type == UNIT && reachCardLimit(drawn.name, drawn.rarity))
{
cout << ">>> " << name << "抽到【" << drawn.name << "】" << getRarityName(drawn.rarity)
<< ",本局该卡牌已达抽取上限,卡牌直接销毁!\n";
return;
}
//指令卡同样遵守抽取上限规则
if(drawn.type == ORDER && reachCardLimit(drawn.name, drawn.rarity))
{
cout << ">>> " << name << "抽到【" << drawn.name << "】" << getRarityName(drawn.rarity)
<< ",本局该卡牌已达抽取上限,卡牌直接销毁!\n";
return;
}
if(drawn.type == UNIT || drawn.type == ORDER)
addCardCount(drawn.name);
hand.push_back(drawn);
cout << ">>> " << name << "抽到卡牌:【" << drawn.name << "】" << getRarityName(drawn.rarity) << "\n";
}
void turnStart() {
if (maxCreditSlot < 12) maxCreditSlot++;
credit = maxCreditSlot;
drawCard();
for (auto& c : supportLine) {
if (c.keyword.find("补给") != string::npos)
c.health = min(c.health + 1, c.maxHealth);
c.hasMoved = false;
c.hasAttacked = false;
c.hasSmoke = false;
c.suppressed = false;
c.inhibited = false;
}
for (auto& c : frontLine) {
if (c.keyword.find("补给") != string::npos)
c.health = min(c.health + 1, c.maxHealth);
c.hasMoved = false;
c.hasAttacked = false;
c.hasSmoke = false;
c.suppressed = false;
c.inhibited = false;
}
}
bool playUnit(int idx, Player& enemy) {
if (idx < 0 || idx >= (int)hand.size()) {
cout << ">>> 错误:无效手牌序号!\n";
return false;
}
Card c = hand[idx];
if (c.type != UNIT) {
cout << ">>> 错误:该卡牌是指令卡!\n";
return false;
}
if (credit < c.deployCost) {
cout << ">>> 错误:指挥点不足!\n";
return false;
}
if (supportLine.size() >= 4) {
cout << ">>> 错误:支援阵线已满4单位!\n";
return false;
}
credit -= c.deployCost;
c.zone = SUPPORT_LINE;
if (c.keyword.find("闪击") == string::npos)
{
c.hasMoved = true;
c.hasAttacked = false;
}
else
{
c.hasMoved = false;
c.hasAttacked = false;
}
string deployName = c.name;
supportLine.push_back(c);
hand.erase(hand.begin() + idx);
// ====== 鼠式登场特效 ======
if(deployName == "鼠式")
{
cout << "\n===== 鼠式登场能力发动!=====\n";
vector<Card> allEnemyUnits;
for(auto &u : enemy.supportLine) allEnemyUnits.push_back(u);
for(auto &u : enemy.frontLine) allEnemyUnits.push_back(u);
int hitCount = allEnemyUnits.size();
for(auto &victim : allEnemyUnits)
{
cout << ">>> 鼠式消灭敌方单位【" << victim.name << "】\n";
}
enemy.hqHP -= hitCount * 2;
cout << ">>> 敌方总部受到 " << hitCount * 2 << " 点伤害!\n";
enemy.supportLine.clear();
enemy.frontLine.clear();
}
if(c.keyword.find("侦察") != string::npos && !deck.empty())
drawCard();
cout << ">>> " << name << "部署【" << deployName << "】 " << c.attack << "/" << c.health << " | " << c.keyword << "\n";
return true;
}
bool castOrder(int idx, Player& self, Player& enemy) {
if (idx < 0 || idx >= (int)hand.size()) {
cout << ">>> 错误:无效手牌序号!\n";
return false;
}
Card order = hand[idx];
if (order.type != ORDER) {
cout << ">>> 错误:这是作战单位!\n";
return false;
}
if (credit < order.deployCost) {
cout << ">>> 错误:指挥点不足!\n";
return false;
}
credit -= order.deployCost;
cout << ">>> " << name << "发动指令【" << order.name << "】\n";
if (order.name == "地毯式轰炸") {
auto dmgAll = [](vector<Card>& group) {
for(auto& u : group)
u.health -= 3;
};
dmgAll(self.supportLine);
dmgAll(self.frontLine);
dmgAll(enemy.supportLine);
dmgAll(enemy.frontLine);
cout << ">>> 地毯式轰炸!场上所有单位受到3点伤害!\n";
auto clear = [](vector<Card>& vec){
vector<Card> alive;
for(auto& c : vec) if(c.health > 0) alive.push_back(c);
vec.swap(alive);
};
clear(self.supportLine);
clear(self.frontLine);
clear(enemy.supportLine);
clear(enemy.frontLine);
}
else if (order.name == "反坦克炮击") {
bool killed = false;
if (!enemy.frontLine.empty()) { enemy.frontLine.erase(enemy.frontLine.begin()); killed = true; }
else if (!enemy.supportLine.empty()) { enemy.supportLine.erase(enemy.supportLine.begin()); killed = true; }
if (!killed) {
cout << ">>> 敌方无单位,指令失效,返还指挥点\n";
credit += order.deployCost;
return false;
}
cout << ">>> 摧毁敌方一名作战单位。\n";
}
else if (order.name == "装甲补给") {
if (self.supportLine.empty() && self.frontLine.empty()) {
cout << ">>> 我方无单位,指令失效,返还指挥点\n";
credit += order.deployCost;
return false;
}
Card& target = (!self.frontLine.empty()) ? self.frontLine[0] : self.supportLine[0];
target.attack += 2;
target.health += 2;
target.maxHealth += 2;
cout << ">>> 目标单位+2攻击/+2生命\n";
}
else if (order.name == "紧急动员") {
self.drawCard();
self.drawCard();
}
else if (order.name == "空中封锁") {
for (auto& u : enemy.supportLine) { u.hasMoved = true; u.hasAttacked = true; }
for (auto& u : enemy.frontLine) { u.hasMoved = true; u.hasAttacked = true; }
cout << ">>> 所有敌方本回合无法行动。\n";
}
else if (order.name == "战地急救") {
self.hqHP = min(self.hqHP + 5, 30);
cout << ">>> 总部恢复5生命。\n";
}
else if (order.name == "医疗纵队") {
self.hqHP = min(self.hqHP + 4, 30);
vector<Card*> allUnits;
for (auto& u : self.supportLine) allUnits.push_back(&u);
for (auto& u : self.frontLine) allUnits.push_back(&u);
if (!allUnits.empty()) {
uniform_int_distribution<int> dist(0, (int)allUnits.size() - 1);
int r = dist(rng);
allUnits[r]->health = allUnits[r]->maxHealth;
cout << ">>> 总部+4生命,修复一名友方至满血\n";
}
}
else if (order.name == "休整待命") {
self.hqHP = min(self.hqHP + 7, 30);
cout << ">>> 总部恢复7生命。\n";
}
else if (order.name == "战时生产") {
if (self.maxCreditSlot >= 12) {
cout << ">>> 槽位已满,指令失效,返还指挥点\n";
credit += order.deployCost;
return false;
}
self.maxCreditSlot += 1;
self.credit += 2;
cout << ">>> 上限+1,获得2指挥点\n";
}
else if (order.name == "北方的铁矿") {
if (self.frontLine.empty())
{
cout << ">>> 前线无单位,指令失效,返还指挥点\n";
credit += order.deployCost;
return false;
}
self.credit += 3;
cout << ">>> 前线存在单位,获得3指挥点\n";
}
//=====新增美国经济指令=====
else if(order.name == "战争机器")
{
self.maxCreditSlot += 1;
cout << ">>> 指挥点槽位+1(无视12上限)\n";
}
else if(order.name == "战争需要")
{
self.maxCreditSlot += 2;
cout << ">>> 指挥点槽位+2(无视12上限)\n";
}
else if(order.name == "战争债券")
{
self.maxCreditSlot += 2;
if(!self.deck.empty()) self.drawCard();
cout << ">>> 指挥点槽位+2(无视12上限),抽取一张卡牌\n";
}
else if (order.name == "军备研发") {
cout << "\n【军备研发 · 三选一】\n1.德军步兵 2.美军步枪兵 3.轻型轰炸机\n选择:";
int sel; cin >> sel;
if (sel == 1)
self.hand.emplace_back("德军步兵","德国", INFANTRY, IRON, 1, 1, 1, 2, "无词条");
else if (sel == 2)
self.hand.emplace_back("美军步枪兵","美国", INFANTRY, COPPER, 1, 1, 1, 3, "补给");
else
self.hand.emplace_back("轻型轰炸机","美国", BOMBER, COPPER, 3, 1, 2, 2, "远程");
cout << ">>> 研发完成加入手牌(研发单位不计入本局抽取上限)\n";
}
else if (order.name == "重型装备开发") {
cout << "\n【重型装备开发 · 三选一】\n1.四号坦克 2.T-34坦克 3.喷火战斗机\n选择:";
int sel; cin >> sel;
if (sel == 1)
self.hand.emplace_back("四号坦克","德国", TANK, SILVER, 4, 1, 4, 4, "重甲");
else if (sel == 2)
self.hand.emplace_back("T-34坦克","苏联", TANK, SILVER, 4, 1, 3, 5, "闪击");
else
self.hand.emplace_back("喷火战斗机","英国", FIGHTER, SILVER, 4, 1, 4, 2, "远程,制空");
cout << ">>> 研发完成加入手牌(研发单位不计入本局抽取上限)\n";
}
hand.erase(hand.begin() + idx);
return true;
}
bool advanceToFront(int unitIdx, Player& enemy) {
if (unitIdx < 0 || unitIdx >= (int)supportLine.size()) {
cout << ">>> 错误:单位序号无效\n";
return false;
}
Card& u = supportLine[unitIdx];
if (u.hasMoved) {
cout << ">>> 该单位本回合已移动!\n";
return false;
}
if(u.suppressed)
{
cout << ">>> 单位受到【压制】效果,本回合无法移动!\n";
return false;
}
if (credit < u.opCost) {
cout << ">>> 指挥点不足\n";
return false;
}
if (frontLine.size() >= 5) {
cout << ">>> 前线已满\n";
return false;
}
if (!enemy.frontLine.empty()) {
cout << ">>> 敌方占据前线,无法推进!\n";
return false;
}
credit -= u.opCost;
u.hasMoved = true;
u.zone = FRONT_LINE;
frontLine.push_back(u);
supportLine.erase(supportLine.begin() + unitIdx);
cout << ">>> " << u.name << "推进占领前线\n";
return true;
}
bool attackHQ(int zoneSel, int unitIdx, Player& enemy) {
Card* attacker = nullptr;
if (zoneSel == 1) {
if (unitIdx < 0 || unitIdx >= (int)supportLine.size()) return false;
attacker = &supportLine[unitIdx];
} else {
if (unitIdx < 0 || unitIdx >= (int)frontLine.size()) return false;
attacker = &frontLine[unitIdx];
}
Card& atk = *attacker;
if (atk.hasAttacked) { cout << ">>> 单位本回合已进攻!\n"; return false; }
if (atk.category == INFANTRY && atk.hasMoved) { cout << ">>> 步兵移动后无法进攻!\n"; return false; }
if(atk.suppressed)
{
cout << ">>> 单位受到【压制】,无法发起进攻!\n";
return false;
}
if (credit < atk.opCost) { cout << ">>> 指挥点不足\n"; return false; }
if(atk.hasSmoke)
{
cout << ">>> 目标带有【烟幕】,无法选中!\n";
return false;
}
bool canReachHQ = (atk.category == ARTILLERY || atk.category == BOMBER || atk.category == FIGHTER)
|| (atk.zone == FRONT_LINE);
if (!canReachHQ) {
cout << ">>> 步兵/坦克必须在前线才能攻击总部!\n";
return false;
}
if(atk.category == BOMBER)
{
bool enemyHasFighter = false;
for(auto &u : enemy.supportLine)
if(u.category == FIGHTER) { enemyHasFighter = true; break; }
if(enemyHasFighter)
{
cout << ">>> 敌方支援阵线存在战斗机,轰炸机禁止直接轰炸总部!\n";
return false;
}
}
credit -= atk.opCost;
atk.hasAttacked = true;
int damage = atk.attack;
if(atk.inhibited) damage = max(0, damage - 2);
enemy.hqHP -= damage;
cout << ">>> " << atk.name << "攻击敌方总部,造成" << damage << "伤害!敌方剩余HP:" << enemy.hqHP << "\n";
return true;
}
bool engageUnit(int myZone, int myIdx, int enemyZone, int enemyIdx, Player& enemy) {
Card* attacker = nullptr;
if (myZone == 1) {
if (myIdx < 0 || myIdx >= (int)supportLine.size()) return false;
attacker = &supportLine[myIdx];
} else {
if (myIdx < 0 || myIdx >= (int)frontLine.size()) return false;
attacker = &frontLine[myIdx];
}
Card& atk = *attacker;
Card* defender = nullptr;
if (enemyZone == 1) {
if (enemyIdx < 0 || enemyIdx >= (int)enemy.supportLine.size()) return false;
defender = &enemy.supportLine[enemyIdx];
} else {
if (enemyIdx < 0 || enemyIdx >= (int)enemy.frontLine.size()) return false;
defender = &enemy.frontLine[enemyIdx];
}
Card& def = *defender;
if (atk.hasAttacked) { cout << ">>> 单位本回合已进攻!\n"; return false; }
if (atk.category == INFANTRY && atk.hasMoved) { cout << ">>> 步兵移动后不能进攻!\n"; return false; }
if(atk.suppressed)
{
cout << ">>> 单位受到【压制】,无法发起进攻!\n";
return false;
}
if(def.hasSmoke)
{
cout << ">>> 目标带有【烟幕】,无法选中!\n";
return false;
}
if (credit < atk.opCost) { cout << ">>> 指挥点不足\n"; return false; }
if(atk.category == BOMBER)
{
bool enemyHasSupportFighter = false;
for(auto &u : enemy.supportLine)
if(u.category == FIGHTER) { enemyHasSupportFighter = true; break; }
if(enemyHasSupportFighter && !(enemyZone == 1 && def.category == FIGHTER))
{
cout << ">>> 敌方支援有战斗机,轰炸机只能攻击敌方支援阵线战斗机!\n";
return false;
}
}
credit -= atk.opCost;
atk.hasAttacked = true;
cout << ">>> " << atk.name << " 交战 " << def.name << "\n";
int dmg = atk.attack;
if(atk.inhibited) dmg = max(0, dmg - 2);
if(atk.keyword.find("冲击") != string::npos && !atk.shockUsed)
{
dmg += 2;
atk.shockUsed = true;
}
if ((atk.keyword.find("穿甲") != string::npos) && def.category == TANK)
dmg *= 2;
if(atk.keyword.find("制空") != string::npos && (def.category == BOMBER || def.category == FIGHTER))
dmg += 3;
if (def.keyword.find("重甲") != string::npos)
dmg = max(1, dmg - 1);
def.health -= dmg;
int counterDmg = 0;
if (!(atk.category == ARTILLERY || atk.category == BOMBER))
{
if(def.keyword.find("伏击") != string::npos)
{
counterDmg = def.attack;
if (atk.keyword.find("重甲") != string::npos)
counterDmg = max(1, counterDmg - 1);
atk.health -= counterDmg;
counterDmg = 0;
}
else
{
counterDmg = def.attack;
if (atk.keyword.find("重甲") != string::npos)
counterDmg = max(1, counterDmg - 1);
}
}
atk.health -= counterDmg;
if (def.health <= 0 && def.keyword.find("坚守") != string::npos) def.health = 1;
if (atk.health <= 0 && atk.keyword.find("坚守") != string::npos) atk.health = 1;
auto clearDead = [](vector<Card>& zone) {
vector<Card> alive;
for (auto& c : zone) if (c.health > 0) alive.push_back(c);
zone.swap(alive);
};
clearDead(supportLine);
clearDead(frontLine);
clearDead(enemy.supportLine);
clearDead(enemy.frontLine);
return true;
}
void showStatusHeader()
{
cout << "\n============================================================\n";
cout << " 【" << name << " 回合信息】\n";
cout << " 指挥点:" << credit << "/" << maxCreditSlot << " | 总部生命值:" << hqHP << "\n";
cout << " 规则:同名称单位/指令卡本局抽取有上限;战时生产最高12槽,部分美国指令可突破上限\n";
cout << "============================================================\n";
}
void showSupportLine() {
cout << "\n【支援阵线】(上限4单位)\n";
if (supportLine.empty()) {
cout << " 暂无单位\n";
return;
}
for (int i = 0; i < (int)supportLine.size(); i++) {
auto& u = supportLine[i];
cout << " " << i+1 << ". " << u.name << getRarityName(u.rarity) << "[" << u.nation << "]"
<< " 攻:" << u.attack << " 血:" << u.health << "/" << u.maxHealth << " 行动消耗:" << u.opCost;
vector<string> tag;
if(u.hasMoved) tag.push_back("已移动");
if(u.hasAttacked) tag.push_back("已进攻");
if(u.suppressed) tag.push_back("压制");
if(u.inhibited) tag.push_back("抑制");
if(u.hasSmoke) tag.push_back("烟幕");
if(!tag.empty()){
cout << " 【";
for(size_t t=0;t<tag.size();t++){
if(t>0) cout << ",";
cout << tag[t];
}
cout << "】";
}
cout << " | 词条:" << u.keyword << "\n";
}
}
void showFrontLine() {
cout << "\n【前线阵地】(上限5单位)\n";
if (frontLine.empty()) {
cout << " 暂无单位\n";
return;
}
for (int i = 0; i < (int)frontLine.size(); i++) {
auto& u = frontLine[i];
cout << " " << i+1 << ". " << u.name << getRarityName(u.rarity) << "[" << u.nation << "]"
<< " 攻:" << u.attack << " 血:" << u.health << "/" << u.maxHealth << " 行动消耗:" << u.opCost;
vector<string> tag;
if(u.hasMoved) tag.push_back("已移动");
if(u.hasAttacked) tag.push_back("已进攻");
if(u.suppressed) tag.push_back("压制");
if(u.inhibited) tag.push_back("抑制");
if(u.hasSmoke) tag.push_back("烟幕");
if(!tag.empty()){
cout << " 【";
for(size_t t=0;t<tag.size();t++){
if(t>0) cout << ",";
cout << tag[t];
}
cout << "】";
}
cout << " | 词条:" << u.keyword << "\n";
}
}
void showHand() {
cout << "\n【手牌】上限9张\n";
if (hand.empty()) {
cout << " 暂无手牌\n";
return;
}
for (int i = 0; i < (int)hand.size(); i++) {
auto& c = hand[i];
cout << " " << i+1 << ". " << c.name << getRarityName(c.rarity) << "[" << c.nation << "]"
<< " 部署费用:" << c.deployCost;
if(c.type == UNIT)
cout << " 攻:" << c.attack << " 血:" << c.health;
else
cout << " 【指令卡】";
cout << " | " << c.keyword << "\n";
}
}
};
bool findMaxThreatTarget(Player& enemy, int &zoneOut, int &idxOut)
{
int scoreMax = -1;
zoneOut = 1; idxOut = 0;
for(int i=0; i<(int)enemy.supportLine.size();i++)
{
auto &u = enemy.supportLine[i];
int s = u.attack;
if(u.category == ARTILLERY || u.category == BOMBER || u.category == FIGHTER) s += 6;
if(s > scoreMax) { scoreMax = s; zoneOut = 1; idxOut = i; }
}
for(int i=0; i<(int)enemy.frontLine.size();i++)
{
auto &u = enemy.frontLine[i];
int s = u.attack;
if(u.category == ARTILLERY || u.category == BOMBER || u.category == FIGHTER) s += 6;
if(s > scoreMax) { scoreMax = s; zoneOut = 2; idxOut = i; }
}
return scoreMax != -1;
}
bool findEnemySupportFighter(Player& enemy, int &idxOut)
{
for(int i=0; i<(int)enemy.supportLine.size();i++)
{
if(enemy.supportLine[i].category == FIGHTER)
{
idxOut = i;
return true;
}
}
return false;
}
void aiTurnAction(Player &ai, Player &player)
{
const int RESERVE_POINT = 2;
vector<int> orderList;
for(int i=0;i<(int)ai.hand.size();i++)
{
auto &c = ai.hand[i];
if(c.type == ORDER && ai.credit >= c.deployCost + RESERVE_POINT)
orderList.push_back(i);
}
// 指令优先级,新增三张经济指令加入序列
vector<string> priorityOrder = {
"空中封锁",
"反坦克炮击",
"地毯式轰炸",
"紧急动员",
"战争债券",
"战争需要",
"战时生产",
"战争机器",
"装甲补给",
"休整待命",
"医疗纵队",
"战地急救",
"北方的铁矿"
};
bool usedOrder = false;
for(auto &want : priorityOrder)
{
for(int idx : orderList)
{
if(ai.hand[idx].name == want)
{
if(want == "北方的铁矿")
{
bool frontHasUnit = !ai.frontLine.empty();
if(!frontHasUnit || ai.credit > 3)
continue;
}
if((want == "战地急救" || want == "休整待命" || want == "医疗纵队") && ai.hqHP > 12)
continue;
if(want == "装甲补给" && ai.supportLine.empty() && ai.frontLine.empty())
continue;
ai.castOrder(idx, ai, player);
usedOrder = true;
break;
}
}
if(usedOrder) break;
}
bool deployed;
do{
deployed = false;
int pick = -1;
int minCost = 99;
for(int i=0;i<(int)ai.hand.size();i++)
{
auto &c = ai.hand[i];
if(c.type == UNIT && ai.supportLine.size() < 4 && ai.credit >= c.deployCost + RESERVE_POINT)
{
if(c.deployCost < minCost)
{
minCost = c.deployCost;
pick = i;
}
}
}
if(pick != -1)
{
ai.playUnit(pick, player);
deployed = true;
}
}while(deployed);
for(int i=0;i<(int)ai.supportLine.size();i++)
{
auto &u = ai.supportLine[i];
if(!u.hasMoved && !u.suppressed && ai.credit >= u.opCost + RESERVE_POINT
&& ai.frontLine.empty() && player.frontLine.empty())
{
ai.advanceToFront(i, player);
break;
}
}
for(int zoneType : {1,2})
{
vector<Card> &group = (zoneType == 1) ? ai.supportLine : ai.frontLine;
for(int i=0;i<(int)group.size();i++)
{
auto &u = group[i];
if(u.category == BOMBER && !u.hasAttacked && !u.suppressed && ai.credit >= u.opCost + RESERVE_POINT)
{
int fighterIdx;
if(findEnemySupportFighter(player, fighterIdx))
{
ai.engageUnit(zoneType, i, 1, fighterIdx, player);
return;
}
}
}
}
int totalFrontDmg = 0;
for(auto &u : ai.frontLine) totalFrontDmg += u.attack;
bool canKillEnemyHQ = (totalFrontDmg >= player.hqHP);
if(canKillEnemyHQ)
{
for(int i=0;i<(int)ai.frontLine.size();i++)
{
if(!ai.frontLine[i].hasAttacked && !ai.frontLine[i].suppressed && ai.credit >= ai.frontLine[i].opCost)
{
ai.attackHQ(2,i,player);
}
}
return;
}
int enemyZone, enemyIdx;
if(findMaxThreatTarget(player, enemyZone, enemyIdx))
{
for(int i=0;i<(int)ai.frontLine.size();i++)
{
if(!ai.frontLine[i].hasAttacked && !ai.frontLine[i].suppressed && ai.credit >= ai.frontLine[i].opCost + RESERVE_POINT)
{
ai.engageUnit(2,i,enemyZone,enemyIdx,player);
return;
}
}
for(int i=0;i<(int)ai.supportLine.size();i++)
{
auto &u = ai.supportLine[i];
if((u.category == ARTILLERY || u.category == BOMBER || u.category == FIGHTER)
&& !u.hasAttacked && !u.suppressed && ai.credit >= u.opCost + RESERVE_POINT)
{
ai.engageUnit(1,i,enemyZone,enemyIdx,player);
return;
}
}
}
bool enemyHasUnit = (!player.supportLine.empty() || !player.frontLine.empty());
if(!enemyHasUnit)
{
for(int i=0;i<(int)ai.frontLine.size();i++)
{
if(!ai.frontLine[i].hasAttacked && !ai.frontLine[i].suppressed && ai.credit >= ai.frontLine[i].opCost)
{
ai.attackHQ(2,i,player);
}
}
}
}
void initFullDeck(Player& p)
{
// ============ 铁卡 IRON【新增多张1费卡】 ============
//德国
p.deck.emplace_back("德军步兵","德国", INFANTRY, IRON, 1, 1, 1, 2, "无词条");
p.deck.emplace_back("侦察装甲车","德国", TANK, IRON, 2, 1, 2, 2, "侦察");
p.deck.emplace_back("德军传令兵","德国", INFANTRY, IRON, 1, 1, 1, 1, "侦察");
//苏联
p.deck.emplace_back("苏联第1088兵团","苏联", INFANTRY, IRON, 0, 0, 1, 1, "闪击");
p.deck.emplace_back("红军步兵","苏联", INFANTRY, IRON, 1, 1, 2, 1, "冲击");
p.deck.emplace_back("民兵游击队","苏联", INFANTRY, IRON, 1, 1, 1, 2, "伏击");
//美国
p.deck.emplace_back("国民警卫队","美国", INFANTRY, IRON, 1, 1, 1, 2, "伏击");
p.deck.emplace_back("美军传令兵","美国", INFANTRY, IRON, 1, 1, 1, 1, "侦察");
//英国
p.deck.emplace_back("本土民兵","英国", INFANTRY, IRON, 1, 1, 1, 2, "守护");
p.deck.emplace_back("皇家斥候","英国", INFANTRY, IRON, 1, 1, 1, 1, "侦察");
// ============ 铜卡 COPPER ============
//德国
p.deck.emplace_back("风暴突击兵","德国", INFANTRY, COPPER, 2, 1, 2, 3, "闪击");
p.deck.emplace_back("玛蒂尔达坦克","德国", TANK, COPPER, 3, 1, 2, 5, "重甲");
p.deck.emplace_back("88毫米高炮","德国", ARTILLERY, COPPER, 3, 1, 3, 2, "远程,制空");
//苏联
p.deck.emplace_back("工兵小队","苏联", INFANTRY, COPPER, 2, 1, 1, 4, "守护");
p.deck.emplace_back("反坦克步兵","苏联", INFANTRY, COPPER, 2, 1, 3, 1, "穿甲");
//美国
p.deck.emplace_back("美军步枪兵","美国", INFANTRY, COPPER, 1, 1, 1, 3, "补给");
p.deck.emplace_back("轻型轰炸机","美国", BOMBER, COPPER, 3, 1, 2, 2, "远程");
//英国
p.deck.emplace_back("英军步兵","英国", INFANTRY, COPPER, 2, 1, 2, 2, "压制");
p.deck.emplace_back("25磅野战炮","英国", ARTILLERY, COPPER, 3, 1, 3, 3, "远程");
// ============ 银卡 SILVER ============
//德国
p.deck.emplace_back("四号坦克","德国", TANK, SILVER, 4, 1, 4, 4, "重甲");
p.deck.emplace_back("斯图卡俯冲轰炸机","德国", BOMBER, SILVER, 5, 1, 4, 3, "远程,冲击");
//苏联
p.deck.emplace_back("近卫步兵","苏联", INFANTRY, SILVER, 3, 1, 3, 3, "坚守");
p.deck.emplace_back("T-34坦克","苏联", TANK, SILVER, 4, 1, 3, 5, "闪击");
p.deck.emplace_back("伊尔-2攻击机","苏联", BOMBER, SILVER, 4, 1, 3, 4, "远程,穿甲");
//美国
p.deck.emplace_back("游骑兵","美国", INFANTRY, SILVER, 3, 1, 4, 2, "伏击");
p.deck.emplace_back("谢尔曼坦克","美国", TANK, SILVER, 4, 1, 4, 3, "冲击");
p.deck.emplace_back("105毫米榴弹炮","美国", ARTILLERY, SILVER, 4, 1, 4, 3, "远程,抑制");
//英国
p.deck.emplace_back("苏格兰高地兵","英国", INFANTRY, SILVER, 3, 1, 3, 3, "冲击");
p.deck.emplace_back("喷火战斗机","英国", FIGHTER, SILVER, 4, 1, 4, 2, "远程,制空");
p.deck.emplace_back("丘吉尔坦克","英国", TANK, SILVER, 5, 2, 3, 7, "重甲,守护");
// ============ 精英 ELITE ============
//德国
p.deck.emplace_back("虎式坦克H1型","德国", TANK, ELITE, 8, 4, 7, 7, "重甲,冲击");
p.deck.emplace_back("鼠式","德国", TANK, ELITE, 12, 4, 12, 10, "重甲3,守护");
//苏联
p.deck.emplace_back("KV-1重型坦克","苏联", TANK, ELITE, 6, 2, 4, 8, "重甲,守护");
p.deck.emplace_back("喀秋莎火箭炮","苏联", ARTILLERY, ELITE, 5, 2, 5, 2, "远程,压制");
p.deck.emplace_back("IS-2重型坦克","苏联", TANK, ELITE, 8, 3, 8, 6, "重甲,穿甲");
//美国
p.deck.emplace_back("潘兴重型坦克","美国", TANK, ELITE, 6, 2, 5, 6, "重甲,穿甲");
p.deck.emplace_back("兰卡斯特","美国", FIGHTER, ELITE,8 , 3, 7, 3, "远程,制空,闪击");
p.deck.emplace_back("B29超级空中堡垒","美国", BOMBER, ELITE,9,4,8,4,"远程");
//英国
p.deck.emplace_back("彗星坦克","英国", TANK, ELITE,7,2,6,5,"冲击,重甲");
//====================指令卡====================
//铁卡指令
p.deck.emplace_back("北方的铁矿","苏联", IRON, 1, "若友方前线存在单位,立即获得3点指挥点");
p.deck.emplace_back("紧急动员","美国", IRON, 2, "抽取两张卡牌");
p.deck.emplace_back("反坦克炮击","英国", IRON, 2, "消灭一名敌方作战单位");
//新增美国铁卡指令:战争机器
p.deck.emplace_back("战争机器","美国", IRON, 2, "增加1个指挥点槽(无视上限)");
//铜卡指令
p.deck.emplace_back("战地急救","英国", COPPER, 3, "我方总部恢复5点生命值");
p.deck.emplace_back("医疗纵队","苏联", COPPER, 3, "总部+4血,修复一名友方至满血");
p.deck.emplace_back("装甲补给","德国", COPPER, 3, "一个友方单位获得+2攻击/+2生命");
p.deck.emplace_back("军备研发","美国", COPPER, 3, "三选一研发轻型单位加入手牌");
//新增美国铜卡指令:战争债券
p.deck.emplace_back("战争债券","美国", COPPER, 5, "增加两个指挥点槽(无视上限)并抽一张卡");
//银卡指令
p.deck.emplace_back("战时生产","德国", SILVER, 4, "指挥槽上限+1,获得2指挥点(最高12槽)");
p.deck.emplace_back("地毯式轰炸","美国", SILVER, 4, "对场上所有单位造成3点伤害");
p.deck.emplace_back("空中封锁","英国", SILVER, 4, "所有敌方单位本回合无法行动");
p.deck.emplace_back("休整待命","苏联", SILVER, 4, "我方总部恢复7点生命值");
//新增美国银卡指令:战争需要
p.deck.emplace_back("战争需要","美国", SILVER, 4, "增加2个指挥点槽(无视上限)");
//精英指令
p.deck.emplace_back("重型装备开发","德国", ELITE, 5, "三选一研发重型单位加入手牌");
p.shuffleDeck();
}
int main()
{
Player player("玩家");
Player ai("AI对手");
initFullDeck(player);
initFullDeck(ai);
for (int i = 0; i < 3; i++) {
player.drawCard();
ai.drawCard();
}
bool isPlayerTurn = true;
while (player.hqHP > 0 && ai.hqHP > 0)
{
system("cls");
if (isPlayerTurn)
{
player.turnStart();
while(true)
{
player.showStatusHeader();
cout << "【?? AI对手阵地信息】\n";
ai.showSupportLine();
ai.showFrontLine();
cout << "\n----------------------------------------\n";
cout << "【?? 我方阵地信息】\n";
player.showSupportLine();
player.showFrontLine();
player.showHand();
cout << "\n========== 操作菜单 ==========\n";
cout << "1 部署单位 | 2 使用指令\n";
cout << "3 单位推进前线 | 4 攻击敌方总部\n";
cout << "5 交战敌方单位 | 6 结束回合\n";
cout << "请输入操作编号:";
int op;
cin >> op;
if(op == 1){
int id;cout<<"手牌序号:";cin>>id;player.playUnit(id-1, ai);
}else if(op == 2){
int id;cout<<"手牌序号:";cin>>id;player.castOrder(id-1,player,ai);
}else if(op == 3){
int id;cout<<"支援阵线单位序号:";cin>>id;player.advanceToFront(id-1,ai);
}else if(op == 4){
int z,idx;cout<<"战线(1支援/2前线):";cin>>z;cout<<"单位序号:";cin>>idx;player.attackHQ(z,idx-1,ai);
}else if(op == 5){
int myZ,myI,eZ,eI;
cout<<"我方战线(1支援/2前线):";cin>>myZ;
cout<<"我方单位序号:";cin>>myI;
cout<<"敌方战线(1/2):";cin>>eZ;
cout<<"敌方单位序号:";cin>>eI;
player.engageUnit(myZ,myI-1,eZ,eI-1,ai);
}else if(op == 6){
cout<<"回合结束\n";break;
}else{
cout<<"无效指令\n";
}
cout<<"\n按下回车键继续...";
cin.ignore();cin.get();
system("cls");
}
}
else
{
ai.turnStart();
cout << "\n================ ?? AI对手回合 ================\n";
aiTurnAction(ai, player);
cout << "\nAI行动完毕,按下回车键切换玩家回合...";
cin.ignore();cin.get();
}
isPlayerTurn = !isPlayerTurn;
}
if(player.hqHP <= 0)
cout << "\n==================== 游戏结束 ====================\n【战败】我方总部被摧毁!\n";
else
cout << "\n==================== 游戏结束 ====================\n【胜利】敌方总部被摧毁!\n";
return 0;
}