From ee7b4e6424b2fe9bb271117bf6d5f23677456dd8 Mon Sep 17 00:00:00 2001 From: Nirenamid Date: Sun, 2 Sep 2018 18:32:32 +0300 Subject: [PATCH] Add files via upload MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Базовый пример на Java с парсингом JSON-данных тика (данные матча не реализованы) --- madcars/examples/Java/Bot.java | 9 +++ madcars/examples/Java/JsonIO.java | 55 +++++++++++++++ madcars/examples/Java/Main.java | 94 ++++++++++++++++++++++++++ madcars/examples/Java/MatchConfig.java | 19 ++++++ madcars/examples/Java/TickState.java | 54 +++++++++++++++ 5 files changed, 231 insertions(+) create mode 100644 madcars/examples/Java/Bot.java create mode 100644 madcars/examples/Java/JsonIO.java create mode 100644 madcars/examples/Java/Main.java create mode 100644 madcars/examples/Java/MatchConfig.java create mode 100644 madcars/examples/Java/TickState.java diff --git a/madcars/examples/Java/Bot.java b/madcars/examples/Java/Bot.java new file mode 100644 index 0000000..afa44e9 --- /dev/null +++ b/madcars/examples/Java/Bot.java @@ -0,0 +1,9 @@ +/** + * Интерфейс типового робота, получающего на вход конфигурацию и состояние мира в формате JSON, + * и отправляющего на выход своё решение на текущем шаге (тоже в JSON) * + */ +public interface Bot { + void onMatchStarted(MatchConfig matchConfig); + void onNextTick(TickState tickState); + void onParsingError(String message); +} diff --git a/madcars/examples/Java/JsonIO.java b/madcars/examples/Java/JsonIO.java new file mode 100644 index 0000000..fe67ad4 --- /dev/null +++ b/madcars/examples/Java/JsonIO.java @@ -0,0 +1,55 @@ +import org.json.JSONObject; +import java.io.*; + +/** + * Обертка, позволяющая считывать из потока ввода и писать в поток вывода JSON-объекты + * Для отладочных целей есть возможность читать команды не из STDIN, а из файла, например: + * + *

{@code gameMessage = JsonIO.readFromFile("messages.json")}

+ */ + +public class JsonIO { + private static FileInputStream fileStream; + private static InputStreamReader reader; + private static BufferedReader bufferedReader; + + public static JSONObject readFromStdIn(){ + return readFromStream(System.in); + } + + public static JSONObject readFromFile(String fileName){ + try { + if (fileStream == null) + fileStream = new FileInputStream(fileName); + return readFromStream(fileStream); + } + catch (FileNotFoundException e) { + return readFromStdIn(); + } + } + private static JSONObject readFromStream(InputStream stream){ + if (reader == null) + reader = new InputStreamReader(stream); + + if (bufferedReader == null) + bufferedReader = new BufferedReader(reader); + + try { + String line = bufferedReader.readLine(); + return (line != null && line.length() != 0) + ? new JSONObject(line) + : null; + } + catch (IOException e) { + return null; + } + } + + public static void writeToStdOut(JSONObject object){ + writeToStream(System.out, object); + } + + private static void writeToStream(PrintStream stream, JSONObject object) { + stream.println(object.toString()); + } +} diff --git a/madcars/examples/Java/Main.java b/madcars/examples/Java/Main.java new file mode 100644 index 0000000..2f0ee42 --- /dev/null +++ b/madcars/examples/Java/Main.java @@ -0,0 +1,94 @@ +import org.json.JSONObject; +import java.util.Random; + +public class Main { + private static Bot robot; + + public static void main(String[] args) { + + JSONObject gameMessage; + while ((gameMessage = JsonIO.readFromStdIn()) != null) { + MessageType messageType; + try { + messageType = gameMessage.getEnum(MessageType.class, "type"); + switch (messageType) { + case tick: + TickState tickState = new TickState(gameMessage.getJSONObject("params")); + robot().onNextTick(tickState); + break; + + case new_match: + MatchConfig matchConfig = new MatchConfig(gameMessage.getJSONObject("params")); + robot().onMatchStarted(matchConfig); + break; + } + } + catch (Exception e){ + robot().onParsingError(e.getMessage()); + } + } + } + + private static Bot robot() { + + if (robot == null) + robot = new Bot() { + // todo заменить этот анонимный класс-заглушку реальным классом стратегии + static final int ON_AIR_PAUSE = 50; + final String commands[] = {"left", "stop", "right"}; + + int thisMathTick = 0; + int matchCounter = 0; + String debugMessage = ""; + + @Override + public void onMatchStarted(MatchConfig matchConfig){ + thisMathTick = 0; + matchCounter ++; + + debugMessage = String.format(".... Match #%d: lives=%d, ", matchCounter, matchConfig.myLives); + } + + @Override + public void onNextTick(TickState tickState) { + thisMathTick++; + + if (thisMathTick == 1) + debugMessage += String.format("my side=%s.... ", commands[1 - tickState.myCar.mirror]); + + String cmd = thisMathTick <= ON_AIR_PAUSE ? "stop" : commands[new Random().nextInt(3)]; + debugMessage += String.format("%d.%d: %s",matchCounter, thisMathTick, cmd); + + new Answer(cmd, debugMessage).send(); + debugMessage = ""; + } + + @Override + public void onParsingError(String message) { + debugMessage = message; + } + }; + return robot; + } + + public static class Answer { + String command; + String debug; + + public String getCommand() { return command;} + public String getDebug() { return debug;} + + Answer(String cmd, String dbg){ + command = cmd; + debug = dbg; + } + void send(){ + JSONObject json = new JSONObject(this); + JsonIO.writeToStdOut(json); + } + } + enum MessageType { + new_match, + tick + } +} diff --git a/madcars/examples/Java/MatchConfig.java b/madcars/examples/Java/MatchConfig.java new file mode 100644 index 0000000..a920ef1 --- /dev/null +++ b/madcars/examples/Java/MatchConfig.java @@ -0,0 +1,19 @@ +import org.json.JSONObject; + +/** + * Параметры матча (характеристики машин, контуры карт и т.д.), присылаемые в начале каждого матча. + * Передается на вход обработчика {@code onMatchStarted} интерфейса {@link Bot} + */ + +public class MatchConfig { + //todo добавить нужные поля и классы и реализовать десериализацию json-объекта + int myLives; + int enemyLives; + // ... + + public MatchConfig(JSONObject params) { + myLives = params.getInt("my_lives"); + enemyLives = params.getInt("enemy_lives"); + // ... + } +} diff --git a/madcars/examples/Java/TickState.java b/madcars/examples/Java/TickState.java new file mode 100644 index 0000000..51221fe --- /dev/null +++ b/madcars/examples/Java/TickState.java @@ -0,0 +1,54 @@ +import org.json.JSONArray; +import org.json.JSONObject; + +/** + * Состояние мира, присылаемое сервером на каждом тике. + * Передается на вход обработчика {@code onNextTick} интерфейса {@link Bot} + */ + +class TickState { + Car myCar; + Car enemyCar; + float deadLine; + + public TickState(JSONObject params){ + myCar = new Car(params.getJSONArray("my_car")); + enemyCar = new Car(params.getJSONArray("enemy_car")); + + deadLine = params.getFloat("deadline_position"); + } + + class Car { + int mirror; // слева = +1, справа = -1 + + float x, y; + float angle; + + WheelPair wheel = new WheelPair(); + + Car(JSONArray carParam){ + JSONArray pos = carParam.getJSONArray(0); + x = pos.getFloat(0); + y = pos.getFloat(1); + + angle = carParam.getFloat(1); + mirror = carParam.getInt(2); + + wheel.rear = new Wheel(carParam.getJSONArray(3)); + wheel.front = new Wheel(carParam.getJSONArray(4)); + } + class WheelPair { + Wheel rear; + Wheel front; + } + class Wheel { + float x, y; + float angle; + Wheel (JSONArray wheelParam) { + x = wheelParam.getFloat(0); + y = wheelParam.getFloat(1); + angle = wheelParam.getFloat(2); + } + } + } +} \ No newline at end of file