From f04db0468fd777a2ab87a2dc67486de797e5c099 Mon Sep 17 00:00:00 2001 From: kulisak12 Date: Fri, 23 Sep 2022 11:54:58 +0200 Subject: [PATCH] =?UTF-8?q?Strategick=C3=A1:=20Algoritmy=20pro=20C=20verzi?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- klient/client.cpp | 92 +++++++++++++++++++++++++++++++++++++++++++++-- klient/play.py | 4 ++- 2 files changed, 93 insertions(+), 3 deletions(-) diff --git a/klient/client.cpp b/klient/client.cpp index 6fa245f..d793763 100644 --- a/klient/client.cpp +++ b/klient/client.cpp @@ -2,6 +2,8 @@ #include #include #include +#include +#include #include #include @@ -223,7 +225,93 @@ State* state; // 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 explored; + std::queue 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() { @@ -231,7 +319,7 @@ int main() scanf("%m[^\n]", &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) m->action = UP; diff --git a/klient/play.py b/klient/play.py index 319fa62..7916ba1 100755 --- a/klient/play.py +++ b/klient/play.py @@ -207,13 +207,15 @@ def pathfind(member: Member, goal: Field) -> Direction: # a také jednoduše získat první krok explored: Set[Field] = set() queue = collections.deque([goal]) + dirs = [Direction.UP, Direction.DOWN, Direction.LEFT, Direction.RIGHT] while queue: field = queue.popleft() - for direction in Direction: + for direction in dirs: neighbour = field.get_neighbour_field(direction) if (neighbour in explored or not neighbour.is_accessible(member.team)): continue + # pokud jsme našli vojáka, vrátíme první krok if neighbour == member.field: return direction.invert() queue.append(neighbour)