Advertisement
Guest User

poker.hoon

a guest
Sep 22nd, 2019
123
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 8.37 KB | None | 0 0
  1. ::I edited the playing cards library to represent cards as numbers 2-14 instead of 1-13
  2. ::If aces are 14 instead of 1, there are fewer annoying edge cases
  3. ::Sorry if that is bad
  4. ::
  5. /+ playing-cards
  6. :- %say
  7. |= [[* eny=@uv *] *]
  8. :- %noun
  9. =/ deck (shuffle-deck:playing-cards make-deck:playing-cards eny)
  10. =/ draw-result (draw:playing-cards 5 deck)
  11. =/ hand1 hand.draw-result
  12. =/ hand2 -:(draw:playing-cards 5 rest.draw-result)
  13. =<
  14. (compare-hands hand1 hand2)
  15. |%
  16. +$ hand-score [hand-type=@t tiebreak-values=(list @)]
  17. ++ card-sorting-function
  18. |= [card1=darc:playing-cards card2=darc:playing-cards]
  19. (lth +:card1 +:card2)
  20. ++ compare-hands
  21. |= [hand1=deck:playing-cards hand2=deck:playing-cards]
  22. =/ hand1-score (score-hand (sort hand1 card-sorting-function))
  23. =/ hand2-score (score-hand (sort hand2 card-sorting-function))
  24. ~& hand1
  25. ~& hand2
  26. ~& hand-type.hand1-score
  27. ~& hand-type.hand2-score
  28. =/ hand1-primary-score (hand-type-to-num hand-type.hand1-score)
  29. =/ hand2-primary-score (hand-type-to-num hand-type.hand2-score)
  30. ?: (gth hand1-primary-score hand2-primary-score)
  31. 'Hand 1 wins'
  32. ?: (gth hand2-primary-score hand1-primary-score)
  33. 'Hand 2 wins'
  34. ::if the hands have the same type (e.g. pair), we look at tiebreak information
  35. ::
  36. =/ i 0
  37. |-
  38. ?: =(i (lent tiebreak-values.hand1-score))
  39. 'Hand ends in a draw'
  40. =/ tiebreak-value-hand1 (snag i tiebreak-values.hand1-score)
  41. =/ tiebreak-value-hand2 (snag i tiebreak-values.hand2-score)
  42. ?: (gth tiebreak-value-hand1 tiebreak-value-hand2)
  43. 'Hand 1 wins'
  44. ?: (gth tiebreak-value-hand2 tiebreak-value-hand1)
  45. 'Hand 2 wins'
  46. $(i +(i))
  47. ++ score-hand
  48. |= hand=deck:playing-cards
  49. ^- hand-score
  50. ?: (is-straight-flush hand)
  51. ['straight-flush' (get-tiebreak-values hand 'straight-flush')]
  52. ?: (is-four-of-a-kind hand)
  53. ['four-of-a-kind' (get-tiebreak-values hand 'four-of-a-kind')]
  54. ?: (is-full-house hand)
  55. ['full-house' (get-tiebreak-values hand 'full-house')]
  56. ?: (is-flush hand)
  57. ['flush' (get-tiebreak-values hand 'flush')]
  58. ?: (is-straight hand)
  59. ['straight' (get-tiebreak-values hand 'straight')]
  60. ?: (is-three-of-a-kind hand)
  61. ['three-of-a-kind' (get-tiebreak-values hand 'three-of-a-kind')]
  62. ?: (is-two-pair hand)
  63. ['two-pair' (get-tiebreak-values hand 'two-pair')]
  64. ?: (is-pair hand)
  65. ['pair' (get-tiebreak-values hand 'pair')]
  66. ['high-card' (get-tiebreak-values hand 'high-card')]
  67. ++ is-straight-flush
  68. |= hand=deck:playing-cards
  69. &((is-straight hand) (is-flush hand))
  70. ++ is-four-of-a-kind
  71. |= hand=deck:playing-cards
  72. =/ i=@ 0
  73. |-
  74. =/ current-card-value +:(snag i hand)
  75. =/ filter-by-value |= card=darc:playing-cards =(+:card current-card-value)
  76. ?: =(4 (lent (skim hand filter-by-value)))
  77. &
  78. ?: =(i 1)
  79. |
  80. $(i +(i))
  81. ++ is-flush
  82. |= hand=deck:playing-cards
  83. ?~ hand
  84. !!
  85. =/ first-card-suit -:i.hand
  86. |-
  87. ?~ t.hand
  88. &
  89. =/ current-card-suit -:i.t.hand
  90. ?: =(first-card-suit current-card-suit)
  91. $(hand t.hand)
  92. |
  93. ++ is-straight
  94. |= hand=deck:playing-cards
  95. ?: (is-wheel-straight hand)
  96. &
  97. ?~ hand
  98. !!
  99. =/ previous-card-value +:i.hand
  100. |-
  101. ?~ t.hand
  102. &
  103. =/ next-card-value +:i.t.hand
  104. ?: =(+(previous-card-value) next-card-value)
  105. $(hand t.hand, previous-card-value next-card-value)
  106. |
  107. ++ is-wheel-straight
  108. ::Straight where hand is A-2-3-4-5
  109. ::
  110. |= hand=deck:playing-cards
  111. ?. =(2 +:(snag 0 hand))
  112. |
  113. ?. =(3 +:(snag 1 hand))
  114. |
  115. ?. =(4 +:(snag 2 hand))
  116. |
  117. ?. =(5 +:(snag 3 hand))
  118. |
  119. ?. =(14 +:(snag 4 hand))
  120. |
  121. &
  122. ++ is-three-of-a-kind
  123. |= hand=deck:playing-cards
  124. =/ i=@ 0
  125. =/ three-of-a-kind-found |
  126. |-
  127. ?: (gth i 3)
  128. three-of-a-kind-found
  129. =/ current-card-value +:(snag i hand)
  130. =/ filter-by-value |= card=darc:playing-cards =(+:card current-card-value)
  131. =/ number-of-matches (lent (skim hand filter-by-value))
  132. ?: =(2 number-of-matches)
  133. |
  134. ?: =(3 number-of-matches)
  135. $(i +(i), three-of-a-kind-found &)
  136. $(i +(i))
  137. ++ is-two-pair
  138. |= hand=deck:playing-cards
  139. =/ i=@ 0
  140. =/ pairs-found 0
  141. |-
  142. ?: (gth i 3)
  143. =(2 pairs-found)
  144. =/ current-card-value +:(snag i hand)
  145. =/ filter-by-value |= card=darc:playing-cards =(+:card current-card-value)
  146. =/ number-of-matches (lent (skim hand filter-by-value))
  147. ?: (gth number-of-matches 2)
  148. |
  149. ?: =(2 number-of-matches)
  150. $(i (add i 2), pairs-found +(pairs-found))
  151. $(i +(i))
  152. ++ is-pair
  153. |= hand=deck:playing-cards
  154. =/ i=@ 0
  155. =/ one-pair-found |
  156. |-
  157. ?: (gth i 3)
  158. one-pair-found
  159. =/ current-card-value +:(snag i hand)
  160. =/ filter-by-value |= card=darc:playing-cards =(+:card current-card-value)
  161. =/ number-of-matches (lent (skim hand filter-by-value))
  162. ?: (gth number-of-matches 2)
  163. |
  164. ?: =(2 number-of-matches)
  165. $(i (add i 2), one-pair-found !one-pair-found)
  166. $(i +(i))
  167. ++ is-full-house
  168. |= hand=deck:playing-cards
  169. =/ i=@ 0
  170. =/ pair-found |
  171. =/ three-of-a-kind-found |
  172. |-
  173. ?: (gth i 3)
  174. &(pair-found three-of-a-kind-found)
  175. =/ current-card-value +:(snag i hand)
  176. =/ filter-by-value |= card=darc:playing-cards =(+:card current-card-value)
  177. =/ number-of-matches (lent (skim hand filter-by-value))
  178. ?: =(2 number-of-matches)
  179. $(i (add 2 i), pair-found &)
  180. ?: =(3 number-of-matches)
  181. $(i (add 3 i), three-of-a-kind-found &)
  182. |
  183. ++ get-tiebreak-values
  184. |= [hand=deck:playing-cards hand-type=@t]
  185. ^- (list @)
  186. ::
  187. ::Easy cases first
  188. ::
  189. ::1. Straight with the highest single highest card wins
  190. ?: |(=('straight' hand-type) =('straight-flush' hand-type))
  191. ::...unless that card happens to be an ace at the bottom of a wheel straight
  192. ::in which case the 'top' of the straight is 5
  193. ::
  194. ?: (is-wheel-straight hand)
  195. ~[5]
  196. ~[+:(snag 4 hand)]
  197. ::2. Flushes/high-card hands are tiebroken by the single highest card
  198. ::If 2 hands have the same high card,the 2nd highest decides, then 3rd, etc.
  199. ::
  200. ?: |(=('flush' hand-type) =('high-card' hand-type))
  201. (turn (flop hand) |=(card=darc:playing-cards +:card))
  202. ::3. These hands are tiebroken by the value of the large set of 3 or 4
  203. ::Hands are sorted, so the middle card is always part of the set of 3 or 4
  204. ::
  205. ?: |(=('full-house' hand-type) =('three-of-a-kind' hand-type) =('four-of-a-kind' hand-type))
  206. ~[+:(snag 2 hand)]
  207. ::
  208. ::Relatively more annoying cases are dealt with on their own
  209. ::
  210. ?: =('two-pair' hand-type)
  211. (get-tiebreak-values-two-pair hand)
  212. ?: =('pair' hand-type)
  213. (get-tiebreak-values-pair hand)
  214. !!
  215.  
  216. ++ get-tiebreak-values-two-pair
  217. ::This case is the trickiest because, unlike three/four of a kind...
  218. ::two competing hands can share have some of the same pairs
  219. ::So two hands can be tiebroken by the high pair, low pair, or the odd card out
  220. ::
  221. |= hand=deck:playing-cards
  222. ::The hand is sorted, so cards at indices 1 and 3 will always be part of pairs
  223. ::
  224. =/ low-pair-value +:(snag 1 hand)
  225. =/ high-pair-value +:(snag 3 hand)
  226. =/ filter |= card=darc:playing-cards |(=(+:card low-pair-value) =(+:card high-pair-value))
  227. =/ one-card-value +:(snag 0 (skip hand filter))
  228. ~[high-pair-value low-pair-value one-card-value]
  229.  
  230. ++ get-tiebreak-values-pair
  231. ::Pairs are tiebroken by the pair's value, followed by high cards
  232. ::
  233. |= hand=deck:playing-cards
  234. =/ i 0
  235. |-
  236. ?: =(4 i)
  237. !!
  238. =/ current-value +:(snag i hand)
  239. =/ next-value +:(snag +(i) hand)
  240. =/ get-card-value |=(card=darc:playing-cards +:card)
  241. =/ filter-by-value |= card=darc:playing-cards =(+:card current-value)
  242. ?: =(current-value next-value)
  243. (weld ~[current-value] (turn (flop (skip hand filter-by-value)) get-card-value))
  244. $(i +(i))
  245.  
  246. ++ hand-type-to-num
  247. ::This function is used to help compare hands arithmatically
  248. ::e.g. a straight-flush is better than a pair, so it will have a higher value
  249. ::
  250. |= hand-type=@t
  251. ?: =(hand-type 'high-card')
  252. 0
  253. ?: =(hand-type 'pair')
  254. 1
  255. ?: =(hand-type 'two-pair')
  256. 2
  257. ?: =(hand-type 'three-of-a-kind')
  258. 3
  259. ?: =(hand-type 'straight')
  260. 4
  261. ?: =(hand-type 'flush')
  262. 5
  263. ?: =(hand-type 'full-house')
  264. 6
  265. ?: =(hand-type 'four-of-a-kind')
  266. 7
  267. ?: =(hand-type 'straight-flush')
  268. 8
  269. !!
  270. --
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement