Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

425 lines
11KB

  1. #!/bin/bash
  2. n0=80000
  3. n_max=9000000
  4. RED="\033[0;31m"
  5. GREEN="\033[0;32m"
  6. BROWN="\033[0;33m"
  7. MAGENTA="\e[0;35m"
  8. CYAN="\e[0;36m"
  9. NC="\033[0m" # No Color
  10. for i in grep awk printf blackjack; do
  11. if [ -z "$(which $i)" ]; then
  12. echo "error: $i not installed"
  13. exit 1
  14. fi
  15. done
  16. debug=0
  17. declare -A strategy
  18. declare -A ev
  19. declare -A min
  20. min["hard"]=4 # from 20 to 4 in hards
  21. min["soft"]=12 # from 20 to 12 in softs
  22. rm -f table.md hard.html soft.html pair.html
  23. # --------------------------------------------------------------
  24. # start with standing
  25. cp hard-stand.txt hard.txt
  26. cp soft-stand.txt soft.txt
  27. cat << EOF >> table.md
  28. | Hand | \$n\$ | Stand [%] | Double [%] | Hit [%] | Play |
  29. |:------:|:-----:|:-----------:|:------------:|:--------:|:---------:|
  30. EOF
  31. for type in hard soft; do
  32. for hand in $(seq 20 -1 ${min[${type}]}); do
  33. # choose two random cards that make up the player's assumed total
  34. if [ ${type} = "hard" ]; then
  35. t="h"
  36. card1=11
  37. card2=11
  38. while test $card1 -gt 10 -o $card2 -gt 10; do
  39. card1=$((${RANDOM} % (${hand}-3) + 2))
  40. card2=$((${hand} - ${card1}))
  41. done
  42. elif [ ${type} = "soft" ]; then
  43. t="s"
  44. # one card is an ace
  45. card1=1
  46. card2=$((${hand} - 10 - ${card1}))
  47. fi
  48. cat << EOF >> ${type}.html
  49. <tr>
  50. <td>${t}${hand}</td>
  51. <td>
  52. <div class="text-right">s<span class="d-none d-lg-inline">tand</span></div>
  53. <div class="text-right">h<span class="d-none d-lg-inline">it</span></div>
  54. <div class="text-right">d<span class="d-none d-lg-inline">ouble</span></div>
  55. </td>
  56. EOF
  57. for upcard in $(seq 2 9) T A; do
  58. if [ "x$upcard" = "xT" ]; then
  59. upcard_n=10
  60. elif [ "x$upcard" = "xA" ]; then
  61. upcard_n=1
  62. else
  63. upcard_n=$(($upcard))
  64. fi
  65. n=${n0} # start with n0 hands
  66. best="x" # x means don't know what to so, so play
  67. while [ "${best}" = "x" ]; do
  68. # tell the user which combination we are trying and how many we will play
  69. echo -ne "${t}${hand}-${upcard} ($card1 $card2)\t"$(printf %.1e ${n})
  70. for play in s d h; do
  71. # start with options.conf as a template and add some custom stuff
  72. cp options.conf blackjack.conf
  73. cat << EOF >> blackjack.conf
  74. hands = ${n}
  75. player = internal
  76. arranged_cards = ${card1}, $((${upcard_n} + 13)), $((${card2} + 26))
  77. report = ${t}${hand}-${upcard}-${play}.yaml
  78. #log = ${t}${hand}-${upcard}-${play}.log
  79. EOF
  80. # read the current strategy
  81. while read w p2 p3 p4 p5 p6 p7 p8 p9 pT pA; do
  82. # w already has the "h" or the "s"
  83. strategy[${w},2]=$p2
  84. strategy[${w},3]=$p3
  85. strategy[${w},4]=$p4
  86. strategy[${w},5]=$p5
  87. strategy[${w},6]=$p6
  88. strategy[${w},7]=$p7
  89. strategy[${w},8]=$p8
  90. strategy[${w},9]=$p9
  91. strategy[${w},T]=$pT
  92. strategy[${w},A]=$pA
  93. done < ${type}.txt
  94. # override the read strategy with the explicit play: s, d or h
  95. strategy[${t}${hand},${upcard}]=${play}
  96. # save the new (temporary) strategy
  97. rm -f ${type}.txt
  98. for h in $(seq 20 -1 ${min[${type}]}); do
  99. echo -n "${t}${h} " >> ${type}.txt
  100. # extra space if h < 10
  101. if [ ${h} -lt 10 ]; then
  102. echo -n " " >> ${type}.txt
  103. fi
  104. for u in $(seq 2 9) T A; do
  105. echo -n "${strategy[${t}${h},${u}]} " >> ${type}.txt
  106. done
  107. echo >> ${type}.txt
  108. done
  109. # debug, comment for production
  110. if [ "${debug}" != "0" ]; then
  111. cp ${type}.txt ${t}${hand}-${upcard}-${play}.str
  112. fi
  113. # ensamble the full bs.txt with no pairing
  114. cat hard.txt soft.txt pair-no.txt > bs.txt
  115. # play!
  116. blackjack
  117. # evaluate the results
  118. ev[${t}${hand},${upcard},${play}]=$(grep mean ${t}${hand}-${upcard}-${play}.yaml | awk '{printf("%g", $2)}')
  119. error[${t}${hand},${upcard},${play}]=$(grep error ${t}${hand}-${upcard}-${play}.yaml | awk '{printf("%g", $2)}')
  120. done
  121. # choose the best one
  122. ev_s=$(echo ${ev[${t}${hand},${upcard},s]} | awk '{printf("%+.2f", 100*$1)}')
  123. ev_d=$(echo ${ev[${t}${hand},${upcard},d]} | awk '{printf("%+.2f", 100*$1)}')
  124. ev_h=$(echo ${ev[${t}${hand},${upcard},h]} | awk '{printf("%+.2f", 100*$1)}')
  125. if [ ${n} -le ${n_max} ]; then
  126. # if we still have room, take into account errors
  127. error_s=$(echo ${error[${t}${hand},${upcard},s]} | awk '{printf("%.1f", 100*$1)}')
  128. error_d=$(echo ${error[${t}${hand},${upcard},d]} | awk '{printf("%.1f", 100*$1)}')
  129. error_h=$(echo ${error[${t}${hand},${upcard},h]} | awk '{printf("%.1f", 100*$1)}')
  130. else
  131. # instead of running infinite hands, above a threshold asume errors are zero
  132. error_s=0
  133. error_d=0
  134. error_h=0
  135. fi
  136. echo -ne "\t${ev_s}\t(${error_s})"
  137. echo -ne "\t${ev_d}\t(${error_d})"
  138. echo -ne "\t${ev_h}\t(${error_h})"
  139. if (( $(echo ${ev_s} ${error_s} ${ev_d} ${error_d} | awk '{print (($1-$2) > ($3+$4))}') )) &&
  140. (( $(echo ${ev_s} ${error_s} ${ev_h} ${error_h} | awk '{print (($1-$2) > ($3+$4))}') )); then
  141. best="s"
  142. color=${BROWN}
  143. best_string="stand"
  144. elif (( $(echo ${ev_d} ${error_d} ${ev_s} ${error_s} | awk '{print (($1-$2) > ($3+$4))}') )) &&
  145. (( $(echo ${ev_d} ${error_d} ${ev_h} ${error_h} | awk '{print (($1-$2) > ($3+$4))}') )); then
  146. best="d"
  147. color=${CYAN}
  148. best_string="double"
  149. elif (( $(echo ${ev_h}-${error_h} ${ev_s} ${error_s} | awk '{print (($1-$2) > ($3+$4))}') )) &&
  150. (( $(echo ${ev_h}-${error_h} ${ev_d} ${error_d} | awk '{print (($1-$2) > ($3+$4))}') )); then
  151. best="h"
  152. color=${MAGENTA}
  153. best_string="hit"
  154. else
  155. best="x"
  156. color=${NC}
  157. best_string="uncertain"
  158. n=$((${n} * 4))
  159. fi
  160. echo -e ${color}"\t"${best_string}${NC}
  161. done
  162. strategy[${t}${hand},${upcard}]=${best}
  163. echo "| ${t}${hand}-${upcard} | $(printf %.1e ${n}) | ${ev_s} (${error_s}) | ${ev_h} (${error_h}) | ${ev_d} (${error_d}) | ${best_string} | " >> table.md
  164. echo " <!-- ${upcard} -->" >> ${type}.html
  165. echo " <td>" >> ${type}.html
  166. echo ${ev_s} ${error_s} | awk -f html_cell.awk >> ${type}.html
  167. echo ${ev_h} ${error_h} | awk -f html_cell.awk >> ${type}.html
  168. echo ${ev_d} ${error_d} | awk -f html_cell.awk >> ${type}.html
  169. echo " </td>" >> ${type}.html
  170. # save the strategy again with the best strategy
  171. rm -f ${type}.txt
  172. for h in $(seq 20 -1 ${min[${type}]}); do
  173. echo -n "${t}${h} " >> ${type}.txt
  174. # extra space if h < 10
  175. if [ ${h} -lt 10 ]; then
  176. echo -n " " >> ${type}.txt
  177. fi
  178. for u in $(seq 2 9) T A; do
  179. echo -n "${strategy[${t}${h},${u}]} " >> ${type}.txt
  180. done
  181. echo >> ${type}.txt
  182. done
  183. done
  184. # echo "</tr>" >> ${type}.html
  185. done
  186. done
  187. cat << EOF >> table.md
  188. | Hand | \$n\$ | Yes [%] | No [%] |
  189. |:------:|:-------:|:----------:|:----------:|
  190. EOF
  191. # --------------------------------------------------------------------
  192. # pairs
  193. type="pair"
  194. t="p"
  195. cp pair-no.txt pair.txt
  196. for hand in A T $(seq 9 -1 2); do
  197. if [ "${hand}" = "A" ]; then
  198. pair=1
  199. elif [ "${hand}" = "T" ]; then
  200. pair=10
  201. else
  202. pair=$((${hand}))
  203. fi
  204. # cat << EOF >> ${type}.html
  205. # <tr>
  206. # <td>${t}${hand}</td>
  207. # <td>
  208. # <div class="text-right">y<span class="d-none d-lg-inline">es</span></div>
  209. # <div class="text-right">n<span class="d-none d-lg-inline">o</span></div>
  210. # </td>
  211. # EOF
  212. for upcard in $(seq 2 9) T A; do
  213. if [ "$upcard" = "T" ]; then
  214. upcard_n=10
  215. elif [ "$upcard" = "A" ]; then
  216. upcard_n=1
  217. else
  218. upcard_n=$(($upcard))
  219. fi
  220. n=${n0} # start with n0 hands
  221. best="x" # x means don't know what to so, so play
  222. while [ "${best}" = "x" ]; do
  223. # tell the user which combination we are trying and how many we will play
  224. echo -ne "${t}${hand}-${upcard}\t\t$(printf %.0e ${n})"
  225. for play in y n; do
  226. # start with options.conf as a template and add some custom stuff
  227. cp options.conf blackjack.conf
  228. cat << EOF >> blackjack.conf
  229. hands = ${n}
  230. player = internal
  231. arranged_cards = ${pair}, $((${upcard_n} + 13)), $((${pair} + 26))
  232. report = ${t}${hand}-${upcard}-${play}.yaml
  233. # log = ${t}${hand}-${upcard}-${play}.log
  234. EOF
  235. # read the current strategy
  236. while read w p2 p3 p4 p5 p6 p7 p8 p9 pT pA; do
  237. # w already has the "p"
  238. strategy[${w},2]=$p2
  239. strategy[${w},3]=$p3
  240. strategy[${w},4]=$p4
  241. strategy[${w},5]=$p5
  242. strategy[${w},6]=$p6
  243. strategy[${w},7]=$p7
  244. strategy[${w},8]=$p8
  245. strategy[${w},9]=$p9
  246. strategy[${w},T]=$pT
  247. strategy[${w},A]=$pA
  248. done < ${type}.txt
  249. # override the read strategy with the explicit play: y or n
  250. strategy[${t}${hand},${upcard}]=${play}
  251. # save the new (temporary) strategy
  252. rm -f ${type}.txt
  253. for h in A T $(seq 9 -1 2); do
  254. echo -n "${t}${h} " >> ${type}.txt
  255. for u in $(seq 2 9) T A; do
  256. echo -n "${strategy[${t}${h},${u}]} " >> ${type}.txt
  257. done
  258. echo >> ${type}.txt
  259. done
  260. if [ "${debug}" != "0" ]; then
  261. cp ${type}.txt ${t}${hand}-${upcard}-${play}.str
  262. fi
  263. # ensamble the full bs.txt
  264. cat hard.txt soft.txt pair.txt > bs.txt
  265. # play!
  266. blackjack
  267. # evaluate the results
  268. ev[${t}${hand},${upcard},${play}]=$(grep mean ${t}${hand}-${upcard}-${play}.yaml | awk '{printf("%g", $2)}')
  269. error[${t}${hand},${upcard},${play}]=$(grep error ${t}${hand}-${upcard}-${play}.yaml | awk '{printf("%g", $2)}')
  270. done
  271. # choose the best one
  272. ev_y=$(echo ${ev[${t}${hand},${upcard},y]} | awk '{printf("%+.2f", 100*$1)}')
  273. ev_n=$(echo ${ev[${t}${hand},${upcard},n]} | awk '{printf("%+.2f", 100*$1)}')
  274. if [ $n -le ${n_max} ]; then
  275. # if we still have room, take into account errors
  276. error_y=$(echo ${error[${t}${hand},${upcard},y]} | awk '{printf("%.1f", 100*$1)}')
  277. error_n=$(echo ${error[${t}${hand},${upcard},n]} | awk '{printf("%.1f", 100*$1)}')
  278. else
  279. # instead of running infinite hands, above a threshold asume errors are zero
  280. error_y=0
  281. error_n=0
  282. fi
  283. echo -ne "\t${ev_y}\t(${error_y})"
  284. echo -ne "\t${ev_n}\t(${error_n})"
  285. if (( $(echo ${ev_y} ${error_y} ${ev_n} ${error_n} | awk '{print (($1-$2) > ($3+$4))}') )); then
  286. best="y"
  287. color=${GREEN}
  288. best_string="yes"
  289. elif (( $(echo ${ev_n} ${error_n} ${ev_y} ${error_y} | awk '{print (($1-$2) > ($3+$4))}') )); then
  290. best="n"
  291. color=${RED}
  292. best_string="no"
  293. else
  294. best="x"
  295. color=${NC}
  296. best_string="uncertain"
  297. n=$((${n} * 4))
  298. fi
  299. echo -e ${color}"\t"${best_string}${NC}
  300. done
  301. echo "| ${t}${hand}-${upcard} | $(printf %.1e ${n}) | ${ev_y} (${error_y}) | ${ev_n} (${error_n}) | ${best_string} | " >> table.md
  302. echo " <!-- ${upcard} -->" >> ${type}.html
  303. echo " <td>" >> ${type}.html
  304. echo ${ev_y} ${error_y} | awk -f html_cell.awk >> ${type}.html
  305. echo ${ev_n} ${error_n} | awk -f html_cell.awk >> ${type}.html
  306. echo " </td>" >> ${type}.html
  307. strategy[${t}${hand},${upcard}]=${best}
  308. # save the strategy again with the best strategy
  309. rm -f ${type}.txt
  310. for h in A T $(seq 9 -1 2); do
  311. echo -n "${t}${h} " >> ${type}.txt
  312. for u in $(seq 2 9) T A; do
  313. echo -n "${strategy[${t}${h},${u}]} " >> ${type}.txt
  314. done
  315. echo >> ${type}.txt
  316. done
  317. done
  318. done
  319. cat header.txt hard.txt header.txt soft.txt header.txt pair.txt > bs.txt
  320. rm -f hard.txt soft.txt pair.txt blackjack.conf
  321. if [ "${debug}" == "0" ]; then
  322. rm -f *.yaml
  323. rm -f *.str
  324. rm -f *.log
  325. fi