You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
240 lines
5.8 KiB
240 lines
5.8 KiB
#include "jsmn.h"
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <vector>
|
|
#include <cassert>
|
|
|
|
using std::vector;
|
|
|
|
// Parsování JSONu
|
|
|
|
static int jsoneq(const char *json, jsmntok_t *tok, const char *s) {
|
|
if (tok->type == JSMN_STRING && (int)strlen(s) == tok->end - tok->start &&
|
|
strncmp(json + tok->start, s, tok->end - tok->start) == 0) {
|
|
return 0;
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
// Třídy reprezentující hru
|
|
|
|
enum Direction
|
|
{
|
|
STAY = -1,
|
|
UP = 0,
|
|
LEFT = 1,
|
|
DOWN = 2,
|
|
RIGHT = 3,
|
|
};
|
|
|
|
struct Team;
|
|
struct Member;
|
|
struct Field;
|
|
|
|
struct Team
|
|
{
|
|
int id;
|
|
bool is_me;
|
|
Field* home;
|
|
vector<Field*> occupied;
|
|
vector<Field*> protected_fields;
|
|
vector<Member*> members;
|
|
Team(int _id, bool _is_me)
|
|
{
|
|
id = id;
|
|
is_me = _is_me;
|
|
}
|
|
};
|
|
|
|
struct Member
|
|
{
|
|
Field * field;
|
|
Team * team;
|
|
int id;
|
|
Direction action = STAY;
|
|
Member(Field *_field)
|
|
{
|
|
field = _field;
|
|
}
|
|
};
|
|
|
|
struct Field
|
|
{
|
|
int i,j;
|
|
bool hill;
|
|
Team* home_for_team = NULL;
|
|
Team* occupied_by_team = NULL;
|
|
Team* protected_for_team = NULL;
|
|
vector<Member*> members;
|
|
Field(int _i, int _j)
|
|
{
|
|
i = _i;
|
|
j = _j;
|
|
}
|
|
};
|
|
|
|
// Celý stav hry včetně parsování a vypisování
|
|
struct State
|
|
{
|
|
// Dealokace paměti není implementována, protože předpokládáme, že program
|
|
// poběží jen krátce a po ukončení všechna paměť automaticky zanikne.
|
|
vector<Team*> teams;
|
|
vector<vector<Field*>> world;
|
|
Team * my_team;
|
|
int round_number;
|
|
int time_to_response;
|
|
|
|
int js_skip(jsmntok_t* t, int i)
|
|
{
|
|
int s = t[i].size;
|
|
i++;
|
|
for(int j=0; j<s; j++)
|
|
i = js_skip(t, i);
|
|
return i;
|
|
}
|
|
|
|
State(char * input_str)
|
|
{
|
|
// Ano, vím, že je to ošklivé, ale prostě parsovat JSON v C/C++ je za trest
|
|
int r;
|
|
jsmn_parser p;
|
|
jsmntok_t t[10000]; /* We expect no more than this count of tokens (jsmn limitation)*/
|
|
|
|
jsmn_init(&p);
|
|
r = jsmn_parse(&p, input_str, strlen(input_str), t,
|
|
sizeof(t) / sizeof(t[0]));
|
|
assert(!(r < 0));
|
|
|
|
assert(!(r < 1 || t[0].type != JSMN_OBJECT));
|
|
|
|
int teams_count, team_id;
|
|
int state_tok, world_tok;
|
|
for (int i = 1, c=0; c < t[0].size;i = js_skip(t, i), c++)
|
|
{
|
|
//printf("- %.*s %d\n", t[i].end - t[i].start, input_str + t[i].start, t[i].size);
|
|
|
|
if (jsoneq(input_str, &t[i], "teams_count") == 0)
|
|
teams_count = atoi(input_str + t[i+1].start);
|
|
if (jsoneq(input_str, &t[i], "team_id") == 0)
|
|
team_id = atoi(input_str + t[i+1].start);
|
|
if (jsoneq(input_str, &t[i], "time_to_response") == 0)
|
|
time_to_response = atoi(input_str + t[i+1].start);
|
|
if (jsoneq(input_str, &t[i], "round_number") == 0)
|
|
round_number = atoi(input_str + t[i+1].start);
|
|
if (jsoneq(input_str, &t[i], "state") == 0)
|
|
state_tok = i+1;
|
|
;
|
|
}
|
|
assert(state_tok);
|
|
for(int i=0; i<teams_count; i++)
|
|
teams.push_back(new Team(i, i==team_id));
|
|
my_team = teams[team_id];
|
|
for (int i = state_tok+1, c=0; c < t[state_tok].size;i = js_skip(t, i), c++)
|
|
{
|
|
if (jsoneq(input_str, &t[i], "world") == 0)
|
|
world_tok = i+1;
|
|
;
|
|
}
|
|
assert(world_tok);
|
|
for (int i = world_tok+1, x=0; x < t[world_tok].size;i = js_skip(t, i), x++)
|
|
{
|
|
vector<Field *> current_row;
|
|
for (int j = i+1, y=0; y < t[i].size;j = js_skip(t, j), y++)
|
|
{
|
|
Field *current_field = new Field(x,y);
|
|
int members_tok;
|
|
for (int k = j+1, c=0; c < t[j].size;k = js_skip(t, k), c++)
|
|
{
|
|
if (jsoneq(input_str, &t[k], "hill") == 0)
|
|
current_field->hill = input_str[t[k+1].start] == 't';
|
|
if (jsoneq(input_str, &t[k], "home_for_team") == 0)
|
|
if(input_str[t[k+1].start] != 'n')
|
|
{
|
|
current_field->home_for_team = teams[atoi(input_str+t[k+1].start)];
|
|
current_field->home_for_team->home = current_field;
|
|
}
|
|
if (jsoneq(input_str, &t[k], "occupied_by_team") == 0)
|
|
if(input_str[t[k+1].start] != 'n')
|
|
{
|
|
current_field->occupied_by_team = teams[atoi(input_str+t[k+1].start)];
|
|
current_field->occupied_by_team->occupied.push_back(current_field);
|
|
}
|
|
|
|
if (jsoneq(input_str, &t[k], "protected_for_team") == 0)
|
|
if(input_str[t[k+1].start] != 'n')
|
|
{
|
|
current_field->protected_for_team = teams[atoi(input_str+t[k+1].start)];
|
|
current_field->protected_for_team->protected_fields.push_back(current_field);
|
|
}
|
|
if (jsoneq(input_str, &t[k], "members") == 0)
|
|
members_tok = k+1;
|
|
}
|
|
for (int k = members_tok+1, c=0; c < t[members_tok].size;k = js_skip(t, k), c++)
|
|
{
|
|
auto m = new Member(current_field);
|
|
for (int l = k+1, d=0; d < t[k].size;l = js_skip(t, l), d++)
|
|
{
|
|
// printf("%d %d: %.*s %d\n", x,y, t[l].end - t[l].start, input_str + t[l].start, t[l].size);
|
|
if (jsoneq(input_str, &t[l], "id") == 0)
|
|
m->id = atoi(input_str + t[l+1].start);
|
|
if (jsoneq(input_str, &t[l], "team") == 0)
|
|
m->team = teams[atoi(input_str+t[l+1].start)];
|
|
}
|
|
m->team->members.push_back(m);
|
|
current_field->members.push_back(m);
|
|
}
|
|
current_row.push_back(current_field);
|
|
}
|
|
world.push_back(current_row);
|
|
}
|
|
}
|
|
|
|
void print_turn()
|
|
{
|
|
for(Team *t: teams)
|
|
if(!t->is_me)
|
|
for(Member *m: t->members)
|
|
if(m->action != STAY)
|
|
{
|
|
fprintf(stderr, "Voják cizího týmu má přiřazenou akci.");
|
|
exit(1);
|
|
}
|
|
bool first = true;
|
|
printf("{\"members\": [");
|
|
for(Member *m: my_team->members)
|
|
{
|
|
if(!first) printf(", ");
|
|
const char * action = "stay";
|
|
if(m->action == UP) action = "up";
|
|
if(m->action == LEFT) action = "left";
|
|
if(m->action == DOWN) action = "down";
|
|
if(m->action == RIGHT) action = "right";
|
|
printf("{\"id\": %d, \"action\": \"%s\"}", m->id, action);
|
|
first = false;
|
|
}
|
|
printf("]}");
|
|
}
|
|
};
|
|
|
|
State* state;
|
|
|
|
|
|
|
|
// Algoritmy
|
|
|
|
// main (zde doplňte kód)
|
|
|
|
int main()
|
|
{
|
|
char * input_str;
|
|
scanf("%m[^\n]", &input_str);
|
|
state = new State(input_str);
|
|
|
|
// TODO sem patří herní logika
|
|
for(Member *m: state->my_team->members)
|
|
m->action = UP;
|
|
|
|
state->print_turn();
|
|
return 0;
|
|
}
|
|
|