добавить случайный элемент набора в список и удалить его из исходного набора - PullRequest
0 голосов
/ 10 ноября 2019

У меня есть набор строк и я хочу добавить в список случайные элементы этого набора (например, раздача покерных карт разным игрокам)

Я пробовал следующее:

std::set<std::string> remaining_cards;
std::vector<std::set<std::string>> player_cards;

int random_number;
for (int i = 0; i < number_of_players; ++i) 
{
    random_number = 2;  // for simplicity let's assume the random number is always 2
    auto it = remaining_cards.cbegin();
    std::advance(it, random_number);
    player_cards.emplace_back(remaining_cards.cbegin(), it);  // get one element
    remaining_cards.erase(it);  // remove distributed card from deck
}

Почему я получаю одну и ту же карту для всех игроков, хотя я удаляю ту, которая была распределена в последней строке, из колоды с erase?

1 Ответ

1 голос
/ 10 ноября 2019

Я не уверен, почему вы используете std::set ... возможно, потому что он сортирует карты автоматически. Я бы использовал std::vector и сортировал вручную (std::sort).

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

Я бы предложил использовать инкапсуляцию и перемещать извлеченные карты вместо копирования перед удалением. Например,

#include <random>
#include <string>
#include <set>
#include <vector>
#include <numeric>

class Random {
private:
    std::default_random_engine generator{};
public:
    int operator()(int maxValue) { return generator() % maxValue; }
};

class Card {
private:
    std::string name{};
public:
    Card() : name{} {}
    Card& operator= (int i) {
        name = std::to_string(i);
        return *this;
    }
    friend bool operator<(Card const& lhs, Card const& rhs) {
        return lhs.name < rhs.name; // or some other sorting.
    }
};

class Player {
private: 
    std::set<Card> cards{};
public:
    void AddCard(Card&& card) noexcept {
        cards.emplace(std::move(card));
    }
};

int main() {
    //fill the deck
    std::vector<Card> deck(42); // instead of remaining cards... why would this be a set?
    std::iota(std::begin(deck), std::end(deck), 1); // fill 1 to 42

    Random random{};

    std::vector<Player> players(4);
    while (deck.size() > 0) { // distribute the whole deck.
        for (auto& player : players) {
            if (deck.empty()) break; // if cards in desck is not equaly dividable between players
            auto randIdx = random(deck.size());
            player.AddCard(std::move(deck[randIdx]));  // move one card
            deck.erase(std::next(std::begin(deck), randIdx));  // and remove it from deck
        }
    }
}
...