21xrx.com
2024-12-23 00:48:30 Monday
登录
文章检索 我的文章 写文章
C++课程设计:扑克牌游戏
2023-07-05 21:29:43 深夜i     --     --
C++ 课程设计 扑克牌游戏 编程 面向对象

本文介绍了一种基于C++编写的扑克牌游戏。此游戏最多支持4个玩家,每人手中拥有5张牌。本文使用了面向对象的编程思想,将牌类、玩家类、游戏类等进行了各自的封装,并实现了洗牌、发牌、比较大小、输出胜者等功能。

扑克牌游戏是一种大众娱乐活动,包括德州扑克、斗地主等。本文所编写的扑克牌游戏仿照德州扑克规则,玩家间通过组合5张牌的牌型来分胜负。

首先,我们需要定义一种牌类,每张牌由花色和点数两个属性组成。定义如下:


class Card

public:

  string suit; //花色

  int point; //点数

;

接着,我们定义玩家类,每位玩家可以拥有多张牌,用vector容器存储。定义如下:


class Player

public:

  string name; //玩家名字

  vector<Card> cards; //手中的牌

;

然后,我们定义游戏类。游戏类中包含了洗牌、发牌、比较大小、输出胜者等功能。定义如下:


class Game {

public:

  vector<Card> deck; //一副牌

  vector<Player> players; //所有玩家

  void shuffle(); //洗牌

  void deal(); //发牌

  void compare(); //比较大小

  void printWinner(); //输出胜者

};

以上三个类中都包含了成员函数,这些函数均使用了封装思想,将牌类、玩家类、游戏类等进行了各自的封装。

洗牌函数中,我们使用了C++11的random库,实现了完整范围的洗牌,代码如下:


void Game::shuffle() {

  deck.clear();

  players.clear();

  for (int i = 1; i <= 13; i++) {

    deck.push_back( i );

    deck.push_back( i );

    deck.push_back( i );

    deck.push_back( i );

  }

  shuffle(deck.begin(), deck.end(), std::mt19937{ std::random_device{}() });

}

发牌函数中,我们使用了随机数生成器,为每位玩家发放5张牌,代码如下:


void Game::deal() {

  for (int i = 0; i < 5; i++) {

    for (auto& player : players) {

      int index = rand() % deck.size();

      player.cards.push_back(deck[index]);

      deck.erase(deck.begin() + index);

    }

  }

}

比较大小函数中,我们使用了STL的算法库,实现了对每个玩家手中5张牌进行牌型判断和大小比较,代码如下:


void Game::compare() {

  vector<tuple<Player, vector<Card>, string, int>> poker;

  for (auto& player : players) {

    vector<Card> cards = player.cards;

    sort(cards.begin(), cards.end(), [&](Card a, Card b) -> bool

      return a.point < b.point;

    );

    string type = ""; int score = 0;

    if (isStraightFlush(cards)) { type = "Straight Flush"; score = getScore(cards, 8); }

    else if (isFourOfAKind(cards)) { type = "Four Of A Kind"; score = getScore(cards, 7); }

    else if (isFullHouse(cards)) { type = "Full House"; score = getScore(cards, 6); }

    else if (isFlush(cards)) { type = "Flush"; score = getScore(cards, 5); }

    else if (isStraight(cards)) { type = "Straight"; score = getScore(cards, 4); }

    else if (isThreeOfAKind(cards)) { type = "Three Of A Kind"; score = getScore(cards, 3); }

    else if (isTwoPair(cards)) { type = "Two Pair"; score = getScore(cards, 2); }

    else if (isOnePair(cards)) { type = "One Pair"; score = getScore(cards, 1); }

    else { type = "High Card"; score = getScore(cards, 0); }

    poker.push_back( score );

  }

  sort(poker.begin(), poker.end(), [&](tuple<Player, vector<Card>, string, int> a, tuple<Player, vector<Card>, string, int> b) -> bool {

    if (get<2>(a) != get<2>(b)) return getTypeScore(get<2>(a)) > getTypeScore(get<2>(b));

    else return get<3>(a) > get<3>(b);

    });

  tuple<Player, vector<Card>, string, int> winner = poker[0];

  int cnt = count_if(poker.begin(), poker.end(), [&](tuple<Player, vector<Card>, string, int> a) -> bool {

    return get<2>(a) == get<2>(winner) && get<3>(a) == get<3>(winner);

    });

  if (cnt == 1) {

    cout << get<0>(winner).name << " wins with " << get<2>(winner) << endl;

  }

  else {

    vector<string> names;

    for (int i = 0; i < cnt; i++) {

      names.push_back(get<0>(poker[i]).name);

    }

    cout << "Tie between ";

    for (int i = 0; i < cnt; i++) {

      if (i == cnt - 1) cout << "and " << names[i] << " with " << get<2>(poker[i]) << endl;

      else cout << names[i] << ", ";

    }

  }

}

最后,我们完成了输出胜者的功能,其中需要处理“平局”的情况,代码如下:


void Game::printWinner() {

  compare();

}

本文中所编写的扑克牌游戏为大家了解C++面向对象思想提供了一个很好的样例。通过对牌类、玩家类、游戏类的封装,实现了对于不同尺度的程序需求的良好解耦。但是,这个游戏仍然可以继续优化,比如用更多现代化的C++特性来改进代码的健壮性、效率和可读性,或者增加GUI界面来提供用户友好的外在表现。所以,我相信这个游戏会有各种各样的优化空间,可以成为初学者多练习的良好试验田。

  
  

评论区

{{item['qq_nickname']}}
()
回复
回复