G

Traffic Simulation

public
Guest Nov 20, 2024 Never 35
Clone
C++ main.cpp 577 lines (535 loc) | 15.05 KB
1
#include <stdio.h>
2
#include <fstream>
3
#include <algorithm>
4
#include <cmath>
5
6
static unsigned long long seed = 5;
7
8
static int pseudo_rand(void)
9
{
10
seed = seed * 25214903917ULL + 11ULL;
11
return (seed >> 16) & 0x3fffffff;
12
}
13
14
static const long long PENALTY = 10'000'000'000'000LL;
15
static const int MAX_TC = 1;
16
static const int MAXN = 1000;
17
static const int MAXM = 1000;
18
static const int ROAD_CNT = 100;
19
20
static const int UP = 0;
21
static const int RIGHT = 1;
22
static const int DOWN = 2;
23
static const int LEFT = 3;
24
25
static const int TURN_LEFT = 3;
26
static const int TURN_RIGHT = 1;
27
static const int GO_STRAIGHT = 0;
28
29
static const int UPLEFT = 1;
30
static const int RIGHTUP = 2;
31
static const int DOWNRIGHT = 3;
32
static const int LEFTDOWN = 4;
33
static const int VERTICAL = 5;
34
static const int HORIZONTAL = 6;
35
36
struct Coordinates
37
{
38
int y, x;
39
Coordinates()
40
{
41
y = x = 0;
42
}
43
Coordinates(int y_, int x_)
44
{
45
y = y_;
46
x = x_;
47
}
48
};
49
50
struct TrafficSignal
51
{
52
int signal, next_signal;
53
TrafficSignal()
54
{
55
signal = next_signal = 0;
56
}
57
};
58
59
struct Vehicle
60
{
61
int x, y, dir, dest_y, dest_x;
62
};
63
64
static Coordinates src[ROAD_CNT*2], dest[ROAD_CNT*2];
65
static int map[MAXN][MAXM], crossroad_id[MAXN][MAXM];
66
static TrafficSignal signal_list[ROAD_CNT*ROAD_CNT];
67
static Vehicle vehicles[MAXN];
68
static int vehicle_on_map[MAXN][MAXM];
69
static int is_movable[MAXN];
70
static int turn_dir[MAXN];
71
static int K, L;
72
73
static int map_bak[MAXN][MAXM], crossroad_id_bak[MAXN][MAXM];
74
static Vehicle vehicles_bak[MAXN];
75
76
int dy[4] = {-1, 0, 1, 0};
77
int dx[4] = {0, 1, 0, -1};
78
79
static int min_x, min_y, max_x, max_y;
80
81
void change_signal(int cross_id, int next_signal)
82
{
83
if (next_signal <= 0 || next_signal > 6) return;
84
signal_list[cross_id].signal = 0;
85
signal_list[cross_id].next_signal = next_signal;
86
}
87
88
static void make_tc() {
89
K = 0, L = 0;
90
min_y = MAXN-1, max_y = 0;
91
min_x = MAXM-1, max_x = 0;
92
for (int y = 0; y < MAXM; y++)
93
{
94
for (int x = 0; x < MAXM; x++)
95
{
96
crossroad_id[y][x] = 0;
97
map[y][x] = 0;
98
}
99
}
100
101
for (int i = 0; i < ROAD_CNT; i++)
102
{
103
int dir = pseudo_rand() % 2;
104
if (dir == 0)
105
{
106
int y = pseudo_rand() % (MAXM - 200) + 100;
107
if(map[y-1][0] == 1 || map[y][0] == 1 || map[y+1][0] == 1 || map[y+2][0] == 1) continue;
108
109
for (int x = 0; x < MAXM; x++)
110
{
111
map[y][x] = map[y + 1][x] = 1;
112
}
113
src[K] = Coordinates(y + 1, 0);
114
dest[K++] = Coordinates(y, 0);
115
src[K] = Coordinates(y, MAXM - 1);
116
dest[K++] = Coordinates(y + 1, MAXM - 1);
117
if (min_y > y) min_y = y;
118
if (max_y < y) max_y = y;
119
}
120
// Similar for vertical roads
121
else
122
{
123
int x = pseudo_rand() % (MAXM - 200) + 100;
124
if(map[0][x-1] == 1 || map[0][x] == 1 || map[0][x+1] == 1 || map[0][x+2] == 1)
125
continue;
126
for (int y = 0; y < MAXM; y++)
127
{
128
map[y][x] = map[y][x + 1] = 1;
129
}
130
src[K] = Coordinates(0, x);
131
dest[K++] = Coordinates(0, x+1);
132
src[K] = Coordinates(MAXM - 1, x+1);
133
dest[K++] = Coordinates(MAXM - 1, x);
134
if (min_x > x) min_x = x;
135
if (max_x < x) max_x = x;
136
}
137
}
138
139
L = 0;
140
for (int y = 100; y < MAXM - 100; y++)
141
{
142
if (map[y - 1][0] == 0 && map[y][0] == 1)
143
{
144
for (int x = 100; x < MAXM-100; x++)
145
{
146
if (map[y-1][x] == 1 && map[y-1][x-1] == 0)
147
{
148
L++;
149
crossroad_id[y][x] = crossroad_id[y+1][x] = crossroad_id[y][x+1] = crossroad_id[y+1][x+1] = L;
150
signal_list[L].signal = signal_list[L].next_signal = 1;
151
}
152
}
153
}
154
}
155
156
for (int i = MAXN - 1; i >= 0; i--)
157
{
158
int src_idx = 0, dest_idx = 0;
159
do {
160
src_idx = pseudo_rand() % K;
161
dest_idx = pseudo_rand() % K;
162
} while (src_idx == dest_idx);
163
vehicles[i].y = src[src_idx].y;
164
vehicles[i].x = src[src_idx].x;
165
vehicles[i].dest_y = dest[dest_idx].y;
166
vehicles[i].dest_x = dest[dest_idx].x;
167
if(vehicles[i].y < 100)
168
{
169
src[src_idx].y++;
170
vehicles[i].dir = DOWN;
171
}
172
else if(vehicles[i].y >= MAXM - 100)
173
{
174
src[src_idx].y--;
175
vehicles[i].dir = UP;
176
}
177
else if(vehicles[i].x < 100)
178
{
179
src[src_idx].x++;
180
vehicles[i].dir = RIGHT;
181
}
182
else if(vehicles[i].x >= MAXM - 100)
183
{
184
src[src_idx].x--;
185
vehicles[i].dir = LEFT;
186
}
187
}
188
for(int y = 0; y < MAXN; y++)
189
{
190
for(int x = 0; x < MAXM; x++)
191
{
192
vehicle_on_map[y][x] = 0;
193
map_bak[y][x] = map[y][x];
194
crossroad_id_bak[y][x] = crossroad_id[y][x];
195
}
196
}
197
198
for(int i = 0; i < MAXN; i++)
199
{
200
vehicles_bak[i] = vehicles[i];
201
vehicle_on_map[vehicles[i].y][vehicles[i].x] = 1;
202
}
203
}
204
205
static int get_nextdir(Vehicle& tar)
206
{
207
int dir = tar.dir;
208
int y = tar.y;
209
int x = tar.x;
210
int dest_y = tar.dest_y;
211
int dest_x = tar.dest_x;
212
int next_y = y + dy[dir];
213
int next_x = x + dx[dir];
214
if(dest_y < next_y - 1)
215
{
216
if(dest_x < next_x - 1)
217
{
218
if(dir == RIGHT)
219
{
220
return TURN_LEFT;
221
}
222
else if(dir == DOWN)
223
{
224
return TURN_RIGHT;
225
}
226
else if(dir == UP)
227
{
228
if(next_y <= min_y + 1)
229
{
230
return TURN_LEFT;
231
}
232
}
233
else if(dir == LEFT)
234
{
235
if(next_x <= min_x + 1)
236
{
237
return TURN_RIGHT;
238
}
239
}
240
}
241
else if(dest_x > next_x + 1)
242
{
243
if(dir == RIGHT)
244
{
245
if(next_x > max_x - 1)
246
{
247
return TURN_LEFT;
248
}
249
}
250
else if(dir == DOWN)
251
{
252
return TURN_LEFT;
253
}
254
else if(dir == UP)
255
{
256
if(next_y <= min_y + 1)
257
{
258
return TURN_RIGHT;
259
}
260
}
261
else if(dir == LEFT)
262
{
263
return TURN_RIGHT;
264
}
265
}
266
else
267
{
268
if(dir == RIGHT)
269
{
270
return TURN_LEFT;
271
}
272
else if(dir == LEFT)
273
{
274
return TURN_RIGHT;
275
}
276
}
277
}
278
else if(dest_y > next_y + 1)
279
{
280
if(dest_x < next_x - 1)
281
{
282
if(dir == RIGHT)
283
{
284
return TURN_RIGHT;
285
}
286
else if(dir == DOWN)
287
{
288
if(next_y > max_y - 1)
289
{
290
return TURN_RIGHT;
291
}
292
}
293
else if(dir == UP)
294
{
295
return TURN_LEFT;
296
}
297
else if(dir == LEFT)
298
{
299
if(next_x <= min_x + 1)
300
{
301
return TURN_LEFT;
302
}
303
}
304
}
305
else if(dest_x > next_x + 1)
306
{
307
if(dir == RIGHT)
308
{
309
if(next_x > max_x - 1)
310
{
311
return TURN_RIGHT;
312
}
313
}
314
else if(dir == DOWN)
315
{
316
if(next_y > max_y - 1)
317
{
318
return TURN_LEFT;
319
}
320
}
321
else if(dir == UP)
322
{
323
return TURN_RIGHT;
324
}
325
else if(dir == LEFT)
326
{
327
return TURN_LEFT;
328
}
329
}
330
else
331
{
332
if(dir == RIGHT)
333
{
334
return TURN_RIGHT;
335
}
336
else if(dir == LEFT)
337
{
338
return TURN_LEFT;
339
}
340
}
341
}
342
else
343
{
344
if(dest_x < next_x - 1)
345
{
346
if(dir == UP)
347
{
348
return TURN_LEFT;
349
}
350
else if(dir == DOWN)
351
{
352
return TURN_RIGHT;
353
}
354
}
355
else if(dest_x > next_x + 1)
356
{
357
if(dir == UP)
358
{
359
return TURN_RIGHT;
360
}
361
else if(dir == DOWN)
362
{
363
return TURN_LEFT;
364
}
365
}
366
}
367
return GO_STRAIGHT;
368
}
369
370
void move_vehicles() {
371
for(int i = 0; i < MAXN; i++)
372
{
373
is_movable[i] = 0;
374
}
375
376
for (int i = 0; i < MAXN; i++)
377
{
378
int x = vehicles[i].x;
379
int y = vehicles[i].y;
380
int dir = vehicles[i].dir;
381
int next_x = x + dx[dir];
382
int next_y = y + dy[dir];
383
384
if(vehicles[i].dest_x == x && vehicles[i].dest_y == y)
385
{
386
continue;
387
}
388
389
if(vehicle_on_map[next_y][next_x] == 1)
390
{
391
continue;
392
}
393
394
if(crossroad_id[next_y][next_x] == 0)
395
{
396
is_movable[i] = 1;
397
}
398
else
399
{
400
if(crossroad_id[y][x] == 0)
401
{
402
int signal = signal_list[crossroad_id[next_y][next_x]].signal;
403
turn_dir[i] = get_nextdir(vehicles[i]);
404
if(turn_dir[i] == TURN_RIGHT)
405
{
406
is_movable[i] = 1;
407
}
408
else
409
{
410
if(dir == UP && signal == UPLEFT)
411
{
412
is_movable[i] = 1;
413
}
414
else if(dir == RIGHT && signal == RIGHTUP)
415
{
416
is_movable[i] = 1;
417
}
418
else if(dir == DOWN && signal == DOWNRIGHT)
419
{
420
is_movable[i] = 1;
421
}
422
else if(dir == LEFT && signal == LEFTDOWN)
423
{
424
is_movable[i] = 1;
425
}
426
427
if(turn_dir[i] == GO_STRAIGHT)
428
{
429
if(dir == UP || dir == DOWN)
430
{
431
if(signal == VERTICAL)
432
{
433
is_movable[i] = 1;
434
}
435
}
436
else
437
{
438
if(signal == HORIZONTAL)
439
{
440
is_movable[i] = 1;
441
}
442
}
443
}
444
}
445
}
446
else
447
{
448
is_movable[i] = 1;
449
}
450
}
451
452
}
453
454
for (int i = 0; i < MAXN; i++) {
455
if (!is_movable[i]) continue;
456
457
int x = vehicles[i].x;
458
int y = vehicles[i].y;
459
int dir = vehicles[i].dir;
460
int next_x = x + dx[dir];
461
int next_y = y + dy[dir];
462
463
if (vehicle_on_map[next_y][next_x] == 0)
464
{
465
vehicle_on_map[y][x] = 0;
466
vehicle_on_map[next_y][next_x] = 1;
467
vehicles[i].x = next_x;
468
vehicles[i].y = next_y;
469
470
if(turn_dir[i] == TURN_RIGHT)
471
{
472
vehicles[i].dir = (dir + 1) % 4;
473
turn_dir[i] = GO_STRAIGHT;
474
}
475
else if(turn_dir[i] == TURN_LEFT)
476
{
477
int next_dir = (dir + 3) % 4;
478
if(next_dir == UP)
479
{
480
if(map[next_y + 1][next_x + 1] == 0)
481
{
482
vehicles[i].dir = next_dir;
483
turn_dir[i] = GO_STRAIGHT;
484
}
485
}
486
else if(next_dir == RIGHT)
487
{
488
if(map[next_y + 1][next_x - 1] == 0)
489
{
490
vehicles[i].dir = next_dir;
491
turn_dir[i] = GO_STRAIGHT;
492
}
493
}
494
else if(next_dir == DOWN)
495
{
496
if(map[next_y - 1][next_x - 1] == 0)
497
{
498
vehicles[i].dir = next_dir;
499
turn_dir[i] = GO_STRAIGHT;
500
}
501
}
502
else if(next_dir == LEFT)
503
{
504
if(map[next_y - 1][next_x + 1] == 0)
505
{
506
vehicles[i].dir = next_dir;
507
turn_dir[i] = GO_STRAIGHT;
508
}
509
}
510
}
511
512
// Check if the vehicle has reached its destination
513
if (vehicles[i].x == vehicles[i].dest_x && vehicles[i].y == vehicles[i].dest_y) {
514
vehicle_on_map[vehicles[i].y][vehicles[i].x] = 0;
515
}
516
}
517
}
518
519
// Update signals for crossroads
520
for(int i = 0; i < L; i++)
521
{
522
signal_list[i].signal = signal_list[i].next_signal;
523
}
524
}
525
526
bool verify()
527
{
528
for(int i = 0; i < MAXN; i++)
529
{
530
if(vehicles[i].x != vehicles[i].dest_x || vehicles[i].y != vehicles[i].dest_y)
531
{
532
return false;
533
}
534
}
535
return true;
536
}
537
538
extern void init(int N, int map[][MAXM], int crossroad_id[][MAXM], Vehicle vehicles[MAXN]);
539
extern bool process();
540
541
int main()
542
{
543
long long gTotalScore = 0;
544
for(int i = 0; i < MAX_TC; i++)
545
{
546
make_tc();
547
std::ofstream game_state_file("game_state.txt");
548
if (game_state_file.is_open()) {
549
game_state_file << "Vehicles:\n";
550
for (int i = 0; i < MAXN; i++) {
551
game_state_file << "Vehicle " << i << ": (" << vehicles_bak[i].y << ", " << vehicles_bak[i].x << ") -> ("
552
<< vehicles_bak[i].dest_y << ", " << vehicles_bak[i].dest_x << "), dir: " << vehicles_bak[i].dir << "\n";
553
}
554
game_state_file.close();
555
} else {
556
printf("Unable to open file game_state.txt");
557
}
558
559
init(MAXM, map_bak, crossroad_id_bak, vehicles_bak);
560
561
bool is_finished = false;
562
563
while(is_finished == false)
564
{
565
is_finished = process();
566
move_vehicles();
567
gTotalScore++;
568
}
569
570
if(verify() == false)
571
{
572
gTotalScore = PENALTY;
573
}
574
}
575
576
printf("%lld\n", gTotalScore);
577
}