gtheler il y a 5 ans
Parent
révision
e39fcb4b38
8 fichiers modifiés avec 122 ajouts et 122 suppressions
  1. +3
    -2
      blackjack.conf
  2. +4
    -12
      src/base.h
  3. +8
    -5
      src/blackjack.cpp
  4. +63
    -57
      src/cards.cpp
  5. +1
    -1
      src/conf.cpp
  6. +25
    -44
      src/tty.cpp
  7. +17
    -0
      src/tty.h
  8. +1
    -1
      src/version.cpp

+ 3
- 2
blackjack.conf Voir le fichier

@@ -1,4 +1,5 @@
flat_bet = 1
# flat_bet = 1
# max_bet = 2
arranged_cards = 2,4,11,1,7
arranged_cards = 9,8,13,12
delay = 0


+ 4
- 12
src/base.h Voir le fichier

@@ -86,6 +86,7 @@ enum class Info {
DealerBlackjack,
PlayerWinsInsurance,
PlayerBlackjackAlso,
PlayerNextHand,
PlayerPushes,
PlayerLosses,
PlayerBlackjack,
@@ -140,8 +141,8 @@ class Card {
std::string singleUTF8;
};

// TODO: static inside a class
extern Card card[52];
// TODO: class static? which class?
extern Card card[53];

class Hand {
public:
@@ -226,7 +227,7 @@ class Player {
unsigned int losses = 0;
// TODO: blackjack_pushes?
unsigned int flat_bet = 1;
unsigned int flat_bet = 0;
bool no_insurance = false;
bool always_insure = false;
@@ -260,16 +261,7 @@ class Dealer {
virtual void deal(Player *) = 0;
virtual unsigned int drawCard(Hand * = nullptr) = 0;
virtual int process(Player *) = 0;
/*
void setNextAction(DealerAction a) {
next_action = a;
}

void getNextAction(DealerAction a) {
next_action = a;
}
*/
bool finished(void) {
return done;
}

+ 8
- 5
src/blackjack.cpp Voir le fichier

@@ -36,7 +36,7 @@

#include "blackjack.h"

Blackjack::Blackjack(Configuration &conf) : rng(dev_random()), fiftyTwoCards(0, 51) {
Blackjack::Blackjack(Configuration &conf) : rng(dev_random()), fiftyTwoCards(1, 52) {

conf.set(&n_hands, {"n_hands", "hands"});
conf.set(&n_decks, {"decks", "n_decks"});
@@ -120,7 +120,6 @@ void Blackjack::deal(Player *player) {
// state that the player did not win anything nor splitted nor doubled down
player->current_result = 0;
player->currentSplits = 0;
// player->hasDoubled = 0;
if (lastPass) {
player->info(Info::Shuffle);
@@ -137,9 +136,12 @@ void Blackjack::deal(Player *player) {
if (player->flat_bet) {
player->currentHand->bet = player->flat_bet;
player->actionRequired = PlayerActionRequired::None;
nextAction = DealerAction::DealPlayerFirstCard;
} else {
player->actionRequired = PlayerActionRequired::Bet;
nextAction = DealerAction::AskForBets;

}

player->info(Info::NewHand, player->bankroll);
@@ -582,14 +584,15 @@ int Blackjack::process(Player *player) {

// deal a card to the first hand
playerCard = drawCard(&(*player->currentHand));
std::cout << "card_player_second " << card[playerCard].utf8() << std::endl;
player->info(Info::CardPlayer, playerCard);

// aces get dealt only one card
// also, if the player gets 21 then we move on to the next hand
if (card[*player->currentHand->cards.begin()].value == 11 || std::abs(player->currentHand->total()) == 21) {
if (++player->currentHand != player->hands.end()) {
player->info(Info::PlayerNextHand, (*player->currentHand).id);
playerCard = drawCard(&(*player->currentHand));
std::cout << "card_player_second " << card[playerCard].utf8() << std::endl;
player->info(Info::CardPlayer, playerCard);

// if the player got an ace or 21 again, we are done
if (card[*player->currentHand->cards.begin()].value == 11 || std::abs(player->currentHand->total()) == 21) {
@@ -684,7 +687,7 @@ unsigned int Blackjack::drawCard(Hand *hand) {
if (n_decks == -1) {
if (n_arranged_cards != 0 && i_arranged_cards < n_arranged_cards) {
// negative (or invalid) values are placeholder for random cards
if ((tag = arranged_cards[i_arranged_cards++]) < 0 || tag > 51) {
if ((tag = arranged_cards[i_arranged_cards++]) <= 0 || tag > 52) {
tag = fiftyTwoCards(rng);
}
} else {

+ 63
- 57
src/cards.cpp Voir le fichier

@@ -26,8 +26,13 @@ static std::string TJQK[4] = {"T", "J", "Q", "K"};
static std::string numbers[14] = {"", "ace", "deuce", "three", "four", "five", "six", "seven", "eight", "nine", "ten", "jack", "queen", "king"};

Card::Card(unsigned int tag) {
number = 1 + (tag % 13);
suit = static_cast<Suit>(tag/13);
if (tag <= 0 || tag > 52) {
return;
}
number = 1 + ((tag-1) % 13);
suit = static_cast<Suit>((tag-1)/13);
value = (number == 1) ? 11 : ((number > 10) ? 10 : number);
numberASCII = (number == 1) ? "A" : ((number < 11) ? std::to_string(number) : TJQK[number-10]);
@@ -60,61 +65,61 @@ Card::Card(unsigned int tag) {
// it would be hacky but hard to understand for humans
// UNIX rule of representation!
switch(tag) {
case 0: singleUTF8 = "🃑"; break;
case 1: singleUTF8 = "🃒"; break;
case 2: singleUTF8 = "🃓"; break;
case 3: singleUTF8 = "🃔"; break;
case 4: singleUTF8 = "🃕"; break;
case 5: singleUTF8 = "🃖"; break;
case 6: singleUTF8 = "🃗"; break;
case 7: singleUTF8 = "🃘"; break;
case 8: singleUTF8 = "🃙"; break;
case 9: singleUTF8 = "🃚"; break;
case 10: singleUTF8 = "🃛"; break;
case 11: singleUTF8 = "🃝"; break;
case 12: singleUTF8 = "🃞"; break;
case 1: singleUTF8 = "🃑"; break;
case 2: singleUTF8 = "🃒"; break;
case 3: singleUTF8 = "🃓"; break;
case 4: singleUTF8 = "🃔"; break;
case 5: singleUTF8 = "🃕"; break;
case 6: singleUTF8 = "🃖"; break;
case 7: singleUTF8 = "🃗"; break;
case 8: singleUTF8 = "🃘"; break;
case 9: singleUTF8 = "🃙"; break;
case 10: singleUTF8 = "🃚"; break;
case 11: singleUTF8 = "🃛"; break;
case 12: singleUTF8 = "🃝"; break;
case 13: singleUTF8 = "🃞"; break;

case 13: singleUTF8 = "🃁"; break;
case 14: singleUTF8 = "🃂"; break;
case 15: singleUTF8 = "🃃"; break;
case 16: singleUTF8 = "🃄"; break;
case 17: singleUTF8 = "🃅"; break;
case 18: singleUTF8 = "🃆"; break;
case 19: singleUTF8 = "🃇"; break;
case 20: singleUTF8 = "🃈"; break;
case 21: singleUTF8 = "🃉"; break;
case 22: singleUTF8 = "🃊"; break;
case 23: singleUTF8 = "🃋"; break;
case 24: singleUTF8 = "🃍"; break;
case 14: singleUTF8 = "🃁"; break;
case 15: singleUTF8 = "🃂"; break;
case 16: singleUTF8 = "🃃"; break;
case 17: singleUTF8 = "🃄"; break;
case 18: singleUTF8 = "🃅"; break;
case 19: singleUTF8 = "🃆"; break;
case 20: singleUTF8 = "🃇"; break;
case 21: singleUTF8 = "🃈"; break;
case 22: singleUTF8 = "🃉"; break;
case 23: singleUTF8 = "🃊"; break;
case 24: singleUTF8 = "🃋"; break;
case 25: singleUTF8 = "🃍"; break;
case 26: singleUTF8 = "🃍"; break;
case 26: singleUTF8 = "🂱"; break;
case 27: singleUTF8 = "🂲"; break;
case 28: singleUTF8 = "🂳"; break;
case 29: singleUTF8 = "🂴"; break;
case 30: singleUTF8 = "🂵"; break;
case 31: singleUTF8 = "🂶"; break;
case 32: singleUTF8 = "🂷"; break;
case 33: singleUTF8 = "🂸"; break;
case 34: singleUTF8 = "🂹"; break;
case 35: singleUTF8 = "🂺"; break;
case 36: singleUTF8 = "🂻"; break;
case 37: singleUTF8 = "🂽"; break;
case 38: singleUTF8 = "🂾"; break;
case 27: singleUTF8 = "🂱"; break;
case 28: singleUTF8 = "🂲"; break;
case 29: singleUTF8 = "🂳"; break;
case 30: singleUTF8 = "🂴"; break;
case 31: singleUTF8 = "🂵"; break;
case 32: singleUTF8 = "🂶"; break;
case 33: singleUTF8 = "🂷"; break;
case 34: singleUTF8 = "🂸"; break;
case 35: singleUTF8 = "🂹"; break;
case 36: singleUTF8 = "🂺"; break;
case 37: singleUTF8 = "🂻"; break;
case 38: singleUTF8 = "🂽"; break;
case 39: singleUTF8 = "🂾"; break;
case 39: singleUTF8 = "🂡"; break;
case 40: singleUTF8 = "🂢"; break;
case 41: singleUTF8 = "🂣"; break;
case 42: singleUTF8 = "🂤"; break;
case 43: singleUTF8 = "🂥"; break;
case 44: singleUTF8 = "🂦"; break;
case 45: singleUTF8 = "🂧"; break;
case 46: singleUTF8 = "🂨"; break;
case 47: singleUTF8 = "🂩"; break;
case 48: singleUTF8 = "🂪"; break;
case 49: singleUTF8 = "🂫"; break;
case 50: singleUTF8 = "🂭"; break;
case 51: singleUTF8 = "🂮"; break;
case 40: singleUTF8 = "🂡"; break;
case 41: singleUTF8 = "🂢"; break;
case 42: singleUTF8 = "🂣"; break;
case 43: singleUTF8 = "🂤"; break;
case 44: singleUTF8 = "🂥"; break;
case 45: singleUTF8 = "🂦"; break;
case 46: singleUTF8 = "🂧"; break;
case 47: singleUTF8 = "🂨"; break;
case 48: singleUTF8 = "🂩"; break;
case 49: singleUTF8 = "🂪"; break;
case 50: singleUTF8 = "🂫"; break;
case 51: singleUTF8 = "🂭"; break;
case 52: singleUTF8 = "🂮"; break;
}
};

@@ -122,7 +127,8 @@ std::string Card::text() {
return numbers[number] + " of " + suitName;
}

Card card[52] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38,
39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51};
Card card[53] = { 0,
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26,
27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39,
40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52};

+ 1
- 1
src/conf.cpp Voir le fichier

@@ -98,7 +98,7 @@ Configuration::Configuration(int argc, char **argv) {
if (optarg != NULL) {
data["flat_bet"] = optarg;
} else {
data["flat_bet"] = "1";
data["flat_bet"] = "yes";
}
break;
case '?':

+ 25
- 44
src/tty.cpp Voir le fichier

@@ -25,11 +25,6 @@
#include <thread>
#include <chrono>

#include <algorithm>
#include <functional>
#include <cctype>
#include <locale>

#ifdef HAVE_LIBREADLINE
#include <readline/readline.h>
#include <readline/history.h>
@@ -43,27 +38,6 @@
std::vector<std::string> commands;


// trim from start (in place)
static inline void ltrim(std::string &s) {
s.erase(s.begin(), std::find_if(s.begin(), s.end(), [](unsigned char ch) {
return !std::isspace(ch);
}));
}

// trim from end (in place)
static inline void rtrim(std::string &s) {
s.erase(std::find_if(s.rbegin(), s.rend(), [](unsigned char ch) {
return !std::isspace(ch);
}).base(), s.end());
}

// trim from both ends (in place)
static inline void trim(std::string &s) {
ltrim(s);
rtrim(s);
}


Tty::Tty(Configuration &conf) {
Libreblackjack::shortversion();
@@ -71,6 +45,7 @@ Tty::Tty(Configuration &conf) {

conf.set(&flat_bet, {"flat_bet", "flatbet"});
conf.set(&no_insurance, {"no_insurance", "dont_insure"});
conf.set(&delay, {"delay"});

if (commands.size() == 0) {
// commands.push_back("help");
@@ -105,7 +80,7 @@ Tty::Tty(Configuration &conf) {
return;
}

void Tty::info(Info msg, int intData) {
void Tty::info(Info msg, int p) {
std::string s;
// TODO: choose utf8 or other representation
@@ -113,12 +88,12 @@ void Tty::info(Info msg, int intData) {
switch (msg) {

case Info::InvalidBet:
if (intData < 0) {
if (p < 0) {
// s = "bet_negative";
s = "Your bet is negative (" + std::to_string(intData) + ")";
} else if (intData > 0) {
s = "Your bet is negative (" + std::to_string(p) + ")";
} else if (p > 0) {
// s = "bet_maximum";
s = "Your bet is larger than the maximum allowed (" + std::to_string(intData) + ")";
s = "Your bet is larger than the maximum allowed (" + std::to_string(p) + ")";
} else {
// s = "bet_zero";
s = "Your bet is zero";
@@ -128,7 +103,7 @@ void Tty::info(Info msg, int intData) {
case Info::NewHand:
// s = "new_hand";
std::cout << std::endl;
s = "Starting new hand, bankroll " + std::to_string(intData);
s = "Starting new hand, bankroll " + std::to_string(p);
dealerHand.cards.clear();
break;
@@ -141,41 +116,41 @@ void Tty::info(Info msg, int intData) {
switch (currentHand->cards.size()) {
case 1:
// s = "card_player_first";
s = "Player's first card is " + card[intData].utf8();
s = "Player's first card is " + card[p].utf8();
break;
case 2:
// s = "card_player_second";
s = "Player's second card is " + card[intData].utf8();
s = "Player's second card is " + card[p].utf8();
break;
default:
// s = "card_player";
s = "Player's card is " + card[intData].utf8();
s = "Player's card is " + card[p].utf8();
break;
}
break;
case Info::CardDealer:
if (intData != -1) {
if (p != -1) {
switch (dealerHand.cards.size()) {
case 0:
// s = "card_dealer_up";
s = "Dealer's up card is " + card[intData].utf8();
s = "Dealer's up card is " + card[p].utf8();
break;
default:
// s = "card_dealer";
s = "Dealer's card is " + card[intData].utf8();
s = "Dealer's card is " + card[p].utf8();
break;
}
} else {
s = "Dealer's hole card is dealt";
}
dealerHand.cards.push_back(intData);
dealerHand.cards.push_back(p);
break;
case Info::CardDealerRevealsHole:
// s = "card_dealer_hole";
s = "Dealer's hole card was " + card[intData].utf8();
*(++(dealerHand.cards.begin())) = intData;
s = "Dealer's hole card was " + card[p].utf8();
*(++(dealerHand.cards.begin())) = p;
// renderTable();
break;
@@ -194,6 +169,12 @@ void Tty::info(Info msg, int intData) {
s = "Player also has Blackjack";
renderTable();
break;

case Info::PlayerNextHand:
// s = "player_pushes";
s = "Playing next hand #" + std::to_string(p);
renderTable();
break;
case Info::PlayerPushes:
// s = "player_pushes";
@@ -213,7 +194,7 @@ void Tty::info(Info msg, int intData) {
break;
case Info::PlayerWins:
// s = "player_wins";
s = "Player wins " + std::to_string(intData);
s = "Player wins " + std::to_string(p);
renderTable();
break;
@@ -389,12 +370,12 @@ void Tty::renderTable(void) {

std::cout << " -- Dealer's hand: --------" << std::endl;
renderHand(&dealerHand);
std::cout << " Total: " << dealerHand.total() << std::endl;
std::cout << " Total: " << ((dealerHand.total() < 0)?"soft ":"") << std::abs(dealerHand.total()) << std::endl;

std::cout << " -- Player's hand --------" << std::endl;
for (auto hand : hands) {
renderHand(&hand);
std::cout << " Total: " << hand.total() << std::endl;
std::cout << " Total: " << ((hand.total() < 0)?"soft ":"") << std::abs(hand.total()) << std::endl;
}

return;

+ 17
- 0
src/tty.h Voir le fichier

@@ -22,6 +22,11 @@

#ifndef TTY_H
#define TTY_H
#include <algorithm>
#include <functional>
#include <cctype>
#include <locale>

#include "blackjack.h"

extern std::vector<std::string> commands;
@@ -66,6 +71,18 @@ class Tty : public Player {
std::string cyan;
std::string white;
std::string reset;

inline void ltrim(std::string &s) {
s.erase(s.begin(), std::find_if(s.begin(), s.end(), [](unsigned char ch) { return !std::isspace(ch); }));
};

inline void rtrim(std::string &s) {
s.erase(std::find_if(s.rbegin(), s.rend(), [](unsigned char ch) { return !std::isspace(ch); }).base(), s.end());
};

inline void trim(std::string &s) { ltrim(s); rtrim(s); };
};

#endif

+ 1
- 1
src/version.cpp Voir le fichier

@@ -31,7 +31,7 @@ void shortversion(void) {

std::cout << "LibreBlackjack ";
#ifdef LIBREBLACKJACK_VCS_BRANCH
std::cout << LIBREBLACKJACK_VCS_VERSION << ((LIBREBLACKJACK_VCS_CLEAN == 0) ? "" : "+Δ") << ((strcmp(LIBREBLACKJACK_VCS_BRANCH, "master") == 0) ? LIBREBLACKJACK_VCS_BRANCH : "") << std::endl;
std::cout << LIBREBLACKJACK_VCS_VERSION << ((LIBREBLACKJACK_VCS_CLEAN == 0) ? "" : "+Δ") << ((strcmp(LIBREBLACKJACK_VCS_BRANCH, "master")) ? LIBREBLACKJACK_VCS_BRANCH : "") << std::endl;
#else
std::cout << PACKAGE_VERSION << std::endl;
#endif

Chargement…
Annuler
Enregistrer