-
Notifications
You must be signed in to change notification settings - Fork 0
/
card_choosers.c
147 lines (126 loc) · 4.34 KB
/
card_choosers.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
#include "card.h"
#include "player.h"
#include "config.h"
#include "game_rules.h"
// Helper functions -----------------------------------------------------------
static void shuffle(int *choices, int nchoices)
{
int i, j, t;
if (nchoices > 1) {
for (i = 0; i < nchoices; i++) {
j = rand() / (RAND_MAX / nchoices + 1);
t = choices[j];
choices[j] = choices[i];
choices[i] = t;
}
}
}
// go through cards, return index of first playable
static int choose_first_playable_from(const struct card_t cards[],
const int ncards, const struct player_helper_t *helper)
{
int i;
for (i = 0; i < ncards; i++)
if (can_lay(&cards[i], helper->pile, helper->pile_size))
return i;
return -1;
}
// add cards of same rank to choice, assume cards are sorted
static void add_similar_from_sorted(const struct card_t cards[], const int ncards,
const struct card_t *first, int choices[], int *nchoices)
{
int i;
int found = FALSE;
for (i = 0; i < ncards; i++) {
if (ranks_equal(&cards[i], first)) {
choices[*nchoices] = i;
(*nchoices)++;
found = TRUE;
} else if (found) {
break;
}
}
}
// add cards of same rank to choice, assume cards are unsorted
static void add_similar_from_unsorted(const struct card_t cards[], const int ncards,
const struct card_t *first, int choices[], int *nchoices)
{
int i;
for (i = 0; i < ncards; i++) {
if (ranks_equal(&cards[i], first)) {
choices[*nchoices] = i;
(*nchoices)++;
}
}
}
// Function callable by players -----------------------------------------------
// choose all lowest cards of same rank, assumes cards already sorted
void choose_lowest_from_sorted(const struct card_t cards[], const int ncards,
const struct player_helper_t *helper, int choices[], int *nchoices)
{
int first = choose_first_playable_from(cards, ncards, helper);
add_similar_from_sorted(cards, ncards, &cards[first], choices, nchoices);
}
// choose all lowest cards of same rank, assumes cards not sorted
void choose_lowest_from_unsorted(const struct card_t cards[], const int ncards,
const struct player_helper_t *helper, int choices[], int *nchoices)
{
struct card_t sorted[ncards];
int i;
for (i = 0; i<ncards; i++)
sorted[i] = cards[i];
sort_cards(sorted, ncards);
int first = choose_first_playable_from(sorted, ncards, helper);
add_similar_from_unsorted(cards, ncards, &sorted[first], choices, nchoices);
}
// choose randomly cards of same rank, assumes cards are sorted
void choose_random_from_sorted(const struct card_t cards[], const int ncards,
const struct player_helper_t *helper, int choices[], int *nchoices)
{
int i;
int possible_choices[ncards];
for (i = 0; i < ncards; i++) {
possible_choices[i] = i;
}
shuffle(possible_choices, ncards);
int first = 0;
for (i = 0; i < ncards; i++) {
if (can_lay(&cards[possible_choices[i]], helper->pile, helper->pile_size)) {
first = possible_choices[i];
break;
}
}
add_similar_from_sorted(cards, ncards, &cards[first], choices, nchoices);
}
void choose_random_from_unsorted(const struct card_t cards[], const int ncards,
const struct player_helper_t *helper, int choices[], int *nchoices)
{
int first = choose_first_playable_from(cards, ncards, helper);
add_similar_from_unsorted(cards, ncards, &cards[first], choices, nchoices);
}
// chooses burn cards, or nothing if none, assumes cards already sorted
void choose_burn_from_sorted(const struct card_t cards[], const int ncards,
const struct player_helper_t *helper, int choices[], int *nchoices)
{
int i;
for (i = ncards-1; i>=0 ; i--) {
if (cards[i].rank == BURN) {
choices[*nchoices] = i;
(*nchoices)++;
} else if (!special_card(&cards[i])) {
break;
}
}
}
// chooses burn cards, or nothing if none, assumes cards not sorted
void choose_burn_from_unsorted(const struct card_t cards[], const int ncards,
const struct player_helper_t *helper, int choices[], int *nchoices)
{
int i;
for (i = 0; i < ncards; i++) {
if (cards[i].rank == BURN) {
choices[*nchoices] = i;
(*nchoices)++;
}
}
}