Browse Source

Strategická: Algoritmy pro C verzi

master
David Klement 2 years ago
parent
commit
f04db0468f
  1. 92
      klient/client.cpp
  2. 4
      klient/play.py

92
klient/client.cpp

@ -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;

4
klient/play.py

@ -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…
Cancel
Save