#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
#include <ctime>
#include <cstdlib>
#include <thread>
using namespace std;
enum Color { RED, YELLOW, BLUE, GREEN, BLACK };
struct Card {
Color color;
string value;
string getColorStr() const {
switch (color) {
case RED: return "红色";
case YELLOW: return "黄色";
case BLUE: return "蓝色";
case GREEN: return "绿色";
case BLACK: return "黑色";
default: return "";
}
}
void display() const {
cout << "[" << getColorStr() << " " << value << "]";
}
};
class Player {
public:
string name;
vector<Card> hand;
Player(string n) : name(n) {}
void drawCard(const Card& card) {
hand.push_back(card);
}
void showHand() const {
cout << name << " 的手牌: ";
for (size_t i = 0; i < hand.size(); ++i) {
cout << i + 1 << ".";
hand[i].display();
cout << " ";
}
cout << endl;
}
};
class UnoGame {
private:
vector<Card> deck;
vector<Card> discardPile;
vector<Player> players;
int currentPlayerIdx;
int direction;
public:
UnoGame() : currentPlayerIdx(0), direction(1) {
srand(time(0));
createDeck();
players.emplace_back("你");
players.emplace_back("法国赌神");
players.emplace_back("给我擦皮鞋");
players.emplace_back("法修散打");
}
void createDeck() {
for (int c = 0; c < 4; ++c) {
Color col = static_cast<Color>(c);
deck.push_back({col, "0"}); for (int i = 1; i <= 9; ++i) {
deck.push_back({col, to_string(i)});
deck.push_back({col, to_string(i)}); }
for (int i = 0; i < 2; ++i) {
deck.push_back({col, "Skip"});
deck.push_back({col, "Reverse"});
deck.push_back({col, "+2"});
}
}
for (int i = 0; i < 4; ++i) {
deck.push_back({BLACK, "Wild"});
deck.push_back({BLACK, "+4"});
}
shuffleDeck();
}
void shuffleDeck() {
random_shuffle(deck.begin(), deck.end());
}
void dealCards() {
for (int i = 0; i < 7; ++i) {
for (auto& p : players) {
p.drawCard(deck.back());
deck.pop_back();
}
}
while (deck.back().color == BLACK || (deck.back().value[0] >= 'A' && deck.back().value[0] <= 'Z')) {
shuffleDeck();
}
discardPile.push_back(deck.back());
deck.pop_back();
}
void drawCards(Player& p, int count) {
cout << p.name << " 抽取了 " << count << " 张牌!" << endl;
for (int i = 0; i < count; ++i) {
if (deck.empty()) reshuffleDiscard();
if (!deck.empty()) {
p.drawCard(deck.back());
deck.pop_back();
}
}
}
void reshuffleDiscard() {
if (discardPile.size() <= 1) return;
Card top = discardPile.back();
discardPile.pop_back();
deck = discardPile;
discardPile.clear();
discardPile.push_back(top);
shuffleDeck();
cout << "牌堆已重洗!" << endl;
}
bool isValidMove(const Card& card, const Card& topCard) {
if (card.color == BLACK) return true; if (card.color == topCard.color) return true;
if (card.value == topCard.value) return true;
return false;
}
void aiChangeColor(Player& current) {
int colorCount[4] = {0}; for (const auto& c : current.hand) {
if (c.color != BLACK) {
colorCount[c.color]++;
}
}
int maxColor = 0;
for (int i = 1; i < 4; i++) {
if (colorCount[i] > colorCount[maxColor]) {
maxColor = i;
}
}
discardPile.back().color = static_cast<Color>(maxColor);
cout << current.name << " 将颜色变更为: " << discardPile.back().getColorStr() << endl;
}
void changeColor() {
int colorChoice;
cout << "请选择一种颜色 (1.红色 2.黄色 3.蓝色 4.绿色): ";
cin >> colorChoice;
Color newColor;
switch (colorChoice) {
case 1: newColor = RED; break;
case 2: newColor = YELLOW; break;
case 3: newColor = BLUE; break;
case 4: newColor = GREEN; break;
default: newColor = RED;
}
discardPile.back().color = newColor;
cout << "颜色变更为: " << discardPile.back().getColorStr() << endl;
}
void handleSpecialCard(const Card& card) {
int nextPlayerIdx = (currentPlayerIdx + direction + players.size()) % players.size();
if (card.value == "Skip") {
cout << "使用了【跳过】,下家暂停一回合!" << endl;
currentPlayerIdx = (nextPlayerIdx + direction + players.size()) % players.size();
}
else if (card.value == "Reverse") {
cout << "使用了【反转】,出牌顺序反转!" << endl;
direction *= -1;
currentPlayerIdx = nextPlayerIdx;
if (players.size() == 2) currentPlayerIdx = (currentPlayerIdx + direction + players.size()) % players.size();
}
else if (card.value == "+2") {
cout << "使用了【+2】,下家罚抽2张并跳过回合!" << endl;
drawCards(players[nextPlayerIdx], 2);
currentPlayerIdx = (nextPlayerIdx + direction + players.size()) % players.size();
}
else if (card.value == "Wild") {
cout << "使用了【变色】!";
if (currentPlayerIdx == 0) changeColor(); else aiChangeColor(players[currentPlayerIdx]); currentPlayerIdx = nextPlayerIdx;
}
else if (card.value == "+4") {
cout << "使用了【+4】!";
if (currentPlayerIdx == 0) changeColor();
else aiChangeColor(players[currentPlayerIdx]);
drawCards(players[nextPlayerIdx], 4);
currentPlayerIdx = (nextPlayerIdx + direction + players.size()) % players.size();
}
else {
currentPlayerIdx = nextPlayerIdx;
}
}
void playAITurn() {
Player& current = players[currentPlayerIdx];
Card& topCard = discardPile.back();
cout << "\n-----------------------------\n";
cout << "当前弃牌堆顶牌: ";
topCard.display();
cout << endl;
cout << current.name << " (AI) 正在思考..." << endl;
this_thread::sleep_for(chrono::milliseconds(1000));
int cardIndex = -1;
for (size_t i = 0; i < current.hand.size(); ++i) {
if (isValidMove(current.hand[i], topCard)) {
cardIndex = i;
break;
}
}
if (cardIndex != -1) {
Card selectedCard = current.hand[cardIndex];
current.hand.erase(current.hand.begin() + cardIndex);
discardPile.push_back(selectedCard);
cout << current.name << " 打出了: ";
selectedCard.display();
cout << endl;
if (current.hand.size() == 1) {
cout << current.name << " 大喊: UNO!!!" << endl;
}
if (current.hand.empty()) {
cout << "\n游戏结束!" << current.name << " 获胜!" << endl;
exit(0);
}
handleSpecialCard(selectedCard);
} else {
drawCards(current, 1);
cout << current.name << " 没有可出的牌,选择抽牌。" << endl;
currentPlayerIdx = (currentPlayerIdx + direction + players.size()) % players.size();
}
}
void playTurn() {
if (currentPlayerIdx == 0) {
Player& current = players[currentPlayerIdx];
Card& topCard = discardPile.back();
cout << "\n-----------------------------\n";
cout << "当前弃牌堆顶牌: ";
topCard.display();
cout << endl;
current.showHand();
int choice;
cout << current.name << " 请选择出牌编号 (输入 0 抽牌): ";
cin >> choice;
if (choice == 0) {
drawCards(current, 1);
currentPlayerIdx = (currentPlayerIdx + direction + players.size()) % players.size();
return;
}
if (choice < 1 || choice > current.hand.size()) {
cout << "无效输入,请重试。" << endl;
return; }
Card selectedCard = current.hand[choice - 1];
if (isValidMove(selectedCard, topCard)) {
current.hand.erase(current.hand.begin() + choice - 1);
discardPile.push_back(selectedCard);
if (current.hand.size() == 1) {
cout << current.name << " 大喊: UNO!!! (只剩一张牌了)" << endl;
}
if (current.hand.empty()) {
cout << "\n恭喜 " << current.name << " 获胜!游戏结束。" << endl;
exit(0);
}
handleSpecialCard(selectedCard);
} else {
cout << "这张牌不能出!(颜色或数字/功能不匹配)" << endl;
}
} else {
playAITurn();
}
}
void start() {
cout << "====== 欢迎来到 UNO 游戏 (1人 vs 3AI) ======" << endl;
dealCards();
while (true) {
playTurn();
}
}
};
int main() {
UnoGame game;
game.start();
return 0;
}
共 1 条回复
又来