/
spacehandcalc.clinc
107 lines (106 loc) · 3.77 KB
/
spacehandcalc.clinc
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
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
; ranks are 1-13 with 1 being two, 12 being king, and 13 being ace
; there are no suits, flushes, or ace-to-four straights
; takes a list of card ranks and returns the value of the best poker
; hand which can be made with them
; returned list is hand type followed by cards in descending order
; all sorting is done highest to lowest
(
(include sort.clinc)
(include deep_compare.clinc)
(include filtermap.clinc)
(include slice.clinc)
(include max.clinc)
(defconstant FIVE_OF_A_KIND 8)
(defconstant FOUR_OF_A_KIND 7)
(defconstant FULL_HOUSE 6)
(defconstant STRAIGHT 5)
(defconstant THREE_OF_A_KIND 4)
(defconstant TWO_PAIR 3)
(defconstant PAIR 2)
(defconstant HIGH_CARD 1)
(defun straight_high_inner (ranks last count)
(if (not ranks)
; at the end of the list
0
(if (= last (f ranks))
; skip identical cards
(straight_high_inner (r ranks) last count)
; if the partial straight continues
(if (= (f ranks) (- last 1))
(if (= count 4)
; found a straight, add 3 to last because next and last are included
(+ last 3)
; keep looking for a straight with the count going up by one
(straight_high_inner (r ranks) (f ranks) (+ count 1))
)
; reset the count
(straight_high_inner (r ranks) (f ranks) 1)
)
)
)
)
; returns the high card of a straight or 0 if there isn't any
; ranks must be sorted in descending order
(defun straight_high (ranks)
(straight_high_inner (ranks (= (f ranks) 13) 0 0))
)
(defun group_by_count_inner (items last count)
(if (not items)
0
(if (= (f items) last)
(group_by_count_inner (r items) last (+ count 1))
(assign val (group_by_count_inner (r items) (f items) 1)
(if last
(c (c count last) val)
val
)
)
)
)
)
(defun group_by_count (items)
(group_by_count_inner items 0 0)
)
(defun space_hand_calc_inner (cards)
(assign
rest (lambda (x) (r x))
greater (lambda (x y) (> x y))
ranks (sort greater cards)
sh (straight_high ranks)
max_straight (if sh
(list STRAIGHT sh)
0
)
groups (sort deep> (group_by_count ranks))
(top_count . top_card) (f groups)
(second_count . second_card) (f (r groups))
topcards (map rest groups)
max_group (if (= top_count 1)
(c HIGH_CARD (slice topcards 5))
(if (= top_count 2)
(if (= second_count 1)
(c PAIR (slice topcards 4))
(c TWO_PAIR (slice topcards 3))
)
(if (= top_count 3)
(if (= second_count 1)
(c THREE_OF_A_KIND (slice topcards 3))
(c FULL_HOUSE (slice topcards 2))
)
(if (= top_count 4)
(c FOUR_OF_A_KIND (slice topcards 2))
(c FIVE_OF_A_KIND (slice topcards 1))
)
)
)
)
(max deep< (list max_straight max_group))
)
)
(defun space_hand_calc (cards boosted)
(assign
result (space_hand_calc_inner cards)
(list (f result) boosted (r result))
)
)
)