-
Notifications
You must be signed in to change notification settings - Fork 0
/
solitaire_state.ml
156 lines (138 loc) · 4.32 KB
/
solitaire_state.ml
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
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
type t = {
deck : Deck.t ref;
player_cards : Hand.t;
dealer_cards : Hand.t;
turn_count : int;
}
let create_state deck player_cards dealer_cards turn_count =
{ deck; player_cards; dealer_cards; turn_count }
let get_deck st = st.deck
let init_state =
let new_deck = ref (Deck.shuffle_deck Deck.full_deck) in
{
deck = new_deck;
dealer_cards = Solitaire_game.hand_dealer new_deck;
player_cards = Solitaire_game.starting_hand_player new_deck;
turn_count = 0;
}
let current_hand st = st.player_cards
let dealer_hand st = st.dealer_cards
let turns st = st.turn_count
let deck_length st =
let deck = st.deck in
Deck.deck_size !deck
let dealer_length st = Hand.hand_size st.dealer_cards
let turn_count_update st = { st with turn_count = st.turn_count + 1 }
let is_card_in_hand card st = Hand.card_in_hand st.player_cards card
let remove_card card dealer_cards = Hand.remove_card dealer_cards card
let get_card_num num st =
List.nth (st.dealer_cards |> Hand.list_of_hand) num
|> Card.indicator_of_card |> Card.int_of_indicator
let match_card card card_num st =
let st = turn_count_update st in
if not (is_card_in_hand card st) then raise Not_found
else
let new_player_cards = remove_card card st.player_cards in
let match_num =
Solitaire_game.match_card card card_num st.dealer_cards
in
if match_num = 0 then
let dealer_cards =
remove_card
(List.nth
(st.dealer_cards |> Hand.list_of_hand)
(card_num - 1))
st.dealer_cards
in
( {
deck = st.deck;
player_cards = new_player_cards;
dealer_cards;
turn_count = st.turn_count;
},
match_num )
else
( {
deck = st.deck;
player_cards = st.player_cards;
dealer_cards = st.dealer_cards;
turn_count = st.turn_count;
},
match_num )
let draw st =
let st = turn_count_update st in
{
deck = st.deck;
player_cards = Solitaire_game.draw st.deck st.player_cards;
dealer_cards = st.dealer_cards;
turn_count = st.turn_count;
}
let special_draw card st =
if not (is_card_in_hand card st) then raise Not_found
else
let st = turn_count_update st in
let new_player_cards = remove_card card st.player_cards in
{
deck = st.deck;
player_cards =
Solitaire_game.special_draw card new_player_cards st.deck;
dealer_cards = st.dealer_cards;
turn_count = st.turn_count;
}
let special_skip card1 card2 (card_num : int) st =
if (not (is_card_in_hand card1 st)) || not (is_card_in_hand card2 st)
then raise Not_found
else
let player_cards = remove_card card1 st.player_cards in
let player_cards_final = remove_card card2 player_cards in
let num =
Solitaire_game.special_skip card1 card2 card_num st.dealer_cards
in
if num = 0 then
let new_dealer_cards =
remove_card
(List.nth
(st.dealer_cards |> Hand.list_of_hand)
(card_num - 1))
st.dealer_cards
in
( {
deck = st.deck;
player_cards = player_cards_final;
dealer_cards = new_dealer_cards;
turn_count = st.turn_count;
},
num )
else
( {
deck = st.deck;
player_cards = player_cards_final;
dealer_cards = st.dealer_cards;
turn_count = st.turn_count;
},
num )
let special_color card card_num st =
if not (is_card_in_hand card st) then raise Not_found
else
let new_player_cards = remove_card card st.player_cards in
let turn_count = turn_count_update st in
( {
deck = turn_count.deck;
player_cards = new_player_cards;
dealer_cards = turn_count.dealer_cards;
turn_count = turn_count.turn_count;
},
Solitaire_game.special_color card st.dealer_cards card_num )
let special_reverse card dealer_num guess st =
if not (is_card_in_hand card st) then raise Not_found
else
let new_player_cards = remove_card card st.player_cards in
let turn_count = turn_count_update st in
( {
deck = turn_count.deck;
player_cards = new_player_cards;
dealer_cards = turn_count.dealer_cards;
turn_count = turn_count.turn_count;
},
Solitaire_game.special_reverse card dealer_num guess
st.dealer_cards )