|
@ -2,6 +2,8 @@ |
|
|
#include <stdio.h> |
|
|
#include <stdio.h> |
|
|
#include <stdlib.h> |
|
|
#include <stdlib.h> |
|
|
#include <string.h> |
|
|
#include <string.h> |
|
|
|
|
|
#include <queue> |
|
|
|
|
|
#include <set> |
|
|
#include <vector> |
|
|
#include <vector> |
|
|
#include <cassert> |
|
|
#include <cassert> |
|
|
|
|
|
|
|
@ -223,7 +225,93 @@ State* state; |
|
|
|
|
|
|
|
|
// Algoritmy
|
|
|
// Algoritmy
|
|
|
|
|
|
|
|
|
// main (zde doplňte kód)
|
|
|
// otoč směr podle jiného otočení
|
|
|
|
|
|
Direction combine_directions(Direction a, Direction b) |
|
|
|
|
|
{ |
|
|
|
|
|
if (a == STAY || b == STAY) |
|
|
|
|
|
{ |
|
|
|
|
|
fprintf(stderr, "Nelze kombinovat se STAY."); |
|
|
|
|
|
exit(1); |
|
|
|
|
|
} |
|
|
|
|
|
return (Direction) ((a + b) % 4); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// získej opačný směr
|
|
|
|
|
|
Direction invert_direction(Direction a) |
|
|
|
|
|
{ |
|
|
|
|
|
if (a == STAY) return STAY; |
|
|
|
|
|
return combine_directions(a, DOWN); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// další políčko v daném směru
|
|
|
|
|
|
Field* get_neighbour_field(Field* f, Direction direction) |
|
|
|
|
|
{ |
|
|
|
|
|
int neighbour_i, neighbour_j; |
|
|
|
|
|
switch (direction) |
|
|
|
|
|
{ |
|
|
|
|
|
case UP: |
|
|
|
|
|
neighbour_i = f->i - 1; |
|
|
|
|
|
neighbour_j = f->j; |
|
|
|
|
|
break; |
|
|
|
|
|
case DOWN: |
|
|
|
|
|
neighbour_i = f->i + 1; |
|
|
|
|
|
neighbour_j = f->j; |
|
|
|
|
|
break; |
|
|
|
|
|
case LEFT: |
|
|
|
|
|
neighbour_i = f->i; |
|
|
|
|
|
neighbour_j = f->j - 1; |
|
|
|
|
|
break; |
|
|
|
|
|
case RIGHT: |
|
|
|
|
|
neighbour_i = f->i; |
|
|
|
|
|
neighbour_j = f->j + 1; |
|
|
|
|
|
break; |
|
|
|
|
|
default: |
|
|
|
|
|
neighbour_i = f->i; |
|
|
|
|
|
neighbour_j = f->j; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// zajisti, aby souřadnice byly v rozsahu herní plochy
|
|
|
|
|
|
neighbour_i %= state->world.size(); |
|
|
|
|
|
neighbour_j %= state->world[0].size(); |
|
|
|
|
|
return state->world[neighbour_i][neighbour_j]; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// jestli daný tým může vstoupit na políčko
|
|
|
|
|
|
bool is_field_accessible(Field* f, Team* t) |
|
|
|
|
|
{ |
|
|
|
|
|
if (f->hill) return false; |
|
|
|
|
|
if (f->occupied_by_team != NULL && f->occupied_by_team != t) return false; |
|
|
|
|
|
return true; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// Najdi nejkratší cestu od vojáka k cílovému políčku.
|
|
|
|
|
|
// Vrátí první krok, který má voják udělat.
|
|
|
|
|
|
// Pokud žádná cesta neexistuje, vrátí STAY.
|
|
|
|
|
|
Direction pathfind(Member* m, Field* goal) |
|
|
|
|
|
{ |
|
|
|
|
|
std::set<Field*> explored; |
|
|
|
|
|
std::queue<Field*> queue; |
|
|
|
|
|
queue.push(goal); |
|
|
|
|
|
auto dirs = {UP, LEFT, DOWN, RIGHT}; |
|
|
|
|
|
while (!queue.empty()) |
|
|
|
|
|
{ |
|
|
|
|
|
auto field = queue.front(); |
|
|
|
|
|
queue.pop(); |
|
|
|
|
|
for (auto direction : dirs) |
|
|
|
|
|
{ |
|
|
|
|
|
auto neighbour = get_neighbour_field(field, direction); |
|
|
|
|
|
if (explored.find(neighbour) != explored.end()) continue; |
|
|
|
|
|
if (!is_field_accessible(neighbour, m->team)) continue; |
|
|
|
|
|
// pokud jsme našli vojáka, vrátíme první krok
|
|
|
|
|
|
if (neighbour == m->field) return invert_direction(direction); |
|
|
|
|
|
queue.push(neighbour); |
|
|
|
|
|
explored.insert(neighbour); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
return STAY; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// Strategie
|
|
|
|
|
|
|
|
|
int main() |
|
|
int main() |
|
|
{ |
|
|
{ |
|
@ -231,7 +319,7 @@ int main() |
|
|
scanf("%m[^\n]", &input_str); |
|
|
scanf("%m[^\n]", &input_str); |
|
|
state = new State(input_str); |
|
|
state = new State(input_str); |
|
|
|
|
|
|
|
|
// TODO sem patří herní logika
|
|
|
// TODO: zde doplňte svou herní strategii
|
|
|
for(Member *m: state->my_team->members) |
|
|
for(Member *m: state->my_team->members) |
|
|
m->action = UP; |
|
|
m->action = UP; |
|
|
|
|
|
|
|
|