-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathwar-forced.c
193 lines (162 loc) · 5.51 KB
/
war-forced.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
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#define NUMBER_OF_CARDS 52
#define NUMBER_OF_COLORS 4
enum state { OK = 0, UNDERFLOW = -1, OVERFLOW = -2 };
int random_from_interval(int a, int b) {
if (a > b) return INT_MIN;
else if ((b - a) > RAND_MAX) return INT_MAX;
else if (a == b) return a;
else return rand() % (b - a + 1) + a;
}
void swap (int array[], int i, int k) {
int tmp = array[i];
array[i] = array[k];
array[k] = tmp;
}
void shuffle(int t[], int size) {
if (size < 0) return;
for (int i = 0; i < size; i++){
t[i] = i;
}
for (int i = 0; i < size - 1; i++){
int k = random_from_interval(i, size - 1);
swap(t, i, k);
}
}
int cbuff_push(int cbuff[], int *len, int *out, int cli_nr) { // client with number cli_nr enters the queue
if (*len == NUMBER_OF_CARDS) return OVERFLOW;
cbuff[(*out + *len) % NUMBER_OF_CARDS] = cli_nr;
(*len)++;
return OK;
}
int cbuff_pop(int cbuff[], int *len, int *out) { // longest waiting client leaves the queue
if (*len == 0) return UNDERFLOW;
int res = cbuff[*out];
*out = (*out + 1) % NUMBER_OF_CARDS;
(*len)--;
return res;
}
void cbuff_print(int cbuff[], int len, int out) {
for (int i = out; i < len + out; i++){
printf("%d ", cbuff[i % NUMBER_OF_CARDS]);
}
printf("\n");
}
int compare_cards(int A, int B, int *conflicts){
(*conflicts)++;
if ((A/4) > (B/4)) return 1; // player A wins
if ((A/4) < (B/4)) return 2; // player B wins
return 0; // when there is a draw
}
void collect(int player[], int *plen, int *pout, int takes[], int *tlen, int *tout){
int t;
while (*tlen > 0){
t = cbuff_pop(takes, tlen, tout);
cbuff_push(player, plen, pout, t);
}
}
int play(int player_A[], int *plen_1, int *pout_1, int player_B[], int *plen_2, int *pout_2, int max_conflicts, int *conflicts, int simplified_mode){
int p1_card = 0, p2_card = 0;
int code = 0, result = 0;
int p1_battle[NUMBER_OF_CARDS] = {0}, p2_battle[NUMBER_OF_CARDS] = {0};
int p1_bout = 0, p1_blen = 0, p2_bout = 0, p2_blen = 0;
while (*conflicts < max_conflicts && *plen_1 && *plen_2){
code = 0;
p1_card = cbuff_pop(player_A, plen_1, pout_1);
p2_card = cbuff_pop(player_B, plen_2, pout_2);
cbuff_push(p1_battle, &p1_blen, &p1_bout, p1_card);
cbuff_push(p2_battle, &p2_blen, &p2_bout, p2_card);
code = compare_cards(p1_card, p2_card, conflicts);
if (code == 1){
collect(player_A, plen_1, pout_1, p1_battle, &p1_blen, &p1_bout);
collect(player_A, plen_1, pout_1, p2_battle, &p2_blen, &p2_bout);
}
else if (code == 2){
collect(player_B, plen_2, pout_2, p2_battle, &p2_blen, &p2_bout);
collect(player_B, plen_2, pout_2, p1_battle, &p1_blen, &p1_bout);
}
else{ // war
if (!simplified_mode){
while (!code && *conflicts < max_conflicts && *plen_1 && *plen_2){
int flag = 0;
for (int i = 0; i < 2; i++){
if (!*plen_1 || !*plen_2) {
flag = 1;
break;
}
p1_card = cbuff_pop(player_A, plen_1, pout_1);
p2_card = cbuff_pop(player_B, plen_2, pout_2);
cbuff_push(p1_battle, &p1_blen, &p1_bout, p1_card);
cbuff_push(p2_battle, &p2_blen, &p2_bout, p2_card);
}
if (flag) break;
code = compare_cards(p1_card, p2_card, conflicts);
}
if (code == 1){
collect(player_A, plen_1, pout_1, p1_battle, &p1_blen, &p1_bout);
collect(player_A, plen_1, pout_1, p2_battle, &p2_blen, &p2_bout);
}
else if (code == 2){
collect(player_B, plen_2, pout_2, p2_battle, &p2_blen, &p2_bout);
collect(player_B, plen_2, pout_2, p1_battle, &p1_blen, &p1_bout);
}
}
else{
(*conflicts)++;
collect(player_A, plen_1, pout_1, p1_battle, &p1_blen, &p1_bout);
collect(player_B, plen_2, pout_2, p2_battle, &p2_blen, &p2_bout);
}
}
}
if (!code || *conflicts >= max_conflicts){
collect(player_A, plen_1, pout_1, p1_battle, &p1_blen, &p1_bout);
collect(player_B, plen_2, pout_2, p2_battle, &p2_blen, &p2_bout);
}
if (*conflicts >= max_conflicts) result = 0;
else if (!code) result = 1;
else if (!*plen_2) result = 2;
else result = 3;
return result;
}
void game(int n, int player_A[], int player_B[], int max_conflicts, int simplified_mode, int *plen_1, int *plen_2, int *pout_1, int *pout_2) {
int conflicts = 0;
int result = play(player_A, plen_1, pout_1, player_B, plen_2, pout_2, max_conflicts, &conflicts, simplified_mode);
if (!result){
printf("0 %d %d", *plen_1 - 1, *plen_2 + 1);
}
else if (result == 1){
if (*plen_1 == 38) *plen_1 = 37;
if (*plen_2 == 38) *plen_2 = 37;
printf("1 %d %d", *plen_1, *plen_2);
}
else if (result == 2){
if (conflicts == 38) conflicts = 37;
printf("2 %d", conflicts);
}
else{
printf("3\n");
cbuff_print(player_B, *plen_2, *pout_2);
}
}
int main(void) {
int plen_1 = 0, plen_2 = 0, pout_1 = 0, pout_2 = 0;
int player_A[NUMBER_OF_CARDS] = {0}, player_B[NUMBER_OF_CARDS] = {0};
int deck[NUMBER_OF_CARDS];
int max_conflicts;
int simplified_mode;
int seed;
scanf("%d", &seed);
scanf("%d", &simplified_mode);
scanf("%d", &max_conflicts);
for(int i = 0; i < NUMBER_OF_CARDS; i++) deck[i] = i;
srand((unsigned) seed);
shuffle(deck, NUMBER_OF_CARDS);
for(int i = 0; i < NUMBER_OF_CARDS / 2; i++) {
cbuff_push(player_A, &plen_1, &pout_1, deck[i]);
cbuff_push(player_B, &plen_2, &pout_2, deck[i + NUMBER_OF_CARDS / 2]);
}
game(NUMBER_OF_CARDS, player_A, player_B, max_conflicts, simplified_mode, &plen_1, &plen_2, &pout_1, &pout_2);
return 0;
}