Strategická: Algoritmy pro C verzi
This commit is contained in:
parent
276c55531f
commit
f04db0468f
2 changed files with 93 additions and 3 deletions
|
@ -2,6 +2,8 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <queue>
|
||||
#include <set>
|
||||
#include <vector>
|
||||
#include <cassert>
|
||||
|
||||
|
@ -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<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()
|
||||
{
|
||||
|
@ -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;
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in a new issue