You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

387 satır
11KB

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