-
Notifications
You must be signed in to change notification settings - Fork 1
/
Father.c
318 lines (304 loc) · 11.3 KB
/
Father.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
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
#include "Father.h"
int main(int argc, char* argv[])
{
if (argc < 2) {
printf("Not enough arguments.\n");
exit(1);
}
FILE* file_pointer = NULL;
if (fopen_s(&file_pointer, argv[1], "r") != 0)
{
printf("couldn't read file");
exit(1);
}
char* line = malloc(sizeof(char) * 10); // as said on the forum, we assume the numbers in the first lines has less then 10 di
int num_of_gens = 0, forest_size = 0;
// get the first 2 lines (size of forest and generations) and convert them to int
fgets(line, sizeof(line), file_pointer);
forest_size = atoi(line);
fgets(line, sizeof(line), file_pointer);
num_of_gens = atoi(line);
free(line);
int num_of_trees = forest_size * forest_size;
char* forest = get_forest(num_of_trees, file_pointer);
fclose(file_pointer);
create_output_file(forest, num_of_gens, forest_size);
return 0;
}
char* get_forest(int num_of_trees, FILE* file_pointer) {
// the function gets the number of trees in the forest and the file pointer
// and returns the forest as a string
char* forest = malloc((num_of_trees + 1) * sizeof(char));
char current_char;
int i = 0;
while ((current_char = (char)fgetc(file_pointer)) != EOF) {
if (current_char != ',' && current_char != '\n') {
forest[i] = current_char;
i++;
}
}
forest[i] = '\0';
return forest;
}
int call_process(char* command_line) {
// calls a process using the given commad line
int buffer_size = (1 + strlen(command_line)); // one more space is needed for wchar_t conversion
STARTUPINFO startinfo = { sizeof(STARTUPINFO), NULL, 0 };
PROCESS_INFORMATION pi;
PROCESS_INFORMATION* ProcessInfoPtr = π
DWORD exit_code;
WCHAR *w_command_line = malloc(buffer_size * sizeof(WCHAR));
size_t w_command_line_size;
mbstowcs_s(&w_command_line_size, w_command_line, buffer_size, command_line, buffer_size);
if (!CreateProcess(NULL, w_command_line, NULL, NULL, FALSE, NORMAL_PRIORITY_CLASS, NULL, NULL, &startinfo, ProcessInfoPtr))
{
printf("Failed to create process (%d).\n", GetLastError());
return FAILURE_CODE;
}
// Wait until son.exe exits.
WaitForSingleObject(pi.hProcess, INFINITE);
GetExitCodeProcess(pi.hProcess, &exit_code);
free(w_command_line);
return (int)exit_code;
}
int get_num_of_burned(char* forest) {
// this function calculates the number of burned trees in the furest using son.exe
//it creates the needed command line and calls call_process to run it
int burned_trees_num = 0, command_size = strlen(forest) + COMMAND_CHARECTERS;
char *command_line = malloc(command_size * sizeof(char));
snprintf(command_line, command_size, "Son.exe %s", forest);
burned_trees_num = call_process(command_line);
if (burned_trees_num == FAILURE_CODE) {
return FAILURE_CODE;
}
free(command_line);
return burned_trees_num;
}
int write_to_file(FILE* file_ptr, char* line) {
// this function writes the given line to the given file
if (EOF == fputs(line, file_ptr))
{
printf("Failed to write to file.\n");
if (fclose(file_ptr) != 0)
{
printf("Failed to close file.\n");
return FAILURE_CODE;
}
return FAILURE_CODE;
}
return SUCCESS_CODE;
}
int create_output_file(char* forest, int num_of_gens, int forest_size) {
// this function creates output.txt and calles all necessary functions in order to do so
FILE* file_pointer = NULL;
if (fopen_s(&file_pointer, "output.txt", "w") != 0) {
printf("couldn't open file");
exit(1);
}
for (int i = 0; i < num_of_gens; i++)
{
int num_of_burned = get_num_of_burned(forest);
int num_length = snprintf(NULL, 0, "%d", num_of_burned);
int line_size = num_length + strlen(forest) + EXRTA_CHARECTERS;
char* line = malloc((line_size) * sizeof(char));
snprintf(line, line_size, "%s - %d\n", forest, num_of_burned);
write_to_file(file_pointer, line);
forest = forest_next_step(forest_size, forest);
}
if (fclose(file_pointer) != 0)
{
printf("Failed to close file.\n");
return FAILURE_CODE;
}
free(forest);
return SUCCESS_CODE;
}
char* forest_next_step(int forest_size, char* forest_string)//creates another "board"/forest on which we will update the progression after one iteration
{
char* next_step_forest = (char*)malloc(((forest_size * forest_size) + 1) * sizeof(char));
char neighbours_plus[4];//neighbours above, below, left, right
char neighbours_total[8];//neighbours above, below, left, right and diagonally
int i, num_neighbours_total_in_array, num_neighbours_plus_in_array; //num_neighbours= how many neighbours exist for a cell. for example, the top corner only has 2 "plus" neighbours (out of the array whose size is 4, and only 3 total neighbours out of the array whose size is 8)
if (forest_size == 1)
{
return forest_string;
}
for (i = 0; i < (forest_size * forest_size); i++)
{
Get_neighbours(i, forest_string, forest_size, neighbours_total, neighbours_plus, &num_neighbours_total_in_array, &num_neighbours_plus_in_array);
Check_neighbours_and_update_cell(i, forest_string, neighbours_total, neighbours_plus, &num_neighbours_total_in_array, &num_neighbours_plus_in_array, next_step_forest);
}
next_step_forest[forest_size * forest_size] = '\0';
free(forest_string);
return next_step_forest;
}
void Get_neighbours(int i, char* forest_string, int forest_size, char* neighbours_total, char* neighbours_plus_shape, int* num_total, int* num_plus)//checks how many neighbours exist in "plus" shape, and in total (including diagonal neighbours)
{
if (top_row(i, forest_size))
{
if (left_column(i, forest_size)) //top left corner
{
neighbours_plus_shape[0] = forest_string[i + 1];
neighbours_plus_shape[1] = forest_string[i + forest_size];
*num_plus = 2;//how many neighbours above, below, to the right or left there are for each cell (out of 4 maximum)
neighbours_total[0] = forest_string[i + 1];
neighbours_total[1] = forest_string[i + forest_size];
neighbours_total[2] = forest_string[i + forest_size + 1];
*num_total = 3;//how many neighbours above, below,diagonally or to the right or left there are for each cell (out of 8 maximum)
}
else if (right_column(i, forest_size)) //top right corner
{
neighbours_plus_shape[0] = forest_string[i + forest_size];
neighbours_plus_shape[1] = forest_string[i - 1];
*num_plus = 2;
neighbours_total[0] = forest_string[i + forest_size];
neighbours_total[1] = forest_string[i - 1];
neighbours_total[2] = forest_string[i + forest_size - 1];
*num_total = 3;
}
else //top row but not corner
{
neighbours_plus_shape[0] = forest_string[i + 1];
neighbours_plus_shape[1] = forest_string[i + forest_size];
neighbours_plus_shape[2] = forest_string[i - 1];
*num_plus = 3;
neighbours_total[0] = forest_string[i + 1];
neighbours_total[1] = forest_string[i + forest_size];
neighbours_total[2] = forest_string[i - 1];
neighbours_total[3] = forest_string[i + forest_size - 1];
neighbours_total[4] = forest_string[i + forest_size + 1];
*num_total = 5;
}
}
else if (bottom_row(i, forest_size))
{
if (left_column(i, forest_size)) //bottom left corner
{
neighbours_plus_shape[0] = forest_string[i + 1];
neighbours_plus_shape[1] = forest_string[i - forest_size];
*num_plus = 2;
neighbours_total[0] = forest_string[i + 1];
neighbours_total[1] = forest_string[i - forest_size];
neighbours_total[2] = forest_string[i - forest_size + 1];
*num_total = 3;
}
else if (right_column(i, forest_size)) //bottom right corner
{
neighbours_plus_shape[0] = forest_string[i - forest_size];
neighbours_plus_shape[1] = forest_string[i - 1];
*num_plus = 2;
neighbours_total[0] = forest_string[i - forest_size];
neighbours_total[1] = forest_string[i - 1];
neighbours_total[2] = forest_string[i - forest_size - 1];
*num_total = 3;
}
else //bottom row but not corner
{
neighbours_plus_shape[0] = forest_string[i + 1];
neighbours_plus_shape[1] = forest_string[i - forest_size];
neighbours_plus_shape[2] = forest_string[i - 1];
*num_plus = 3;
neighbours_total[0] = forest_string[i + 1];
neighbours_total[1] = forest_string[i - forest_size];
neighbours_total[2] = forest_string[i - 1];
neighbours_total[3] = forest_string[i - forest_size - 1];
neighbours_total[4] = forest_string[i - forest_size + 1];
*num_total = 5;
}
}
else if (left_column(i, forest_size)) //but not the corners
{
neighbours_plus_shape[0] = forest_string[i + 1];
neighbours_plus_shape[1] = forest_string[i - forest_size];
neighbours_plus_shape[2] = forest_string[i + forest_size];
*num_plus = 3;
neighbours_total[0] = forest_string[i + 1];
neighbours_total[1] = forest_string[i - forest_size];
neighbours_total[2] = forest_string[i + forest_size];
neighbours_total[3] = forest_string[i - forest_size + 1];
neighbours_total[4] = forest_string[i + forest_size + 1];
*num_total = 5;
}
else if (right_column(i, forest_size)) //but not the corners
{
neighbours_plus_shape[0] = forest_string[i - 1];
neighbours_plus_shape[1] = forest_string[i - forest_size];
neighbours_plus_shape[2] = forest_string[i + forest_size];
*num_plus = 3;
neighbours_total[0] = forest_string[i - 1];
neighbours_total[1] = forest_string[i - forest_size];
neighbours_total[2] = forest_string[i + forest_size];
neighbours_total[3] = forest_string[i - forest_size - 1];
neighbours_total[4] = forest_string[i + forest_size - 1];
*num_total = 5;
}
else// not on the borders of the forest
{
neighbours_plus_shape[0] = forest_string[i + 1];
neighbours_plus_shape[1] = forest_string[i - forest_size];
neighbours_plus_shape[2] = forest_string[i - 1];
neighbours_plus_shape[3] = forest_string[i + forest_size];
*num_plus = 4;
neighbours_total[0] = forest_string[i + 1];
neighbours_total[1] = forest_string[i - forest_size];
neighbours_total[2] = forest_string[i + forest_size];
neighbours_total[3] = forest_string[i - 1];
neighbours_total[4] = forest_string[i - forest_size - 1];
neighbours_total[5] = forest_string[i - forest_size + 1];
neighbours_total[6] = forest_string[i + forest_size - 1];
neighbours_total[7] = forest_string[i + forest_size + 1];
*num_total = 8;
}
}
bool top_row(int i, int forest_size)
{
return (i / forest_size == 0);
}
bool bottom_row(int i, int forest_size)
{
return (i / forest_size == forest_size - 1);
}
bool left_column(int i, int forest_size)
{
return (i % forest_size == 0);
}
bool right_column(int i, int forest_size)
{
return (i % forest_size == forest_size - 1);
}
void Check_neighbours_and_update_cell(int i, char* forest_string, char* neighbours_total, char* neighbours_plus_shape, int* num_total, int* num_plus, char* next_step_forest)
{
int j, tree_count = 0, no_fire_around_tree = 1;
if (forest_string[i] == 'F')
{
next_step_forest[i] = 'G';
}
else if (forest_string[i] == 'T')
{
for (j = 0; j < *num_plus; j++)
{
if (neighbours_plus_shape[j] == 'F')
{
no_fire_around_tree = 0;
}
}
if (no_fire_around_tree == 1)// there is no fire around the tree
next_step_forest[i] = 'T';
else//there is fire next to the tree
next_step_forest[i] = 'F';
}
else// forest_string[i] = 'G'
{
for (j = 0; j < *num_total; j++)
{
if (neighbours_total[j] == 'T')
{
tree_count++;
}
}
if (tree_count > 1)
next_step_forest[i] = 'T';
else
next_step_forest[i] = 'G';
}
}