소스 검색

internal with default and basic strategy

master
gtheler 5 년 전
부모
커밋
61e78fd573
16개의 변경된 파일563개의 추가작업 그리고 171개의 파일을 삭제
  1. +1
    -0
      blackjack.conf
  2. +0
    -41
      bs.txt
  3. +10
    -0
      players/20-basic-strategy/.gitignore
  4. +17
    -0
      players/20-basic-strategy/hard-stand.txt
  5. +5
    -0
      players/20-basic-strategy/options.conf
  6. +10
    -0
      players/20-basic-strategy/pair-no.txt
  7. +385
    -0
      players/20-basic-strategy/run.sh
  8. +10
    -0
      players/20-basic-strategy/soft-stand.txt
  9. +5
    -1
      src/base.h
  10. +7
    -2
      src/blackjack.cpp
  11. +0
    -3
      src/conf.cpp
  12. +2
    -2
      src/conf.h
  13. +92
    -7
      src/internal.cpp
  14. +1
    -0
      src/internal.h
  15. +1
    -1
      src/main.cpp
  16. +17
    -114
      src/report.cpp

+ 1
- 0
blackjack.conf 파일 보기

@@ -1,5 +1,6 @@
flat_bet = 1
no_insurance = true
delay = 0

; arranged_cards = 2,1,11
; rng_seed = 1

+ 0
- 41
bs.txt 파일 보기

@@ -1,41 +0,0 @@
# 2 3 4 5 6 7 8 9 T A
h20 s s s s s s s s s s
h19 s s s s s s s s s s
h18 s s s s s s s s s s
h17 s s s s s s s s s s
h16 s s s s s h h h s h
h15 s s s s s h h h h h
h14 s s s s s h h h h h
h13 s s s s s h h h h h
h12 h h s s s h h h h h
h11 d d d d d d d d d h
h10 d d d d d d d d h d
h9 h d d d d h h h h h
h8 h h h h h h h h h h
h7 h h h h h h h h h h
h6 h h h h h h h h h h
h5 h h h h h h h h h h
h4 h h h h h h h h h h

# 2 3 4 5 6 7 8 9 T A
s20 s s s s s s s s s s
s19 s s s s d s s s s s
s18 d d d d d s s h h h
s17 h d d d d h h h h h
s16 h h d d d h h h h h
s15 h h d d d h h h h h
s14 h h h d d h h h h h
s13 h h h h d h h h h h
s12 h h h h d h h h h h

# 2 3 4 5 6 7 8 9 T A
pA y y y y y y y y y y
pT n n n n n n n n n n
p9 y y y y y n y y n n
p8 y y y y y y y y y y
p7 y y y y y y n n n n
p6 y y y y y n n n n n
p5 n n n n n n n n n n
p4 n n n y y n n n n n
p3 y y y y y y n n n n
p2 y y y y y y n n n n

+ 10
- 0
players/20-basic-strategy/.gitignore 파일 보기

@@ -0,0 +1,10 @@
*.yaml
*.str
*.log
hard.txt
soft.txt
pair.txt
bs.txt
*.html
table.md
blackjack.conf

+ 17
- 0
players/20-basic-strategy/hard-stand.txt 파일 보기

@@ -0,0 +1,17 @@
h20 s s s s s s s s s s
h19 s s s s s s s s s s
h18 s s s s s s s s s s
h17 s s s s s s s s s s
h16 s s s s s s s s s s
h15 s s s s s s s s s s
h14 s s s s s s s s s s
h13 s s s s s s s s s s
h12 s s s s s s s s s s
h11 s s s s s s s s s s
h10 s s s s s s s s s s
h9 s s s s s s s s s s
h8 s s s s s s s s s s
h7 s s s s s s s s s s
h6 s s s s s s s s s s
h5 s s s s s s s s s s
h4 s s s s s s s s s s

+ 5
- 0
players/20-basic-strategy/options.conf 파일 보기

@@ -0,0 +1,5 @@
decks = -1
flat_bet = 1
no_insurance = true
; hit_soft_17 = 0
; rng_seed = 1

+ 10
- 0
players/20-basic-strategy/pair-no.txt 파일 보기

@@ -0,0 +1,10 @@
pA n n n n n n n n n n
pT n n n n n n n n n n
p9 n n n n n n n n n n
p8 n n n n n n n n n n
p7 n n n n n n n n n n
p6 n n n n n n n n n n
p5 n n n n n n n n n n
p4 n n n n n n n n n n
p3 n n n n n n n n n n
p2 n n n n n n n n n n

+ 385
- 0
players/20-basic-strategy/run.sh 파일 보기

@@ -0,0 +1,385 @@
#!/bin/bash

for i in grep cut bc awk; do
if [ -z "$(which $i)" ]; then
echo "error: $i not installed"
exit 1
fi
done

debug=0

declare -A strategy
declare -A ev

declare -A min
min["hard"]=4 # from 20 to 4 in hards
min["soft"]=12 # from 20 to 12 in softs

rm -f hard.html soft.html pair.html

# --------------------------------------------------------------
# start with standing
cp hard-stand.txt hard.txt
cp soft-stand.txt soft.txt

cat << EOF > table.md
| Hand | \$n\$ | Stand | Double | Hit |
| ---- | ----- | ----- | ------ | --- |
EOF


for type in hard soft; do
for hand in $(seq 20 -1 ${min[${type}]}); do
# choose two random cards that make up the player's assumed total
if [ ${type} = "hard" ]; then
t="h"
card1=11
card2=11
while test $card1 -gt 10 -o $card2 -gt 10; do
card1=$((${RANDOM} % (${hand}-3) + 2))
card2=$((${hand} - ${card1}))
done
elif [ ${type} = "soft" ]; then
t="s"
# one card is an ace
card1=1
card2=$((${hand} - 10 - ${card1}))
fi

cat << EOF >> ${type}.html
<tr>
<td>${t}${hand}</td>
<td>
<div class="text-right">s<span class="d-none d-lg-inline">tand</span></div>
<div class="text-right">h<span class="d-none d-lg-inline">it</span></div>
<div class="text-right">d<span class="d-none d-lg-inline">ouble</span></div>
</td>
EOF
for upcard in $(seq 2 9) T A; do
if [ "x$upcard" = "xT" ]; then
upcard_n=10
elif [ "x$upcard" = "xA" ]; then
upcard_n=1
else
upcard_n=$(($upcard))
fi
n=10000 # start with n hands
best="x" # x means don't know what to so, so play
while [ "${best}" = "x" ]; do
# tell the user which combination we are trying and how many we will play
echo -n ${t}${hand}-${upcard} \($card1 $card2\) "n="${n}

for play in s d h; do
# start with options.conf as a template and add some custom stuff
cp options.conf blackjack.conf
cat << EOF >> blackjack.conf
hands = ${n}
player = internal
arranged_cards = ${card1}, $((${upcard_n} + 13)), $((${card2} + 26))
report = ${t}${hand}-${upcard}-${play}.yaml
#log = ${t}${hand}-${upcard}-${play}.log
EOF
# read the current strategy
while read w p2 p3 p4 p5 p6 p7 p8 p9 pT pA; do
# w already has the "h" or the "s"
strategy[${w},2]=$p2
strategy[${w},3]=$p3
strategy[${w},4]=$p4
strategy[${w},5]=$p5
strategy[${w},6]=$p6
strategy[${w},7]=$p7
strategy[${w},8]=$p8
strategy[${w},9]=$p9
strategy[${w},T]=$pT
strategy[${w},A]=$pA
done < ${type}.txt
# override the read strategy with the explicit play: s, d or h
strategy[${t}${hand},${upcard}]=${play}
# save the new (temporary) strategy
rm -f ${type}.txt
for h in $(seq 20 -1 ${min[${type}]}); do
echo -n "${t}${h} " >> ${type}.txt
# extra space if h < 10
if [ ${h} -lt 10 ]; then
echo -n " " >> ${type}.txt
fi
for u in $(seq 2 9) T A; do
echo -n "${strategy[${t}${h},${u}]} " >> ${type}.txt
done
echo >> ${type}.txt
done

# debug, comment for production
if [ "${debug}" != "0" ]; then
cp ${type}.txt ${t}${hand}-${upcard}-${play}.str
fi
# ensamble the full bs.txt with no pairing
cat hard.txt soft.txt pair-no.txt > bs.txt
# play!
blackjack
# evaluate the results
ev[${t}${hand},${upcard},${play}]=$(grep mean ${t}${hand}-${upcard}-${play}.yaml | awk '{printf("%+g", $2)}')
error[${t}${hand},${upcard},${play}]=$(grep error ${t}${hand}-${upcard}-${play}.yaml | awk '{printf("%.1g", $2)}')
done
# choose the best one
ev_s=$(printf %g ${ev[${t}${hand},${upcard},s]})
ev_d=$(printf %g ${ev[${t}${hand},${upcard},d]})
ev_h=$(printf %g ${ev[${t}${hand},${upcard},h]})
if [ $n -le 9999999 ]; then
# if we still have room, take into account errors
error_s=${error[${t}${hand},${upcard},s]}
error_d=${error[${t}${hand},${upcard},d]}
error_h=${error[${t}${hand},${upcard},h]}
else
# instead of running infinite hands, above a threshold asume errors are zero
error_s=0
error_d=0
error_h=0
fi
echo -ne "\ts=${ev_s} (${error_s})"
echo -ne "\td=${ev_d} (${error_d})"
echo -ne "\th=${ev_h} (${error_h})"
if (( $(echo "${ev_s}-${error_s} > ${ev_d}+${error_d}" | bc -l) )) &&
(( $(echo "${ev_s}-${error_s} > ${ev_h}+${error_h}" | bc -l) )); then
best="s"
echo -e "\tstand"
elif (( $(echo "${ev_d}-${error_d} > ${ev_s}+${error_s}" | bc -l) )) &&
(( $(echo "${ev_d}-${error_d} > ${ev_h}+${error_h}" | bc -l) )); then
best="d"
echo -e "\tdouble"
elif (( $(echo "${ev_h}-${error_h} > ${ev_s}+${error_s}" | bc -l) )) &&
(( $(echo "${ev_h}-${error_h} > ${ev_d}+${error_d}" | bc -l) )); then
best="h"
echo -e "\thit"
else
best="x"
n=$((${n} * 10))
echo -e "\tuncertain"
fi
done

strategy[${t}${hand},${upcard}]=${best}
# echo "| ${t}${hand}-${upcard} | ${n} | ${ev_s} (${error_s}) | ${ev_h} (${error_h}) | ${ev_d} (${error_d}) |" >> table.md
#
# echo " <!-- ${upcard} -->" >> ${type}.html
# echo " <td>" >> ${type}.html
# echo ${ev_s} ${error_s} | awk -f cell.awk >> ${type}.html
# echo ${ev_h} ${error_h} | awk -f cell.awk >> ${type}.html
# echo ${ev_d} ${error_d} | awk -f cell.awk >> ${type}.html
# echo " </td>" >> ${type}.html
# save the strategy again with the best strategy
rm -f ${type}.txt
for h in $(seq 20 -1 ${min[${type}]}); do
echo -n "${t}${h} " >> ${type}.txt
# extra space if h < 10
if [ ${h} -lt 10 ]; then
echo -n " " >> ${type}.txt
fi
for u in $(seq 2 9) T A; do
echo -n "${strategy[${t}${h},${u}]} " >> ${type}.txt
done
echo >> ${type}.txt
done
done
echo "</tr>" >> ${type}.html
done
done

exit

cat << EOF >> table.md


| Hand | \$n\$ | Yes | No |
| ---- | ----- | ----- | ---- |
EOF

# --------------------------------------------------------------------
# pairs
type="pair"
t="p"
cp pair-no.txt pair.txt

for hand in A T `seq 9 -1 2`; do
if [ "${hand}" = "A" ]; then
pair=1
elif [ "${hand}" = "T" ]; then
pair=10
else
pair=$((${hand}))
fi
cat << EOF >> ${type}.html
<tr>
<td>${t}${hand}</td>
<td>
<div class="text-right">y<span class="d-none d-lg-inline">es</span></div>
<div class="text-right">n<span class="d-none d-lg-inline">o</span></div>
</td>
EOF
for upcard in `seq 2 9` T A; do
if [ "$upcard" = "T" ]; then
upcard_n=10
elif [ "$upcard" = "A" ]; then
upcard_n=1
else
upcard_n=$(($upcard))
fi
n=1000 # start with n hands
best="x" # x means don't know what to so, so play
while [ "${best}" = "x" ]; do
# tell the user which combination we are trying and how many we will play
echo -n ${t}${hand}-${upcard} "n="${n}
for play in y n; do
# start with options.conf as a template and add some custom stuff
cp options.conf blackjack.conf
cat << EOF >> blackjack.conf
hands = ${n}
dealer2player = internal
arranged_cards = ${pair} $((${upcard_n} + 13)) $((${pair} + 26))
yaml_report = ${t}${hand}-${upcard}-${play}.yaml
log = ${t}${hand}-${upcard}-${play}.log
EOF
# read the current strategy
while read w p2 p3 p4 p5 p6 p7 p8 p9 pT pA; do
# w already has the "p"
strategy[${w},2]=$p2
strategy[${w},3]=$p3
strategy[${w},4]=$p4
strategy[${w},5]=$p5
strategy[${w},6]=$p6
strategy[${w},7]=$p7
strategy[${w},8]=$p8
strategy[${w},9]=$p9
strategy[${w},T]=$pT
strategy[${w},A]=$pA
done < ${type}.txt
# override the read strategy with the explicit play: y or n
strategy[${t}${hand},${upcard}]=${play}
# save the new (temporary) strategy
rm -f ${type}.txt
for h in A T `seq 9 -1 2`; do
echo -n "${t}${h} " >> ${type}.txt
for u in `seq 2 9` T A; do
echo -n "${strategy[${t}${h},${u}]} " >> ${type}.txt
done
echo >> ${type}.txt
done
if [ "${debug}" != "0" ]; then
cp ${type}.txt ${t}${hand}-${upcard}-${play}.str
fi
# ensamble the full bs.txt
cat hard.txt soft.txt pair.txt > bs.txt
# play!
blackjack > /dev/null
# evaluate the results
ev[${t}${hand},${upcard},${play}]=`grep return ${t}${hand}-${upcard}-${play}.yaml | awk '{printf("%+g", $2)}'`
error[${t}${hand},${upcard},${play}]=`grep error ${t}${hand}-${upcard}-${play}.yaml | awk '{printf("%.1g", $2)}'`
done
# choose the best one
ev_y=`printf %g ${ev[${t}${hand},${upcard},y]}`
ev_n=`printf %g ${ev[${t}${hand},${upcard},n]}`
if [ $n -le 999999 ]; then
# if we still have room, take into account errors
error_y=${error[${t}${hand},${upcard},y]}
error_n=${error[${t}${hand},${upcard},n]}
else
# instead of running infinite hands, above a threshold asume errors are zero
error_y=0
error_n=0
fi
echo -ne "\ty=${ev_y} (${error_y})"
echo -ne "\tn=${ev_n} (${error_n})"
if (( $(echo "${ev_y}-${error_y} > ${ev_n}+${error_n}" | bc -l) )); then
best="y"
echo -e "\tyes"
elif (( $(echo "${ev_n}-${error_n} > ${ev_y}+${error_y}" | bc -l) )); then
best="n"
echo -e "\tno"
else
best="x"
n=$((${n} * 10))
echo -e "\tuncertain"
fi
done

echo "| ${t}${hand}-${upcard} | ${n} | ${ev_y} (${error_y}) | ${ev_n} (${error_n}) |" >> table.md
echo " <!-- ${upcard} -->" >> ${type}.html
echo " <td>" >> ${type}.html
echo ${ev_y} ${error_y} | awk -f cell.awk >> ${type}.html
echo ${ev_n} ${error_n} | awk -f cell.awk >> ${type}.html
echo " </td>" >> ${type}.html
strategy[${t}${hand},${upcard}]=${best}
# save the strategy again with the best strategy
rm -f ${type}.txt
for h in A T `seq 9 -1 2`; do
echo -n "${t}${h} " >> ${type}.txt
for u in `seq 2 9` T A; do
echo -n "${strategy[${t}${h},${u}]} " >> ${type}.txt
done
echo >> ${type}.txt
done
done
done

cat header.txt hard.txt header.txt soft.txt header.txt pair.txt > bs.txt
if [ "${debug}" == "0" ]; then
rm -f *.yaml
rm -f *.str
rm -f *.log
fi

+ 10
- 0
players/20-basic-strategy/soft-stand.txt 파일 보기

@@ -0,0 +1,10 @@
s20 s s s s s s s s s s
s19 s s s s s s s s s s
s18 s s s s s s s s s s
s17 s s s s s s s s s s
s16 s s s s s s s s s s
s15 s s s s s s s s s s
s14 s s s s s s s s s s
s13 s s s s s s s s s s
s12 s s s s s s s s s s

+ 5
- 1
src/base.h 파일 보기

@@ -29,6 +29,8 @@
#include <random>
#include <cmath>

#include "conf.h"

namespace Libreblackjack {
void shortversion(void);
void help(const char *);
@@ -328,12 +330,14 @@ class Dealer {
double variance = 0;
} playerStats;

std::string report_file_path;
int report_verbosity = 3;
void updateMeanAndVariance(void);
private:
bool done = false;
std::list<reportItem> report;
int reportVerbosity = 3;
};


+ 7
- 2
src/blackjack.cpp 파일 보기

@@ -38,7 +38,7 @@

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

conf.set(&n_hands, {"n_hands", "hands"});
conf.set(&n_hands, {"n_hands", "hands"});
conf.set(&n_decks, {"decks", "n_decks"});

conf.set(&max_bet, {"max_bet", "maxbet"});
@@ -46,7 +46,12 @@ Blackjack::Blackjack(Configuration &conf) : rng(dev_random()), fiftyTwoCards(1,
conf.set(&double_after_split, {"das", "double_after_split"});
conf.set(&blackjack_pays, {"blackjack_pays"});
conf.set(&playerStats.bankroll, {"bankroll"});
conf.set(&playerStats.bankroll, {"bankroll", "initial_bankroll"});
// TODO: these should be go in the parent dealer class
conf.set(&error_standard_deviations, {"error_standard_deviations"});
conf.set(report_file_path, {"report_file_path", "report"});
conf.set(&report_verbosity, {"report_verbosity", "report_level"});
conf.set(&number_of_burnt_cards, {"number_of_burnt_cards", "n_burnt_cards", "burnt_cards"});
conf.set(&penetration, {"penetration"});

+ 0
- 3
src/conf.cpp 파일 보기

@@ -79,7 +79,6 @@ Configuration::Configuration(int argc, char **argv) {
show_version = true;
break;
case 'c':
std::cout << "custom conf " << optarg << std::endl;
configFilePath = std::move(std::string(optarg));
explicitConfigFile = true;
break;
@@ -146,8 +145,6 @@ Configuration::Configuration(int argc, char **argv) {
// common settings to all dealers and players
set(&max_incorrect_commands, {"max_incorrect_commands"});
set(&error_standard_deviations, {"error_standard_deviations"});
set(yaml_report_path, {"yaml_report", "yaml_report_path"});
return;

+ 2
- 2
src/conf.h 파일 보기

@@ -53,11 +53,11 @@ class Configuration {
std::string getPlayerName(void) { return player; };

unsigned int max_incorrect_commands = 10;
std::string yaml_report_path;
std::string report_file_path;
// TODO:

unsigned int hands_per_char = false;
double error_standard_deviations;
bool show_help = false;
bool show_version = false;

+ 92
- 7
src/internal.cpp 파일 보기

@@ -29,10 +29,11 @@


Internal::Internal(Configuration &conf) {
hard.resize(21); // 4--20
soft.resize(21); // 12--20
pair.resize(21); // 2*(2--10) + 11

// fill everything with "none"
hard.resize(21);
soft.resize(21);
pair.resize(21);
for (int value = 0; value < 21; value++) {
hard[value].resize(12);
@@ -45,16 +46,100 @@ Internal::Internal(Configuration &conf) {
pair[value][upcard] = Libreblackjack::PlayerActionTaken::None;
}
}
// TODO: read a default basic strategy
// read in a skeleton of the basic strategy
std::vector<std::string> default_hard(21);
std::vector<std::string> default_soft(21);
std::vector<std::string> default_pair(21);
default_hard[20] = " ssssssssss";
default_hard[19] = " ssssssssss";
default_hard[18] = " ssssssssss";
default_hard[17] = " ssssssssss";
default_hard[16] = " ssssshhhsh";
default_hard[15] = " ssssshhhhh";
default_hard[14] = " ssssshhhhh";
default_hard[13] = " ssssshhhhh";
default_hard[12] = " hhssshhhhh";
default_hard[11] = " dddddddddh";
default_hard[10] = " ddddddddhd";
default_hard[9] = " hddddhhhhh";
default_hard[8] = " hhhhhhhhhh";
default_hard[7] = " hhhhhhhhhh";
default_hard[6] = " hhhhhhhhhh";
default_hard[5] = " hhhhhhhhhh";
default_hard[4] = " hhhhhhhhhh";
default_soft[20] = " ssssssssss";
default_soft[19] = " ssssdsssss";
default_soft[18] = " dddddsshhh";
default_soft[17] = " hddddhhhhh";
default_soft[16] = " hhdddhhhhh";
default_soft[15] = " hhdddhhhhh";
default_soft[14] = " hhhddhhhhh";
default_soft[13] = " hhhhdhhhhh";
default_soft[12] = " hhhhdhhhhh";
default_pair[20] = " nnnnnnnnnn";
default_pair[18] = " yyyyynyynn";
default_pair[16] = " yyyyyyyyyy";
default_pair[14] = " yyyyyynnnn";
default_pair[12] = " yyyyynnnnn";
default_pair[11] = " yyyyyyyyyy";
default_pair[10] = " nnnnnnnnnn";
default_pair[8] = " nnnyynnnnn";
default_pair[6] = " yyyyyynnnn";
default_pair[4] = " yyyyyynnnn";
for (int value = 4; value < 21; value++) {
for (int upcard = 2; upcard < 12; upcard++) {
if (default_hard[value] != "") {
switch (default_hard[value][upcard]) {
case 'h':
hard[value][upcard] = Libreblackjack::PlayerActionTaken::Hit;
break;
case 's':
hard[value][upcard] = Libreblackjack::PlayerActionTaken::Stand;
break;
case 'd':
hard[value][upcard] = Libreblackjack::PlayerActionTaken::Double;
break;
}
}

if (default_soft[value] != "") {
switch (default_soft[value][upcard]) {
case 'h':
soft[value][upcard] = Libreblackjack::PlayerActionTaken::Hit;
break;
case 's':
soft[value][upcard] = Libreblackjack::PlayerActionTaken::Stand;
break;
case 'd':
soft[value][upcard] = Libreblackjack::PlayerActionTaken::Double;
break;
}
}
if (default_pair[value] != "" && default_pair[value][upcard] == 'y') {
pair[value][upcard] = Libreblackjack::PlayerActionTaken::Split;
}
}
}
// read the actual file
conf.set(strategy_file_path, {"strategy_file_path", "strategy_file", "strategy"});
// std::ifstream is RAII, i.e. no need to call close
std::ifstream fileStream("bs.txt");
std::ifstream fileStream(strategy_file_path);
std::string line;
std::string token;
if (fileStream.is_open()) {
while (getline(fileStream, line)) {
if (line[0] == '#' || line[0] == ';' || line.empty()) {
if (line[0] == '#' || line[0] == ';' || line.empty() || line.find_first_not_of(" \t\r\n") == line.npos) {
continue;
}


+ 1
- 0
src/internal.h 파일 보기

@@ -34,6 +34,7 @@ class Internal : public Player {

private:
std::string strategy_file_path{"bs.txt"};
std::vector<std::vector<Libreblackjack::PlayerActionTaken>> pair;
std::vector<std::vector<Libreblackjack::PlayerActionTaken>> soft;
std::vector<std::vector<Libreblackjack::PlayerActionTaken>> hard;

+ 1
- 1
src/main.cpp 파일 보기

@@ -22,8 +22,8 @@

#include <iostream>

#include "base.h"
#include "conf.h"
#include "base.h"
#include "blackjack.h"
#include "tty.h"
#include "stdinout.h"

+ 17
- 114
src/report.cpp 파일 보기

@@ -63,125 +63,28 @@ void Dealer::reportPrepare(void) {
}

int Dealer::writeReportYAML(void) {
// FILE *file;
// struct rusage usage;
// double wall;
// double ev, error;
// int precision;
// char format[32];

// if ((file = blackjack_conf.yaml_report) == NULL) {
// file = stderr;
// }

FILE *out;
if (report_file_path != "") {
out = fopen(report_file_path.c_str(), "w");
} else {
out = stderr;
}
// TODO: choose if comments with explanations are to be added
// TODO: choose verbosity level
std::cerr << "---" << std::endl;
fprintf(out, "---\n");
for (auto item : report) {
if (item.level <= reportVerbosity) {
std::cerr << item.key << ": ";
fprintf(stderr, item.format.c_str(), item.value);
std::cerr << std::endl;
if (item.level <= report_verbosity) {
fprintf(out, "%s: ", item.key.c_str());
fprintf(out, item.format.c_str(), item.value);
fprintf(out, "\n");
}
}
fprintf(out, "...\n");
// std::cerr << "rules:" << std::endl;
// std::cerr << " decks: " << decks << std::endl;
// std::cerr << " hands: " << n_hands << std::endl;
// std::cerr << " hit_soft_17: %d\n",
// blackjack_conf.hit_soft_17);
// std::cerr << " double_after_split: %d\n",
// blackjack_conf.double_after_split);
// std::cerr << " blackjack_pays: %g\n",
// blackjack_conf.blackjack_pays);
// std::cerr << " rng_seed: %d\n", blackjack_conf.rng_seed);
// std::cerr << " number_of_burnt_cards: %d\n",
// blackjack_conf.number_of_burnt_cards);
// std::cerr << " no_negative_bankroll: %d\n",
// blackjack_conf.no_negative_bankroll);
// std::cerr << " max_bet: %d\n", blackjack_conf.max_bet);

// if (blackjack_conf.decks > 0)
// {
// std::cerr << " penetration: %g\n",
// blackjack_conf.penetration);
// std::cerr << " penetration_sigma: %g\n",
// blackjack_conf.penetration_sigma);
// }

// TODO
// if (getrusage (RUSAGE_SELF, &usage) == 0) {
// std::cerr << "cpu:" << std::endl;
// std::cerr << " user: " + (usage.ru_utime.tv_sec + 1e-6 * usage.ru_utime.tv_usec) << std::endl;
// std::cerr << " system: " + (usage.ru_stime.tv_sec + 1e-6 * usage.ru_stime.tv_usec) << std::endl;

// measue final wall time
// TODO: chrono
// gettimeofday (&wall_time_final, NULL);
// wall = (blackjack.wall_time_final.tv_sec -
// blackjack.wall_time_initial.tv_sec) +
// 1e-6 * (blackjack.wall_time_final.tv_usec -
// blackjack.wall_time_initial.tv_usec);
// std::cerr << " wall: %g\n", wall);

// speed
// std::cerr << " second_per_hand: %.1e\n", wall / blackjack.hand);
// std::cerr << " hands_per_second: %.1e\n", blackjack.hand / wall);
// }

// std::cerr << "player: " << std::endl;
// std::cerr << " wins: " ((double) player->wins / (double) player->number_of_hands)) << std::endl;
// std::cerr << " pushes: %g\n",
// (double) player->pushes / (double) player->number_of_hands);
// std::cerr << " losses: %g\n",
// (double) player->losses / (double) player->number_of_hands);
// std::cerr << " dealer_blackjacks: %g\n",
// (double) player->dealer_blackjacks /
// (double) player->number_of_hands);
// std::cerr << " player_blackjacks: %g\n",
// (double) player->player_blackjacks /
// (double) player->number_of_hands);
// std::cerr << " dealer_busts: %g\n",
// (double) player->dealer_busts / (double) player->number_of_hands);
// std::cerr << " player_busts: %g\n",
// (double) player->player_busts / (double) player->number_of_hands);
// std::cerr << " doubled_hands: %g\n",
// (double) player->doubled_hands / (double) player->number_of_hands);
// std::cerr << " doubled_wins: %g\n",
// (double) player->doubled_wins / (double) player->number_of_hands);
// std::cerr << " insured_hands: %g\n",
// (double) player->insured_hands / (double) player->number_of_hands);
// std::cerr << " insured_wins: %g\n",
// (double) player->insured_wins / (double) player->number_of_hands);

// std::cerr << " number_of_hands: %g\n",
// (double) player->number_of_hands);
// std::cerr << " number_of_shuffles: %g\n", (double) blackjack.shuffles);
// std::cerr << " total_money_waged: %g\n",
// (double) player->total_money_waged);
// std::cerr << " worst_bankroll: %g\n",
// (double) player->worst_bankroll);
// std::cerr << " final_bankroll: %g\n", (double) player->bankroll);

// return is a keyword!

// precision = (int) (ceil (-log10 (error))) - 2;
// if (precision >= 0) {
// snprintf (format, 32, ("%%+.%df ± %%.%df"), precision, precision);
// } else {
// snprintf (format, 32, ("%%+.0f ± %%.0f"));
// }


// std::cerr << " variance: % g\n", player->variance);
// std::cerr << " deviation: % g\n", sqrt (player->variance));
// std::cerr << " error: % g\n",
// sqrt (player->variance / (double) (blackjack.hand)));
// std::cerr << " result: \"("), std::cerr << format,
// 100.0 * ev,
// 100 * error);
// std::cerr << ") %%\"" << std::endl;
std::cerr << "..." << std::endl;
if (report_file_path != "") {
fclose(out);
}

return 0;
}

Loading…
취소
저장