diff --git a/src/game/CardTile.cpp b/src/game/CardTile.cpp new file mode 100644 index 0000000..588fa0c --- /dev/null +++ b/src/game/CardTile.cpp @@ -0,0 +1,100 @@ +/** + * @file CardTile.cpp + * + * @author Yuzhe Guo + * @date 2025.11.15 + */ +#include "CardTile.h" +#include +#include + +#include "../common/utils.h" + +namespace UNO::GAME { + CardTile::CardTile() = default; + + template + void CardTile::pushFront(T... t) + { + cards_.emplace_front(t...); + } + + template + void CardTile::pushBack(T... t) + { + cards_.emplace_back(t...); + } + + Card CardTile::popFront() + { + const Card card = cards_.front(); + cards_.pop_front(); + return card; + } + + Card CardTile::popBack() + { + const Card card = cards_.back(); + cards_.pop_back(); + return card; + } + + bool CardTile::isEmpty() const + { + return cards_.empty(); + } + + void CardTile::shuffle() + { + std::random_device rd; + std::mt19937 gen(rd()); + std::ranges::shuffle(cards_, COMMON::Utils::getInstance()->getRandom().getGenerator()); + } + + void CardTile::clear() + { + cards_.clear(); + } + + DiscardPile::DiscardPile() = default; + + void DiscardPile::add(Card card) + { + this->pushFront(card); + } + + Deck::Deck() = default; + + void Deck::init() + { + for (const auto color : AllColors) { + for (const auto type : AllTypes) { + if (color != CardColor::WILD && type != CardType::WILD && type != CardType::WILDDRAWFOUR) { + this->pushBack(color, type); + } + } + } + for (int i = 0; i < 4; i++) { + this->pushBack(CardColor::WILD, CardType::WILD); + this->pushBack(CardColor::WILD, CardType::WILDDRAWFOUR); + } + this->shuffle(); + } + + Card Deck::draw() + { + if (this->isEmpty()) { + this->init(); + } + return this->popFront(); + } + + std::vector Deck::draw(const size_t n) + { + std::vector draw_card; + for (size_t i = 0; i < n; i++) { + draw_card.push_back(this->draw()); + } + return draw_card; + } +} // namespace UNO::GAME diff --git a/src/game/CardTile.h b/src/game/CardTile.h new file mode 100644 index 0000000..94c9725 --- /dev/null +++ b/src/game/CardTile.h @@ -0,0 +1,110 @@ +/** + * @file CardTile.h + * + * 牌堆 + * + * @author Yuzhe Guo + * @date 2025.11.15 + */ +#ifndef UNO_GAME_CARDTILE_H +#define UNO_GAME_CARDTILE_H +#include +#include + +#include "Card.h" + +namespace UNO::GAME { + /** + * @brief 牌堆 + */ + class CardTile { + private: + std::deque cards_; + + protected: + /** + * 向牌堆前加入卡牌 + * @param t 要加入的卡牌 + */ + template + void pushFront(T... t); + + /** + * 向牌堆后加入卡牌 + * @param t 要加入的卡牌 + */ + template + void pushBack(T... t); + + /** + * 将牌堆中第一张牌删除 + * @return 删除的牌 + */ + Card popFront(); + + /** + * 将牌堆中最后一张牌删除 + * @return 删除的牌 + */ + Card popBack(); + + /** + * @return 牌堆是否为空 + */ + [[nodiscard]] bool isEmpty() const; + + /** + * 将牌堆中的卡牌随机洗混 + */ + void shuffle(); + + /** + * 清空牌堆 + */ + void clear(); + + public: + CardTile(); + }; + + /** + * @brief 弃牌堆 + */ + class DiscardPile : CardTile { + public: + DiscardPile(); + + /** + * 向弃牌堆中添加 @param card 卡牌 + */ + void add(Card card); + }; + + /** + * @brief 起牌堆 + */ + class Deck : CardTile { + public: + Deck(); + + /** + * 初始化牌堆 + */ + void init(); + + /** + * 摸一张牌 + * @return 摸到的牌 + */ + Card draw(); + + /** + * 摸 n 张牌 + * @param n 摸牌的张数 + * @return 摸到的牌 + */ + std::vector draw(size_t n); + }; +} + +#endif //UNO_GAME_CARDTILE_H