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.

204 lines
4.7 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)
{
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);
printf("%d", teams_count);
for(int i=0; i<teams_count; i++)
{
teams.push_back(new Team(i, i==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)];
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)];
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)];
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)];
}
current_field->members.push_back(m);
}
current_row.push_back(current_field);
}
world.push_back(current_row);
}
}
};
State* state;
// Algoritmy
// main (zde doplňte kód)
void load()
{
char * input_str;
scanf("%m[^\n]", &input_str);
state = new State(input_str);
}
int main()
{
load();
return 0;
}