Проблема в том, что srand
инициализируется одним и тем же значением при каждом запуске.Таким образом, одни и те же случайные значения генерируются в том же порядке.Вот почему все руки одинаковы.
srand
и rand
взяты из заголовка <cstdlib>
.
В C ++ 11 и выше лучше использовать функциииз заголовка <random>
.
Также C ++ предоставляет множество возможностей для использования объектно-ориентированного программирования и имеет обширную библиотеку структур данных и алгоритмов.Я бы предложил использовать std::vector
или std::array
вместо простых массивов.А также используйте std::shuffle
, чтобы получить случайный порядок карт.
#include <vector>
#include <string>
#include <random>
#include <algorithm>
#include <iostream>
#include <exception>
//////////////////////////////////////////////////////////////////////////////////////////
class Rank
{
std::string value;
Rank(std::string value) : value(value) {}
public:
static const std::vector< Rank >& get_all()
{
static std::vector< Rank > suits = { { "2" }, { "3" }, { "4" }, { "5" }, { "6" },
{ "7" }, { "8" }, { "9" }, { "10" }, { "J" },
{ "Q" }, { "K" }, { "A" } };
return suits;
}
const std::string& to_string() const { return value; }
};
//////////////////////////////////////////////////////////////////////////////////////////
class Suit
{
std::string value;
Suit(std::string value) : value(value) {}
public:
static const std::vector< Suit >& get_all()
{
static std::vector< Suit > ranks = {
{ "Clubs" }, { "Diamonds" }, { "Hearts" }, { "Spades" }
};
return ranks;
}
const std::string& to_string() const { return value; }
};
//////////////////////////////////////////////////////////////////////////////////////////
class Card
{
Suit suit;
Rank rank;
public:
Card(const Suit& suit, const Rank& rank) : suit(suit), rank(rank) {}
std::string to_string() const { return rank.to_string() + " of " + suit.to_string(); }
};
//////////////////////////////////////////////////////////////////////////////////////////
class Deck
{
std::vector< Card > cards;
public:
Deck()
{
const auto& ranks = Rank::get_all();
const auto& suits = Suit::get_all();
cards.reserve(ranks.size() * suits.size());
for (const Suit& s : suits)
for (const Rank& r : ranks)
cards.emplace_back(s, r);
}
void shuffle()
{
static std::random_device rd;
static std::mt19937 g(rd());
std::shuffle(cards.begin(), cards.end(), g);
}
std::size_t cards_count() const { return cards.size(); }
Card get_top_card()
{
if (cards_count() == 0)
throw std::logic_error("No more cards!");
const auto card = cards.back();
cards.pop_back();
return card;
}
};
//////////////////////////////////////////////////////////////////////////////////////////
int get_player_count()
{
std::cout << "Please enter the number of players:" << std::endl;
int player_count;
std::cin >> player_count;
return player_count;
}
//////////////////////////////////////////////////////////////////////////////////////////
void deal_cards(int player_count, int cards_to_deal, Deck& deck)
{
for (auto player_num = 1; player_num <= player_count; player_num++)
{
std::cout << "\n\nPlayer " << player_num << "'s hand :\n";
for (auto card_count = 0; card_count < cards_to_deal; card_count++)
{
if (deck.cards_count() == 0)
{
std::cout << "\n\nNo more cards to deal!" << std::endl;
return;
}
std::cout << deck.get_top_card().to_string() << ", ";
}
}
std::cout << std::endl;
}
//////////////////////////////////////////////////////////////////////////////////////////
int main()
{
Deck deck;
deck.shuffle();
const auto player_count = get_player_count();
const auto cards_to_deal = 5;
deal_cards(player_count, cards_to_deal, deck);
}
//////////////////////////////////////////////////////////////////////////////////////////