2017-02-17 28 views
2

Мне пришлось программировать игру blacjack для класса. Кажется, что все работает нормально, за исключением перетасовки колоды карт при инициализации игры (рисование первых двух карт). Все с этого момента кажется случайным.Случайный случайный случайный случай, похоже, дает тот же результат, но только в первых двух случаях. Как мне избежать этого?

Я предоставлю все необходимые коды. RandomWithLimits-функция Я использую:

int randomWithLimits(int upperLimit, int lowerLimit) 
{ 
    return (std::rand() % (upperLimit - lowerLimit + 1) + lowerLimit); 
} 

достаточно просто, она высевают в основном, как это:

int main() 
{ 
    srand(time(nullptr)); 
    Blackjack bj; 
    bool play = true; 
    while (play == true) play = bj.playGame(); 
    return 0; 
} 

сама блэкджек функция довольно долго, но вот та часть, которая Безразлично» т будет работать должным образом (первый тур):

bool Blackjack::playGame() { 
    CardDeck deck = CardDeck(); 
    std::cout << "The dealer shuffles the deck\n"; 
    deck.shuffle(); 
    drawInitialCards(); 
    std::cout << "\nYour hand is currently " << playerHand << "."; 


    {...} 


    std::string cont; 
    std::cout << "\n\n\nDo you wish to play another round? (y/n) "; 
    std::cin >> cont; 
    while (cont != "y" && cont != "n") { 
     std::cout << "\nNot a valid choice, choose again: (y/n) "; 
     std::cin >> cont; 
    } 
    if (cont == "y") return true; 
    else return false; 
} 

CardDeck класс с этой функцией

CardDeck::CardDeck() { 
    int count = 0; 
    for (int s = CLUBS; s <= SPADES; s++) { 
     for (int r = TWO; r <= ACE; r++) { 
      Card card(static_cast<Suit>(s), static_cast<Rank>(r)); 
      cards.push_back(card); 
     } 
    } 
    currentCardIndex = 0; 
} 

, который создает колоду. currentCardIndex отслеживает, сколько карт было нарисовано, s - это перечисляемый тип Suit, а r - тип перечисления, называемый Rank. Кажется, это работает нормально.

Он использует эту функцию воспроизведения в случайном порядке,

void CardDeck::shuffle() { 
    int count = 0; 
    while (count < 100) { 
     int a = randomWithLimits(51, 0); 
     int b = randomWithLimits(51, 0); 
     swap(a, b); 
     count++; 
    } 
} 

который использует randomWithLimits-функцию от ранее и этот своп-функции

void CardDeck::swap(int a, int b) { 
    Card temp = cards[a]; 
    cards[a] = cards[b]; 
    cards[b] = temp; 
} 

Это не большая проблема, но она по-прежнему беспокоит меня. Всякий раз, когда я скомпилировать и запустить функцию в первый раз, первый выход всегда:

The dealer shuffles the deck 

You drew a Two of Clubs. 
The dealer drew a card. 

You drew a Four of Clubs. 
The dealer drew a card. 
Your hand is currently 6. 

С тех пор каждая карта, кажется случайным. Функция ничьих карт:

Card CardDeck::drawCard() { 
    currentCardIndex++; 
    return cards[currentCardIndex - 1]; 
} 

drawInitialCards-функция:

void Blackjack::drawInitialCards() { 
    Card card = deck.drawCard(); 
    std::cout << "\nYou drew a " << card.toString() << "."; 
    playerHand = getPlayerCardValue(&card); 
    card = deck.drawCard(); 
    std::cout << "\nThe dealer drew a card."; 
    dealerHand = getDealerCardValue(&card, dealerHand); 
    card = deck.drawCard(); 
    std::cout << "\n\nYou drew a " << card.toString() << "."; 
    playerHand += getPlayerCardValue(&card); 
    card = deck.drawCard(); 
    std::cout << "\nThe dealer drew a card."; 
    dealerHand += getDealerCardValue(&card, dealerHand); 
} 

Я пытался возиться с сколько раз перетасовать-функцию свопы карты, поместить ли я семя в основном или playGame-функция и т. д., но я всегда получаю этот результат. Любая помощь?

+2

Мне кажется, что ваша функция перетасовки - совсем неделя ... попробуйте реализацию std: http://www.cplusplus.com/reference/algorithm/random_shuffle/ – Kupto

+0

Я знаю, что она довольно слабая, но она работает при тестировании только функция перетасовки. После тестирования это немного похоже на то, что drawInitialCards-функция черпает из другой колоды вообще (которая всегда одна и всегда возвращает даже пронумерованные карты Клубов, насколько я проверял). – pelsbust

+0

Как выглядит реализация getPlayerCardValue() '? Используете ли вы его где-нибудь еще, кроме функции 'Blackjack :: drawInitialCards()'? – Kupto

ответ

2

Обнаружили ошибку. Это

bool Blackjack::playGame() { 
    CardDeck deck = CardDeck(); 

просто должны быть написаны

bool Blackjack::playGame() { 
    deck = CardDeck(); 

кажется, что я создал новую колоду, как я думал.

+1

Хорошо для вас, в следующий раз попробуйте отладки до запроса на SO;) – Kupto

2

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

Одна вещь, которую ваш текущий код не гарантирует, заключается в том, что каждая карта будет удалена в случайном порядке. Вместо того, чтобы делать это 100 раз случайной паре, попробуйте поменять каждую карту случайным в петле от карточки 0 до карточки 51.

void CardDeck::shuffle() { 

    for(int a = 0; a < 52; a++) { 
     int b = randomWithLimits(51, 0); 
     swap(a, b); 
    } 
} 

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

+0

Спасибо, что кажется лучше да. Это была не ошибка, но ваш код все еще лучше LOL – pelsbust

+1

+1, но Fisher-Yates будет лучшим решением ... https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle – Kupto

+0

Fisher-Yates - это более общее решение, но вышеупомянутое решение не должно приводить к предвзятым результатам. Он ударяет по каждому месту один раз и заменяет его любой возможной картой в колоде. Этот метод может быть быстрее, чем воссоздать полную колоду. –

 Смежные вопросы

  • Нет связанных вопросов^_^