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 <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;
|
||||||
|
|
||||||
|
|
|
@ -207,13 +207,15 @@ def pathfind(member: Member, goal: Field) -> Direction:
|
||||||
# a také jednoduše získat první krok
|
# a také jednoduše získat první krok
|
||||||
explored: Set[Field] = set()
|
explored: Set[Field] = set()
|
||||||
queue = collections.deque([goal])
|
queue = collections.deque([goal])
|
||||||
|
dirs = [Direction.UP, Direction.DOWN, Direction.LEFT, Direction.RIGHT]
|
||||||
while queue:
|
while queue:
|
||||||
field = queue.popleft()
|
field = queue.popleft()
|
||||||
for direction in Direction:
|
for direction in dirs:
|
||||||
neighbour = field.get_neighbour_field(direction)
|
neighbour = field.get_neighbour_field(direction)
|
||||||
if (neighbour in explored or
|
if (neighbour in explored or
|
||||||
not neighbour.is_accessible(member.team)):
|
not neighbour.is_accessible(member.team)):
|
||||||
continue
|
continue
|
||||||
|
# pokud jsme našli vojáka, vrátíme první krok
|
||||||
if neighbour == member.field:
|
if neighbour == member.field:
|
||||||
return direction.invert()
|
return direction.invert()
|
||||||
queue.append(neighbour)
|
queue.append(neighbour)
|
||||||
|
|
Loading…
Reference in a new issue