|
|
|
@@ -22,11 +22,19 @@ |
|
|
|
|
|
|
|
#include <iostream> |
|
|
|
#include <utility> |
|
|
|
//#include <random> |
|
|
|
#include <cstdlib> |
|
|
|
#include <ctime> |
|
|
|
|
|
|
|
#include "blackjack.h" |
|
|
|
|
|
|
|
Blackjack::Blackjack() { |
|
|
|
std::cout << "I'm your Blackjack dealer!" << std::endl; |
|
|
|
|
|
|
|
// TODO: better RNGs |
|
|
|
// https://codeforces.com/blog/entry/61587 |
|
|
|
srand((int)time(0)); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
Blackjack::~Blackjack() { |
|
|
|
@@ -34,6 +42,9 @@ Blackjack::~Blackjack() { |
|
|
|
} |
|
|
|
|
|
|
|
void Blackjack::deal(Player *player) { |
|
|
|
|
|
|
|
// let's start by assuming the player does not need to do anything |
|
|
|
setInputNeeded(false); |
|
|
|
|
|
|
|
switch(next_action) { |
|
|
|
// ------------------------------------------------------------------------- |
|
|
|
@@ -59,9 +70,9 @@ void Blackjack::deal(Player *player) { |
|
|
|
infinite_decks_card_number_for_arranged_ones = 0; |
|
|
|
n_hand++; |
|
|
|
|
|
|
|
// clear dealer's hand, create a new one and add it to the list |
|
|
|
hands.clear(); |
|
|
|
hands.push_back(std::move(Hand())); |
|
|
|
// clear dealer's hand |
|
|
|
hand.holeCardShown = false; |
|
|
|
hand.cards.clear(); |
|
|
|
|
|
|
|
// erase all the player's, create one, add and make it the current one |
|
|
|
player->hands.clear(); |
|
|
|
@@ -74,11 +85,12 @@ void Blackjack::deal(Player *player) { |
|
|
|
player->hasDoubled = 0; |
|
|
|
|
|
|
|
if (lastPass) { |
|
|
|
// TODO: send informative messages to the player |
|
|
|
// tell people we are shuffling |
|
|
|
// bjcall (blackjack.current_player->write (player, "shuffling")); |
|
|
|
|
|
|
|
// shuffle the cards |
|
|
|
// shuffle_shoe (); |
|
|
|
shuffle(); |
|
|
|
|
|
|
|
// TODO: reset card counting systems |
|
|
|
// burn as many cards as asked |
|
|
|
@@ -95,9 +107,8 @@ void Blackjack::deal(Player *player) { |
|
|
|
setNextAction(DealerAction::AskForBets); |
|
|
|
} |
|
|
|
|
|
|
|
// bjcall (blackjack.current_player->write (player, "new_hand")); |
|
|
|
// TODO: think! |
|
|
|
std::cout << "new_hand" << std::endl; |
|
|
|
return; |
|
|
|
|
|
|
|
break; |
|
|
|
|
|
|
|
@@ -110,50 +121,77 @@ void Blackjack::deal(Player *player) { |
|
|
|
// TODO: setter |
|
|
|
player->actionRequired = PlayerActionRequired::Bet; |
|
|
|
setInputNeeded(true); |
|
|
|
return; |
|
|
|
break; |
|
|
|
|
|
|
|
case DealerAction::DealPlayerFirstCard: |
|
|
|
// where's step 2? |
|
|
|
// where's step 2? <- probably that's the player's bet |
|
|
|
// step 3. deal the first card to each player |
|
|
|
player->n_hands++; // splits are counted as a single hand |
|
|
|
player->total_money_waged += player->currentHand->bet; |
|
|
|
|
|
|
|
Card card; |
|
|
|
card.tag = 7; |
|
|
|
player->currentHand->cards.push_back(card); |
|
|
|
std::cout << "card_player_first " << player->currentHand->cards.begin()->tag << std::endl; |
|
|
|
// bjcall (write_formatted_card (player, 0, "card_player_first", card)); |
|
|
|
playerFirstCard = dealCard(&(*player->currentHand)); |
|
|
|
std::cout << "card_player_first " << card[playerFirstCard].ascii() << std::endl; |
|
|
|
std::cout << "card_player_first " << card[playerFirstCard].text() << std::endl; |
|
|
|
std::cout << "card_player_first " << card[playerFirstCard].utf8() << std::endl; |
|
|
|
|
|
|
|
/* |
|
|
|
// step 4. show dealer's upcard |
|
|
|
card = deal_card_to_hand (blackjack.dealer_hand); |
|
|
|
bjcall (write_formatted_card (player, 0, "card_dealer_up", card)); |
|
|
|
if (stdout_opts.isatty) |
|
|
|
{ |
|
|
|
print_card_art (card); |
|
|
|
} |
|
|
|
upCard = dealCard(&hand); |
|
|
|
std::cout << "card_dealer_up " << card[upCard].text() << std::endl; |
|
|
|
|
|
|
|
// step 5. deal the second card to each player |
|
|
|
card = deal_card_to_hand (player->current_hand); |
|
|
|
bjcall (write_formatted_card (player, 0, "card_player_second", card)); |
|
|
|
if (stdout_opts.isatty) |
|
|
|
{ |
|
|
|
print_hand_art (player->current_hand); |
|
|
|
} |
|
|
|
playerSecondCard = dealCard(&(*player->currentHand)); |
|
|
|
std::cout << "card_player_second " << card[playerSecondCard].utf8() << std::endl; |
|
|
|
|
|
|
|
|
|
|
|
// step 6. deal the dealer's hole card |
|
|
|
holeCard = dealCard(&hand); |
|
|
|
std::cout << "card_dealer_hole" << std::endl; |
|
|
|
|
|
|
|
// TODO: ENHC |
|
|
|
blackjack.next_dealer_action = DEAL_DEALERS_HOLE_CARD; |
|
|
|
break; |
|
|
|
*/ |
|
|
|
// TODO: print (draw) the hand |
|
|
|
|
|
|
|
// step 7.a. if the upcard is an ace ask for insurance |
|
|
|
if (card[upCard].value == 11) { |
|
|
|
if (player->no_insurance == false && player->always_insure == false) { |
|
|
|
player->actionRequired = PlayerActionRequired::Insurance; |
|
|
|
setNextAction(DealerAction::AskForInsurance); |
|
|
|
setInputNeeded(true); |
|
|
|
return; |
|
|
|
|
|
|
|
} else if (player->always_insure) { |
|
|
|
player->currentHand->insured = true; |
|
|
|
// TODO: allow insurance for less than one half of the original bet |
|
|
|
player->current_result -= 0.5 * player->currentHand->bet; |
|
|
|
player->bankroll -= 0.5 * player->currentHand->bet; |
|
|
|
player->n_insured_hands++; |
|
|
|
|
|
|
|
player->actionRequired = PlayerActionRequired::None; |
|
|
|
setNextAction(DealerAction::CheckforBlackjacks); |
|
|
|
setInputNeeded(false); |
|
|
|
return; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
// step 7.b. if either the dealer or the player has a chance to have a blackjack, check |
|
|
|
if ((card[upCard].value == 10 || card[upCard].value == 11) || player->currentHand->total() == 21) { |
|
|
|
player->actionRequired = PlayerActionRequired::None; |
|
|
|
setNextAction(DealerAction::CheckforBlackjacks); |
|
|
|
setInputNeeded(false); |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
// step 7.c. ask the player to play |
|
|
|
player->actionRequired = PlayerActionRequired::Play; |
|
|
|
setNextAction(DealerAction::AskForPlay); |
|
|
|
setInputNeeded(true); |
|
|
|
return; |
|
|
|
break; |
|
|
|
|
|
|
|
|
|
|
|
/* |
|
|
|
case DealerAction::DealDealerHoleCard: |
|
|
|
break; |
|
|
|
case DealerAction::AskForInsurance: |
|
|
|
std::cout << "hola" << std::endl; |
|
|
|
break; |
|
|
|
|
|
|
|
/* |
|
|
|
case DealerAction::CheckforBlackjacks: |
|
|
|
break; |
|
|
|
case DealerAction::PayOrTakeInsuranceBets: |
|
|
|
@@ -261,3 +299,41 @@ int Blackjack::process(Player *player) { |
|
|
|
|
|
|
|
return 0; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void Blackjack::shuffle() { |
|
|
|
|
|
|
|
// for infinite decks there is no need to shuffle (how would one do it?) |
|
|
|
// we just pick a random card when we need to deal and that's it |
|
|
|
if (n_decks == -1) { |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
// TODO: shuffle shoe |
|
|
|
|
|
|
|
return; |
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
int Blackjack::dealCard(Hand *hand) { |
|
|
|
|
|
|
|
int dealt_tag = 0; |
|
|
|
|
|
|
|
if (n_decks == -1) { |
|
|
|
|
|
|
|
// TODO: arranged cards |
|
|
|
int random_integer = random(); |
|
|
|
dealt_tag = (random_integer % 32) + (random_integer % 16) + (random_integer % 4); |
|
|
|
|
|
|
|
} else { |
|
|
|
dealt_tag = 1; |
|
|
|
} |
|
|
|
|
|
|
|
if (hand != nullptr) { |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
return dealt_tag; |
|
|
|
} |