-
Notifications
You must be signed in to change notification settings - Fork 0
/
hand.c
156 lines (146 loc) · 2.92 KB
/
hand.c
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
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <time.h>
#include <string.h>
#include "structs.h"
#include "card.h"
/**
* Take a random card from the deck
* Remove it from the deck
* Add it to the hand
* Realloc memory space if necessary
*
* @param hand hand to add to
* @param deck deck to pull from
*/
void add_card(hand *hand, deck *deck)
{
time_t t;
srand((unsigned)(time(&t)));
int i = (rand() % 52);
if (!has_available_card(deck))
{
printf("No more cards! Game over!\n");
return;
}
while (deck->cards[i].taken)
{
i = rand() % 52;
}
if (hand->card_count == hand->hand_limit)
{
hand->cards = (card *)(realloc(hand->cards, sizeof(card) * (hand->card_count + 2)));
hand->hand_limit += 2;
}
deck->cards[i].taken = true;
*(hand->cards + hand->card_count) = *(deck->cards + i);
hand->card_count++;
}
/**
* Check if a hand contains an ace inside
*
* @param hand hand to check
*
* @return {@code true} if hand contains an ace, {@code false} otherwise
*/
bool contains_ace(hand *hand)
{
for (int i = 0; i < hand->card_count; i++)
{
if (strcmp(hand->cards[i].value, "A") == 0)
{
return true;
}
}
return false;
}
/**
* Check if a hand contains a face card or 10 inside
*
* @param hand hand to check
*
* @return {@code true} if hand contains a face card or 10, {@code false} otherwise
*/
bool contains_face_card(hand *hand)
{
for (int i = 0; i < hand->card_count; i++)
{
if (strcmp(hand->cards[i].value, "J") == 0 || strcmp(hand->cards[i].value, "Q") == 0 || strcmp(hand->cards[i].value, "K") == 0 || strcmp(hand->cards[i].value, "10") == 0)
{
return true;
}
}
return false;
}
/**
* Check if a hand contains a blackjack
*
* @param hand hand to check
*
* @return {@code true} if hand contains a blackjack, {@code false} otherwise
*/
bool contains_blackjack(hand *hand)
{
if (hand->card_count == 2)
{
return contains_face_card(hand) && contains_ace(hand);
}
return false;
}
/**
* Get the value of the hand
*
* @param hand hand to check
*
* @return 21 if blackjack, otherwise the value of the hand calculated from the sum of card values
*/
int get_hand_value(hand *hand)
{
if (contains_blackjack(hand))
{
return 21;
}
int values = 0;
for (int i = 0; i < hand->card_count; i++)
{
values += get_card_value(hand->cards[i]);
}
if(contains_ace(hand) && values < 11){
values += 10;
}
return values;
}
/**
* Check if the hand has busted
*
* @param hand hand to check
*
* @return {@code true} if busted, {@code false} otherwise
*/
bool has_busted(hand *hand)
{
if (get_hand_value(hand) > 21)
{
return true;
}
return false;
}
/**
* Sets the hand's held to true
*
* @param hand hand to set
*/
void hold(hand *hand)
{
hand->held = true;
}
/**
* Sets the hand's bust to true
*
* @param hand hand to set
*/
void bust(hand *hand)
{
hand->has_busted = true;
}