|
|
|
|
|
|
|
|
conf.set(&double_after_split, {"das", "double_after_split"}); |
|
|
conf.set(&double_after_split, {"das", "double_after_split"}); |
|
|
conf.set(&blackjack_pays, {"blackjack_pays"}); |
|
|
conf.set(&blackjack_pays, {"blackjack_pays"}); |
|
|
|
|
|
|
|
|
|
|
|
conf.set(&playerInfo.bankroll, {"bankroll"}); |
|
|
|
|
|
|
|
|
conf.set(&number_of_burnt_cards, {"number_of_burnt_cards", "n_burnt_cards", "burnt_cards"}); |
|
|
conf.set(&number_of_burnt_cards, {"number_of_burnt_cards", "n_burnt_cards", "burnt_cards"}); |
|
|
conf.set(&penetration, {"penetration"}); |
|
|
conf.set(&penetration, {"penetration"}); |
|
|
|
|
|
|
|
|
playerInfo.hands.push_back(std::move(PlayerHand())); |
|
|
playerInfo.hands.push_back(std::move(PlayerHand())); |
|
|
playerInfo.currentHand = playerInfo.hands.begin(); |
|
|
playerInfo.currentHand = playerInfo.hands.begin(); |
|
|
|
|
|
|
|
|
// state that the player did not win anything nor splitted nor doubled down |
|
|
|
|
|
|
|
|
// state that the player did not win anything nor split nor doubled down |
|
|
playerInfo.currentResult = 0; |
|
|
playerInfo.currentResult = 0; |
|
|
playerInfo.currentSplits = 0; |
|
|
playerInfo.currentSplits = 0; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
} |
|
|
lastPass = false; |
|
|
lastPass = false; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
info(Libreblackjack::Info::NewHand, n_hand, 1e3*playerInfo.bankroll); |
|
|
|
|
|
|
|
|
if (player->flat_bet) { |
|
|
if (player->flat_bet) { |
|
|
|
|
|
|
|
|
|
|
|
// TODO: check bankroll |
|
|
playerInfo.currentHand->bet = player->flat_bet; |
|
|
playerInfo.currentHand->bet = player->flat_bet; |
|
|
|
|
|
// take player's money |
|
|
|
|
|
playerInfo.bankroll -= playerInfo.currentHand->bet; |
|
|
|
|
|
if (playerInfo.bankroll < playerInfo.worstBankroll) { |
|
|
|
|
|
playerInfo.worstBankroll = playerInfo.bankroll; |
|
|
|
|
|
} |
|
|
|
|
|
playerInfo.totalMoneyWaged += playerInfo.currentHand->bet; |
|
|
|
|
|
|
|
|
player->actionRequired = Libreblackjack::PlayerActionRequired::None; |
|
|
player->actionRequired = Libreblackjack::PlayerActionRequired::None; |
|
|
nextAction = Libreblackjack::DealerAction::DealPlayerFirstCard; |
|
|
nextAction = Libreblackjack::DealerAction::DealPlayerFirstCard; |
|
|
|
|
|
|
|
|
} else { |
|
|
} else { |
|
|
|
|
|
|
|
|
player->actionRequired = Libreblackjack::PlayerActionRequired::Bet; |
|
|
player->actionRequired = Libreblackjack::PlayerActionRequired::Bet; |
|
|
nextAction = Libreblackjack::DealerAction::AskForBets; |
|
|
|
|
|
|
|
|
nextAction = Libreblackjack::DealerAction::None; |
|
|
|
|
|
|
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
info(Libreblackjack::Info::NewHand, n_hand, 1e3*playerInfo.bankroll); |
|
|
|
|
|
return; |
|
|
return; |
|
|
|
|
|
|
|
|
break; |
|
|
break; |
|
|
|
|
|
|
|
|
case Libreblackjack::DealerAction::AskForBets: |
|
|
|
|
|
break; |
|
|
|
|
|
|
|
|
|
|
|
// ------------------------------------------------------------------------- |
|
|
// ------------------------------------------------------------------------- |
|
|
case Libreblackjack::DealerAction::DealPlayerFirstCard: |
|
|
case Libreblackjack::DealerAction::DealPlayerFirstCard: |
|
|
// where's step 2? <- probably that's the player's bet |
|
|
// where's step 2? <- probably that's the player's bet |
|
|
// step 3. deal the first card to each player |
|
|
// step 3. deal the first card to each player |
|
|
playerInfo.n_hands++; // splits are counted as a single hand |
|
|
|
|
|
playerInfo.totalMoneyWaged += playerInfo.currentHand->bet; |
|
|
|
|
|
|
|
|
|
|
|
playerFirstCard = drawCard(&(*playerInfo.currentHand)); |
|
|
playerFirstCard = drawCard(&(*playerInfo.currentHand)); |
|
|
info(Libreblackjack::Info::CardPlayer, playerFirstCard); |
|
|
info(Libreblackjack::Info::CardPlayer, playerFirstCard); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (card[upCard].value == 11) { |
|
|
if (card[upCard].value == 11) { |
|
|
if (player->no_insurance == false && player->always_insure == false) { |
|
|
if (player->no_insurance == false && player->always_insure == false) { |
|
|
player->actionRequired = Libreblackjack::PlayerActionRequired::Insurance; |
|
|
player->actionRequired = Libreblackjack::PlayerActionRequired::Insurance; |
|
|
nextAction = Libreblackjack::DealerAction::AskForInsurance; |
|
|
|
|
|
|
|
|
nextAction = Libreblackjack::DealerAction::None; |
|
|
return; |
|
|
return; |
|
|
|
|
|
|
|
|
} else if (player->always_insure) { |
|
|
} else if (player->always_insure) { |
|
|
playerInfo.currentHand->insured = true; |
|
|
playerInfo.currentHand->insured = true; |
|
|
// TODO: allow insurance for less than one half of the original bet |
|
|
// TODO: allow insurance for less than one half of the original bet |
|
|
playerInfo.currentResult -= 0.5 * playerInfo.currentHand->bet; |
|
|
|
|
|
|
|
|
// if the guy (girl) wants to insure, we take his (her) money |
|
|
playerInfo.bankroll -= 0.5 * playerInfo.currentHand->bet; |
|
|
playerInfo.bankroll -= 0.5 * playerInfo.currentHand->bet; |
|
|
|
|
|
if (playerInfo.bankroll < playerInfo.worstBankroll) { |
|
|
|
|
|
playerInfo.worstBankroll = playerInfo.bankroll; |
|
|
|
|
|
} |
|
|
playerInfo.handsInsured++; |
|
|
playerInfo.handsInsured++; |
|
|
|
|
|
|
|
|
player->actionRequired = Libreblackjack::PlayerActionRequired::None; |
|
|
player->actionRequired = Libreblackjack::PlayerActionRequired::None; |
|
|
|
|
|
|
|
|
return; |
|
|
return; |
|
|
break; |
|
|
break; |
|
|
|
|
|
|
|
|
case Libreblackjack::DealerAction::AskForInsurance: |
|
|
|
|
|
return; |
|
|
|
|
|
break; |
|
|
|
|
|
|
|
|
|
|
|
case Libreblackjack::DealerAction::CheckforBlackjacks: |
|
|
case Libreblackjack::DealerAction::CheckforBlackjacks: |
|
|
// step 8. check if there are any blackjack |
|
|
// step 8. check if there are any blackjack |
|
|
playerBlackack = player->currentHand->blackjack(); |
|
|
|
|
|
|
|
|
playerBlackack = playerInfo.currentHand->blackjack(); |
|
|
if (hand.blackjack()) { |
|
|
if (hand.blackjack()) { |
|
|
info(Libreblackjack::Info::CardDealerRevealsHole, holeCard); |
|
|
info(Libreblackjack::Info::CardDealerRevealsHole, holeCard); |
|
|
info(Libreblackjack::Info::DealerBlackjack); |
|
|
info(Libreblackjack::Info::DealerBlackjack); |
|
|
playerInfo.blackjacksDealer++; |
|
|
playerInfo.blackjacksDealer++; |
|
|
|
|
|
|
|
|
if (player->currentHand->insured) { |
|
|
|
|
|
info(Libreblackjack::Info::PlayerWinsInsurance, 1e3*player->currentHand->bet); |
|
|
|
|
|
playerInfo.currentResult += player->currentHand->bet; |
|
|
|
|
|
playerInfo.bankroll += player->currentHand->bet; |
|
|
|
|
|
|
|
|
if (playerInfo.currentHand->insured) { |
|
|
|
|
|
|
|
|
|
|
|
// pay him (her) |
|
|
|
|
|
playerInfo.bankroll += (1.0 + 0.5) * playerInfo.currentHand->bet; |
|
|
|
|
|
playerInfo.currentResult += playerInfo.currentHand->bet; |
|
|
|
|
|
info(Libreblackjack::Info::PlayerWinsInsurance, 1e3*playerInfo.currentHand->bet); |
|
|
|
|
|
|
|
|
playerInfo.winsInsured++; |
|
|
playerInfo.winsInsured++; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
if (playerBlackack) { |
|
|
if (playerBlackack) { |
|
|
info(Libreblackjack::Info::PlayerBlackjackAlso); |
|
|
info(Libreblackjack::Info::PlayerBlackjackAlso); |
|
|
info(Libreblackjack::Info::PlayerPushes, 1e3*player->currentHand->bet); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// give him his (her her) money back |
|
|
|
|
|
playerInfo.bankroll += playerInfo.currentHand->bet; |
|
|
|
|
|
info(Libreblackjack::Info::PlayerPushes, 1e3*playerInfo.currentHand->bet); |
|
|
|
|
|
|
|
|
playerInfo.blackjacksPlayer++; |
|
|
playerInfo.blackjacksPlayer++; |
|
|
playerInfo.pushes++; |
|
|
playerInfo.pushes++; |
|
|
|
|
|
|
|
|
} else { |
|
|
} else { |
|
|
info(Libreblackjack::Info::PlayerLosses, 1e3*player->currentHand->bet); |
|
|
|
|
|
playerInfo.currentResult -= player->currentHand->bet; |
|
|
|
|
|
playerInfo.bankroll -= player->currentHand->bet; |
|
|
|
|
|
if (playerInfo.bankroll < playerInfo.worstBankroll) { |
|
|
|
|
|
playerInfo.worstBankroll = playerInfo.bankroll; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
playerInfo.currentResult -= playerInfo.currentHand->bet; |
|
|
|
|
|
info(Libreblackjack::Info::PlayerLosses, 1e3*playerInfo.currentHand->bet); |
|
|
|
|
|
|
|
|
playerInfo.losses++; |
|
|
playerInfo.losses++; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return; |
|
|
return; |
|
|
|
|
|
|
|
|
} else if (playerBlackack) { |
|
|
} else if (playerBlackack) { |
|
|
playerInfo.currentResult += blackjack_pays * player->currentHand->bet; |
|
|
|
|
|
playerInfo.bankroll += blackjack_pays * player->currentHand->bet; |
|
|
|
|
|
playerInfo.blackjacksPlayer++; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// pay him (her) |
|
|
|
|
|
playerInfo.bankroll += (1.0 + blackjack_pays) * playerInfo.currentHand->bet; |
|
|
|
|
|
playerInfo.currentResult += blackjack_pays * playerInfo.currentHand->bet; |
|
|
|
|
|
info(Libreblackjack::Info::PlayerWins, 1e3 * blackjack_pays*playerInfo.currentHand->bet); |
|
|
|
|
|
|
|
|
info(Libreblackjack::Info::PlayerWins, 1e3 * blackjack_pays*player->currentHand->bet); |
|
|
|
|
|
|
|
|
playerInfo.blackjacksPlayer++; |
|
|
playerInfo.wins++; |
|
|
playerInfo.wins++; |
|
|
playerInfo.winsBlackjack++; |
|
|
playerInfo.winsBlackjack++; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return; |
|
|
return; |
|
|
|
|
|
|
|
|
} else { |
|
|
} else { |
|
|
// only if the dealer had the chance to have a blackjack we say "no_blackjacks" |
|
|
|
|
|
|
|
|
// only if the dealer had the chance to have a blackjack we say "No blackjacks" |
|
|
if (card[upCard].value == 10 || card[upCard].value == 11) { |
|
|
if (card[upCard].value == 10 || card[upCard].value == 11) { |
|
|
info(Libreblackjack::Info::NoBlackjacks); |
|
|
info(Libreblackjack::Info::NoBlackjacks); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
case Libreblackjack::DealerAction::MoveOnToNextHand: |
|
|
case Libreblackjack::DealerAction::MoveOnToNextHand: |
|
|
// see if we finished all the player's hands |
|
|
// see if we finished all the player's hands |
|
|
if (++player->currentHand != player->hands.end()) { |
|
|
|
|
|
|
|
|
if (++playerInfo.currentHand != playerInfo.hands.end()) { |
|
|
unsigned int playerCard = drawCard(&(*playerInfo.currentHand)); |
|
|
unsigned int playerCard = drawCard(&(*playerInfo.currentHand)); |
|
|
info(Libreblackjack::Info::CardPlayer, playerCard, player->currentHand->id); |
|
|
|
|
|
|
|
|
info(Libreblackjack::Info::CardPlayer, playerCard, playerInfo.currentHand->id); |
|
|
|
|
|
|
|
|
if (std::abs(player->currentHand->value()) == 21) { |
|
|
|
|
|
|
|
|
if (std::abs(playerInfo.currentHand->value()) == 21) { |
|
|
player->actionRequired = Libreblackjack::PlayerActionRequired::None; |
|
|
player->actionRequired = Libreblackjack::PlayerActionRequired::None; |
|
|
nextAction = Libreblackjack::DealerAction::MoveOnToNextHand; |
|
|
nextAction = Libreblackjack::DealerAction::MoveOnToNextHand; |
|
|
return; |
|
|
return; |
|
|
} else { |
|
|
|
|
|
|
|
|
} else { |
|
|
player->actionRequired = Libreblackjack::PlayerActionRequired::Play; |
|
|
player->actionRequired = Libreblackjack::PlayerActionRequired::Play; |
|
|
nextAction = Libreblackjack::DealerAction::AskForPlay; |
|
|
nextAction = Libreblackjack::DealerAction::AskForPlay; |
|
|
return; |
|
|
return; |
|
|
|
|
|
|
|
|
} else { |
|
|
} else { |
|
|
// assume the player busted in all the hands |
|
|
// assume the player busted in all the hands |
|
|
bool bustedAllHands = true; |
|
|
bool bustedAllHands = true; |
|
|
for (auto playerHand : player->hands) { |
|
|
|
|
|
// if she did not bust, set false |
|
|
|
|
|
if (playerHand.busted() == false) { |
|
|
|
|
|
|
|
|
for (auto playerHand = playerInfo.hands.begin(); playerHand != playerInfo.hands.end(); playerHand++) { |
|
|
|
|
|
// if he (she) did not bust, set to false |
|
|
|
|
|
if (playerHand->busted() == false) { |
|
|
bustedAllHands = false; |
|
|
bustedAllHands = false; |
|
|
|
|
|
break; |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
dealerTotal = hand.value(); |
|
|
dealerTotal = hand.value(); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (hand.busted()) { |
|
|
if (hand.busted()) { |
|
|
info(Libreblackjack::Info::DealerBusts, dealerTotal); |
|
|
info(Libreblackjack::Info::DealerBusts, dealerTotal); |
|
|
playerInfo.bustsDealer++; |
|
|
playerInfo.bustsDealer++; |
|
|
for (auto playerHand : player->hands) { |
|
|
|
|
|
|
|
|
for (auto playerHand : playerInfo.hands) { |
|
|
if (playerHand.busted() == false) { |
|
|
if (playerHand.busted() == false) { |
|
|
info(Libreblackjack::Info::PlayerWins, 1e3*playerHand.bet); |
|
|
|
|
|
|
|
|
// pay him (her) |
|
|
|
|
|
playerInfo.bankroll += 2 * playerHand.bet; |
|
|
playerInfo.currentResult += playerHand.bet; |
|
|
playerInfo.currentResult += playerHand.bet; |
|
|
playerInfo.bankroll += playerHand.bet; |
|
|
|
|
|
|
|
|
info(Libreblackjack::Info::PlayerWins, 1e3*playerHand.bet); |
|
|
|
|
|
|
|
|
playerInfo.wins++; |
|
|
playerInfo.wins++; |
|
|
playerInfo.winsDoubled += playerHand.doubled; |
|
|
playerInfo.winsDoubled += playerHand.doubled; |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
} else { |
|
|
} else { |
|
|
for (auto playerHand : player->hands) { |
|
|
|
|
|
|
|
|
for (auto playerHand : playerInfo.hands) { |
|
|
if (playerHand.busted() == false) { // busted hands have already been solved |
|
|
if (playerHand.busted() == false) { // busted hands have already been solved |
|
|
playerTotal = std::abs(playerHand.value()); |
|
|
playerTotal = std::abs(playerHand.value()); |
|
|
|
|
|
|
|
|
if (dealerTotal > playerTotal) { |
|
|
if (dealerTotal > playerTotal) { |
|
|
|
|
|
|
|
|
|
|
|
playerInfo.currentResult -= playerHand.bet; |
|
|
info(Libreblackjack::Info::PlayerLosses, 1e3*playerHand.bet, playerTotal); |
|
|
info(Libreblackjack::Info::PlayerLosses, 1e3*playerHand.bet, playerTotal); |
|
|
playerInfo.bankroll -= playerHand.bet; |
|
|
|
|
|
if (playerInfo.bankroll < playerInfo.worstBankroll) { |
|
|
|
|
|
playerInfo.worstBankroll = playerInfo.bankroll; |
|
|
|
|
|
} |
|
|
|
|
|
playerInfo.losses++; |
|
|
playerInfo.losses++; |
|
|
|
|
|
|
|
|
} else if (dealerTotal == playerTotal) { |
|
|
} else if (dealerTotal == playerTotal) { |
|
|
|
|
|
|
|
|
|
|
|
// give him his (her her) money back |
|
|
|
|
|
playerInfo.bankroll += playerHand.bet; |
|
|
info(Libreblackjack::Info::PlayerPushes, 1e3*playerHand.bet); |
|
|
info(Libreblackjack::Info::PlayerPushes, 1e3*playerHand.bet); |
|
|
playerInfo.pushes++; |
|
|
playerInfo.pushes++; |
|
|
|
|
|
|
|
|
} else { |
|
|
} else { |
|
|
|
|
|
|
|
|
info(Libreblackjack::Info::PlayerWins, 1e3*playerHand.bet, playerTotal); |
|
|
|
|
|
|
|
|
// pay him (her) |
|
|
|
|
|
playerInfo.bankroll += 2 * playerHand.bet; |
|
|
playerInfo.currentResult += playerHand.bet; |
|
|
playerInfo.currentResult += playerHand.bet; |
|
|
playerInfo.bankroll += playerHand.bet; |
|
|
|
|
|
|
|
|
info(Libreblackjack::Info::PlayerWins, 1e3*playerHand.bet, playerTotal); |
|
|
playerInfo.wins++; |
|
|
playerInfo.wins++; |
|
|
|
|
|
|
|
|
if (playerHand.doubled) { |
|
|
|
|
|
playerInfo.winsDoubled++; |
|
|
|
|
|
} else { |
|
|
|
|
|
playerInfo.wins++; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
playerInfo.winsDoubled += playerHand.doubled; |
|
|
|
|
|
|
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
player->actionRequired = Libreblackjack::PlayerActionRequired::None; |
|
|
player->actionRequired = Libreblackjack::PlayerActionRequired::None; |
|
|
nextAction = Libreblackjack::DealerAction::StartNewHand; |
|
|
nextAction = Libreblackjack::DealerAction::StartNewHand; |
|
|
|
|
|
|
|
|
info(Libreblackjack::Info::Help); |
|
|
info(Libreblackjack::Info::Help); |
|
|
return 0; |
|
|
return 0; |
|
|
break; |
|
|
break; |
|
|
|
|
|
|
|
|
|
|
|
///ig+bankroll+name help |
|
|
|
|
|
///ig+bankroll+desc Ask for help |
|
|
|
|
|
///ig+bankroll+detail Ask for the bankroll. |
|
|
|
|
|
case Libreblackjack::PlayerActionTaken::Bankroll: |
|
|
|
|
|
info(Libreblackjack::Info::Bankroll, 1e3*playerInfo.bankroll); |
|
|
|
|
|
return 0; |
|
|
|
|
|
break; |
|
|
|
|
|
|
|
|
case Libreblackjack::PlayerActionTaken::None: |
|
|
case Libreblackjack::PlayerActionTaken::None: |
|
|
return 0; |
|
|
return 0; |
|
|
|
|
|
|
|
|
info(Libreblackjack::Info::BetInvalid, player->currentBet); |
|
|
info(Libreblackjack::Info::BetInvalid, player->currentBet); |
|
|
return 0; |
|
|
return 0; |
|
|
} else { |
|
|
} else { |
|
|
|
|
|
|
|
|
// ok, valid bet, copy the player's bet and use the local copy |
|
|
// ok, valid bet, copy the player's bet and use the local copy |
|
|
// (to prevent cheating players from changing the bet after dealing) |
|
|
// (to prevent cheating players from changing the bet after dealing) |
|
|
playerInfo.currentHand->bet = player->currentBet; |
|
|
playerInfo.currentHand->bet = player->currentBet; |
|
|
|
|
|
|
|
|
|
|
|
// and take his (her) money |
|
|
|
|
|
playerInfo.bankroll -= playerInfo.currentHand->bet; |
|
|
|
|
|
if (playerInfo.bankroll < playerInfo.worstBankroll) { |
|
|
|
|
|
playerInfo.worstBankroll = playerInfo.bankroll; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
nextAction = Libreblackjack::DealerAction::DealPlayerFirstCard; |
|
|
nextAction = Libreblackjack::DealerAction::DealPlayerFirstCard; |
|
|
return 1; |
|
|
return 1; |
|
|
|
|
|
|
|
|
} |
|
|
} |
|
|
break; |
|
|
break; |
|
|
|
|
|
|
|
|
case Libreblackjack::PlayerActionTaken::Insure: |
|
|
case Libreblackjack::PlayerActionTaken::Insure: |
|
|
// TODO: allow insurance for less than one half of the original bet |
|
|
// TODO: allow insurance for less than one half of the original bet |
|
|
playerInfo.currentHand->insured = true; |
|
|
|
|
|
playerInfo.currentResult -= 0.5 * playerInfo.currentHand->bet; |
|
|
|
|
|
|
|
|
// take his (her) money |
|
|
playerInfo.bankroll -= 0.5 * playerInfo.currentHand->bet; |
|
|
playerInfo.bankroll -= 0.5 * playerInfo.currentHand->bet; |
|
|
|
|
|
if (playerInfo.bankroll < playerInfo.worstBankroll) { |
|
|
|
|
|
playerInfo.worstBankroll = playerInfo.bankroll; |
|
|
|
|
|
} |
|
|
|
|
|
playerInfo.currentHand->insured = true; |
|
|
playerInfo.handsInsured++; |
|
|
playerInfo.handsInsured++; |
|
|
|
|
|
|
|
|
player->actionRequired = Libreblackjack::PlayerActionRequired::None; |
|
|
player->actionRequired = Libreblackjack::PlayerActionRequired::None; |
|
|
|
|
|
|
|
|
break; |
|
|
break; |
|
|
|
|
|
|
|
|
case Libreblackjack::PlayerActionTaken::DontInsure: |
|
|
case Libreblackjack::PlayerActionTaken::DontInsure: |
|
|
player->currentHand->insured = false; |
|
|
|
|
|
|
|
|
playerInfo.currentHand->insured = false; |
|
|
player->actionRequired = Libreblackjack::PlayerActionRequired::None; |
|
|
player->actionRequired = Libreblackjack::PlayerActionRequired::None; |
|
|
nextAction = Libreblackjack::DealerAction::CheckforBlackjacks; |
|
|
nextAction = Libreblackjack::DealerAction::CheckforBlackjacks; |
|
|
return 1; |
|
|
return 1; |
|
|
|
|
|
|
|
|
///ip+double+detail two cards. |
|
|
///ip+double+detail two cards. |
|
|
///ip+double+detail This command can be abbreviated as `d`. |
|
|
///ip+double+detail This command can be abbreviated as `d`. |
|
|
case Libreblackjack::PlayerActionTaken::Double: |
|
|
case Libreblackjack::PlayerActionTaken::Double: |
|
|
|
|
|
// TODO: rule to allow doubling only for 9, 10 or 11 |
|
|
if (playerInfo.currentHand->cards.size() == 2) { |
|
|
if (playerInfo.currentHand->cards.size() == 2) { |
|
|
|
|
|
|
|
|
// TODO: check bankroll |
|
|
// TODO: check bankroll |
|
|
|
|
|
// take his (her) money |
|
|
|
|
|
playerInfo.bankroll -= playerInfo.currentHand->bet; |
|
|
|
|
|
if (playerInfo.bankroll < playerInfo.worstBankroll) { |
|
|
|
|
|
playerInfo.worstBankroll = playerInfo.bankroll; |
|
|
|
|
|
} |
|
|
playerInfo.totalMoneyWaged += playerInfo.currentHand->bet; |
|
|
playerInfo.totalMoneyWaged += playerInfo.currentHand->bet; |
|
|
|
|
|
|
|
|
playerInfo.currentHand->bet *= 2; |
|
|
playerInfo.currentHand->bet *= 2; |
|
|
playerInfo.currentHand->doubled = true; |
|
|
playerInfo.currentHand->doubled = true; |
|
|
playerInfo.handsDoubled++; |
|
|
playerInfo.handsDoubled++; |
|
|
|
|
|
|
|
|
if (playerInfo.currentHand->busted()) { |
|
|
if (playerInfo.currentHand->busted()) { |
|
|
info(Libreblackjack::Info::PlayerLosses, 1e3*playerInfo.currentHand->bet, playerTotal); |
|
|
info(Libreblackjack::Info::PlayerLosses, 1e3*playerInfo.currentHand->bet, playerTotal); |
|
|
playerInfo.currentResult -= playerInfo.currentHand->bet; |
|
|
playerInfo.currentResult -= playerInfo.currentHand->bet; |
|
|
playerInfo.bankroll -= playerInfo.currentHand->bet; |
|
|
|
|
|
playerInfo.bustsPlayer++; |
|
|
playerInfo.bustsPlayer++; |
|
|
playerInfo.losses++; |
|
|
playerInfo.losses++; |
|
|
} |
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
player->actionRequired = Libreblackjack::PlayerActionRequired::None; |
|
|
player->actionRequired = Libreblackjack::PlayerActionRequired::None; |
|
|
nextAction = Libreblackjack::DealerAction::MoveOnToNextHand; |
|
|
nextAction = Libreblackjack::DealerAction::MoveOnToNextHand; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
} else { |
|
|
} else { |
|
|
|
|
|
|
|
|
std::cout << "cannot_double" << std::endl; |
|
|
|
|
|
|
|
|
info(Libreblackjack::Info::PlayerDoubleInvalid); |
|
|
return -1; |
|
|
return -1; |
|
|
|
|
|
|
|
|
} |
|
|
} |
|
|
break; |
|
|
break; |
|
|
|
|
|
|
|
|
///ip+split+name split |
|
|
///ip+split+name split |
|
|
///ip+split+desc Split the current hand |
|
|
|
|
|
|
|
|
///ip+split+desc Split the current hand. Adds an additional wage equal to the original one. |
|
|
///ip+split+detail |
|
|
///ip+split+detail |
|
|
///ip+split+detail This command can be abbreviated as `p` (for pair). |
|
|
///ip+split+detail This command can be abbreviated as `p` (for pair). |
|
|
case Libreblackjack::PlayerActionTaken::Split: |
|
|
case Libreblackjack::PlayerActionTaken::Split: |
|
|
|
|
|
|
|
|
// TODO: check bankroll to see if player can split |
|
|
// TODO: check bankroll to see if player can split |
|
|
if (playerInfo.currentSplits < 3 && playerInfo.currentHand->cards.size() == 2 && card[firstCard].value == card[secondCard].value) { |
|
|
if (playerInfo.currentSplits < 3 && playerInfo.currentHand->cards.size() == 2 && card[firstCard].value == card[secondCard].value) { |
|
|
|
|
|
|
|
|
|
|
|
// take player's money |
|
|
|
|
|
playerInfo.bankroll -= playerInfo.currentHand->bet; |
|
|
|
|
|
if (playerInfo.bankroll < playerInfo.worstBankroll) { |
|
|
|
|
|
playerInfo.worstBankroll = playerInfo.bankroll; |
|
|
|
|
|
} |
|
|
|
|
|
playerInfo.totalMoneyWaged += playerInfo.currentHand->bet; |
|
|
|
|
|
|
|
|
// tell the player the split is valid |
|
|
// tell the player the split is valid |
|
|
info(Libreblackjack::Info::PlayerSplitOk, playerInfo.currentHand->id); |
|
|
info(Libreblackjack::Info::PlayerSplitOk, playerInfo.currentHand->id); |
|
|
|
|
|
|
|
|
// mark that we split to put ids in the hands and to limi the number of spltis |
|
|
// mark that we split to put ids in the hands and to limi the number of spltis |
|
|
playerInfo.currentSplits++; |
|
|
playerInfo.currentSplits++; |
|
|
|
|
|
|
|
|
// the first hand is id=1, then we add one |
|
|
|
|
|
|
|
|
// the first hand is id=1, the rest have the id of the size of the list |
|
|
if (playerInfo.currentHand == playerInfo.hands.begin()) { |
|
|
if (playerInfo.currentHand == playerInfo.hands.begin()) { |
|
|
playerInfo.currentHand->id = 1; |
|
|
playerInfo.currentHand->id = 1; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
PlayerHand newHand; |
|
|
PlayerHand newHand; |
|
|
newHand.id = playerInfo.hands.size() + 1; |
|
|
newHand.id = playerInfo.hands.size() + 1; |
|
|
newHand.bet = playerInfo.currentHand->bet; |
|
|
newHand.bet = playerInfo.currentHand->bet; |
|
|
playerInfo.totalMoneyWaged += playerInfo.currentHand->bet; |
|
|
|
|
|
|
|
|
|
|
|
// remove second the card from the first hand |
|
|
// remove second the card from the first hand |
|
|
playerInfo.currentHand->cards.pop_back(); |
|
|
playerInfo.currentHand->cards.pop_back(); |
|
|
|
|
|
|
|
|
break; |
|
|
break; |
|
|
|
|
|
|
|
|
case Libreblackjack::PlayerActionTaken::Hit: |
|
|
case Libreblackjack::PlayerActionTaken::Hit: |
|
|
|
|
|
|
|
|
///ip+hit+name hit |
|
|
///ip+hit+name hit |
|
|
///ip+hit+desc Hit on the current hand |
|
|
///ip+hit+desc Hit on the current hand |
|
|
///ip+hit+detail |
|
|
///ip+hit+detail |
|
|
|
|
|
|
|
|
info(Libreblackjack::Info::CardPlayer, playerCard, playerInfo.currentHand->id); |
|
|
info(Libreblackjack::Info::CardPlayer, playerCard, playerInfo.currentHand->id); |
|
|
|
|
|
|
|
|
if (playerInfo.currentHand->busted()) { |
|
|
if (playerInfo.currentHand->busted()) { |
|
|
info(Libreblackjack::Info::PlayerLosses, 1e3*playerInfo.currentHand->bet); |
|
|
|
|
|
|
|
|
|
|
|
playerInfo.currentResult -= playerInfo.currentHand->bet; |
|
|
playerInfo.currentResult -= playerInfo.currentHand->bet; |
|
|
playerInfo.bankroll -= playerInfo.currentHand->bet; |
|
|
|
|
|
|
|
|
info(Libreblackjack::Info::PlayerLosses, 1e3*playerInfo.currentHand->bet); |
|
|
playerInfo.bustsPlayer++; |
|
|
playerInfo.bustsPlayer++; |
|
|
playerInfo.losses++; |
|
|
playerInfo.losses++; |
|
|
|
|
|
|
|
|
player->actionRequired = Libreblackjack::PlayerActionRequired::None; |
|
|
player->actionRequired = Libreblackjack::PlayerActionRequired::None; |
|
|
nextAction = Libreblackjack::DealerAction::MoveOnToNextHand; |
|
|
nextAction = Libreblackjack::DealerAction::MoveOnToNextHand; |
|
|
return 1; |
|
|
return 1; |
|
|
|
|
|
|
|
|
} else if (std::abs(playerInfo.currentHand->value()) == 21) { |
|
|
} else if (std::abs(playerInfo.currentHand->value()) == 21) { |
|
|
|
|
|
|
|
|
player->actionRequired = Libreblackjack::PlayerActionRequired::None; |
|
|
player->actionRequired = Libreblackjack::PlayerActionRequired::None; |
|
|
nextAction = Libreblackjack::DealerAction::MoveOnToNextHand; |
|
|
nextAction = Libreblackjack::DealerAction::MoveOnToNextHand; |
|
|
return 1; |
|
|
return 1; |
|
|
|
|
|
|
|
|
} else { |
|
|
} else { |
|
|
|
|
|
|
|
|
player->actionRequired = Libreblackjack::PlayerActionRequired::Play; |
|
|
player->actionRequired = Libreblackjack::PlayerActionRequired::Play; |
|
|
nextAction = Libreblackjack::DealerAction::AskForPlay; |
|
|
nextAction = Libreblackjack::DealerAction::AskForPlay; |
|
|
return 1; |
|
|
return 1; |
|
|
|
|
|
|
|
|
} |
|
|
} |
|
|
break; |
|
|
break; |
|
|
|
|
|
|
|
|
default: |
|
|
default: |
|
|
|
|
|
|
|
|
std::cout << "invalid_command" << std::endl; |
|
|
|
|
|
|
|
|
info(Libreblackjack::Info::CommandInvalid); |
|
|
return -1; |
|
|
return -1; |
|
|
|
|
|
|
|
|
break; |
|
|
break; |