Как сделать так, чтобы функция раздавала отдельные карточные руки отдельным людям? - PullRequest
0 голосов
/ 03 января 2019

Для домашнего задания мне нужно создать программу, которая позволит вам играть в ирландскую карточную игру 25. Я могу сделать так, чтобы мой код протянул руку одному человеку, но если я попытаюсь иметь несколько человек, код выдаст идентичная рука другим людям. Как я могу дать разные, уникальные руки другим людям?

Я пытался использовать цикл, думая, что функция просто сбросит массив, но у него нет

/* Deals a random hand of cards */
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#define TRUE 1
#define FALSE 0
#define BOOL int
#define NUM_SUITS 4
#define NUM_RANKS 13

int DealCards(int i);

int main()
{
    int i;
    int NumOfPlayers;

    printf("Please Enter the Number Of Players: ");
    scanf("%d", &NumOfPlayers);

    for (i = 1; i <= NumOfPlayers; i++)
    {
        DealCards(i);
    }
}

int DealCards(int i)
{
    BOOL in_hand[NUM_SUITS][NUM_RANKS] = { FALSE };
    int        num_cards   = 5, rank, suit;
    const char rank_code[] = { '2', '3',  '4',  '5',  '6',  '7', '8',
                               '9', '10', '11', '12', '13', 'A' };
    const char suit_code[] = { 'C', 'D', 'H', 'S' };
    srand(time(NULL));
    printf("\n\nPlayer %d's hand :\n", i);
    while (num_cards > 0)
    {
        suit = rand() % NUM_SUITS;
        rank = rand() % NUM_RANKS;
        if (!in_hand[suit][rank])
        {
            in_hand[suit][rank] = TRUE;
            num_cards--;
            printf(" %cof%c ", rank_code[rank], suit_code[suit]);
        }
        printf("\n");
    }
    return 0;
}

Ответы [ 4 ]

0 голосов
/ 06 января 2019

Проблема в том, что 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);
}

//////////////////////////////////////////////////////////////////////////////////////////
0 голосов
/ 03 января 2019

Просто инициализируйте ваш srand (время (NULL)) перед тем, как раздавать карты

    #include <stdio.h>
    #include <stdlib.h>
    #include <time.h>
    #define  TRUE 1
    #define  FALSE 0
    #define  BOOL int
    #define NUM_SUITS 4
    #define NUM_RANKS 13
    int DealCards(int i);
    int main()
    {
    int i;
    int NumOfPlayers;

    printf("Please Enter the Number Of Players: ");
    scanf("%d",&NumOfPlayers);
   //here for example
     srand(time(NULL));
    for (i = 1; i <= NumOfPlayers; i++)
    {
        DealCards(i);
    }
    }
    int DealCards(int i) {
    BOOL in_hand[NUM_SUITS][NUM_RANKS] = { FALSE };
    int num_cards = 5, rank, suit;
    const char rank_code[] = { '2','3','4','5','6','7','8',
                              '9','10','11','12','13','A' };
    const char suit_code[] = { 'C','D','H','S' };
    printf("\n\nPlayer %d's hand :\n",i);
    while (num_cards > 0) {

        suit = rand() % NUM_SUITS;
        rank = rand() % NUM_RANKS;
        if (!in_hand[suit][rank])
        {  
            in_hand[suit][rank] = TRUE;
            num_cards--;
            printf(" %cof%c\n", rank_code[rank], suit_code[suit]);

        }
    }
    return 0;
    }
0 голосов
/ 03 января 2019

Ваш текущий метод - рисовать карты с заменой, а затем проверять, было ли это нарисовано. Это довольно простая и лучшая модель игры, чтобы shuffle колода.

Что вы должны сделать, это определить тип, который кодирует конкретную карту, заполнить коллекцию этого типа, с каждым значением используемой карты, перемешать колоду, а затем назначить карты из перемешанной колоды.

как эскиз

#include <vector>
#include <string>
#include <random>
#include <algorithm>
#include <iostream>

const std::vector<std::string> rank_code = { "2","3","4","5","6","7","8","9","10","Jack","Queen","King","Ace" };
const std::vector<std::string> suit_code = { "Clubs","Diamonds","Hearts","Spades" };

const int num_cards = 5;

struct Card
{
    Card(char s, char r) : suit(s), rank(r) {}
    char suit;
    char rank;
};

std::ostream & operator<< (std::ostream & os, const Card & c)
{
    return os << rank_code[c.rank] << " of " << suit_code[c.suit];
}

using Deck = std::vector<Card>;

Deck freshDeck()
{
    Deck result;
    for (std::size_t s = 0; s < suit_code.size(); ++s)
        for (std::size_t r = 0; r < rank_code.size(); ++r)
            result.emplace_back(s, r);
    return result;
}

void dealCards(int player, Deck & deck)
{
    std::string joiner;
    std::cout << std::endl << "Player " << player << "'s hand" << std::endl;
    for (int c = 0; c < num_cards; ++c)
    {
        std::cout << joiner << deck.back();
        deck.pop_back();
        joiner = ", ";
    }
    std::cout << std::endl;        
}

int main ()
{
    std::mt19937 gen{ std::random_device{}() };

    Deck deck = freshDeck();
    std::shuffle(deck.begin(), deck.end(), gen);

    std::cout << "Enter number of players" << std::endl;
    int num_players;
    std::cin >> num_players;

    for (int p = 1; p <= num_players; ++p)
    {
        dealCards(p, deck);
    }
}
0 голосов
/ 03 января 2019

Проблема в том, что вы вызываете функцию srand() перед тем, как раздать карту каждому игроку.Вы используете time(NULL) в качестве аргумента, поэтому начальное число меняется только каждую секунду, и игроки получают карты с одинаковым начальным значением.Вам нужно установить seed только один раз для каждого запуска программы.

...