diff --git a/clients/cpp/MyStrategy.cpp b/clients/cpp/MyStrategy.cpp index 1c43230..205e98f 100644 --- a/clients/cpp/MyStrategy.cpp +++ b/clients/cpp/MyStrategy.cpp @@ -58,6 +58,7 @@ UnitAction MyStrategy::getAction(const Unit &unit, const Game &game, action.jumpDown = !action.jump; action.aim = aim; action.shoot = true; + action.reload = false; action.swapWeapon = false; action.plantMine = false; return action; diff --git a/clients/cpp/main.cpp b/clients/cpp/main.cpp index 2beee63..a067297 100644 --- a/clients/cpp/main.cpp +++ b/clients/cpp/main.cpp @@ -33,7 +33,7 @@ class Runner { myStrategy.getAction(unit, playerView->game, debug))); } } - PlayerMessageGame::ActionMessage(actions).writeTo(*outputStream); + PlayerMessageGame::ActionMessage(Versioned(actions)).writeTo(*outputStream); outputStream->flush(); } } diff --git a/clients/cpp/model/PlayerMessageGame.cpp b/clients/cpp/model/PlayerMessageGame.cpp index 2e0a596..d158a9b 100644 --- a/clients/cpp/model/PlayerMessageGame.cpp +++ b/clients/cpp/model/PlayerMessageGame.cpp @@ -19,32 +19,19 @@ std::string PlayerMessageGame::CustomDataMessage::toString() const { } PlayerMessageGame::ActionMessage::ActionMessage() { } -PlayerMessageGame::ActionMessage::ActionMessage(std::unordered_map action) : action(action) { } +PlayerMessageGame::ActionMessage::ActionMessage(Versioned action) : action(action) { } PlayerMessageGame::ActionMessage PlayerMessageGame::ActionMessage::readFrom(InputStream& stream) { PlayerMessageGame::ActionMessage result; - size_t actionSize = stream.readInt(); - result.action = std::unordered_map(); - result.action.reserve(actionSize); - for (size_t i = 0; i < actionSize; i++) { - int actionKey; - actionKey = stream.readInt(); - UnitAction actionValue; - actionValue = UnitAction::readFrom(stream); - result.action.emplace(std::make_pair(actionKey, actionValue)); - } + result.action = Versioned::readFrom(stream); return result; } void PlayerMessageGame::ActionMessage::writeTo(OutputStream& stream) const { stream.write(TAG); - stream.write((int)(action.size())); - for (const auto& actionEntry : action) { - stream.write(actionEntry.first); - actionEntry.second.writeTo(stream); - } + action.writeTo(stream); } std::string PlayerMessageGame::ActionMessage::toString() const { return std::string("PlayerMessageGame::ActionMessage") + "(" + - "TODO" + + action.toString() + ")"; } std::shared_ptr PlayerMessageGame::readFrom(InputStream& stream) { diff --git a/clients/cpp/model/PlayerMessageGame.hpp b/clients/cpp/model/PlayerMessageGame.hpp index ad76e15..e4ec810 100644 --- a/clients/cpp/model/PlayerMessageGame.hpp +++ b/clients/cpp/model/PlayerMessageGame.hpp @@ -32,6 +32,8 @@ #include "TextAlignment.hpp" #include #include "ColorFloat.hpp" +#include +#include "Versioned.hpp" #include #include #include "UnitAction.hpp" @@ -64,9 +66,9 @@ class PlayerMessageGame::ActionMessage : public PlayerMessageGame { public: static const int TAG = 1; public: - std::unordered_map action; + Versioned action; ActionMessage(); - ActionMessage(std::unordered_map action); + ActionMessage(Versioned action); static ActionMessage readFrom(InputStream& stream); void writeTo(OutputStream& stream) const; std::string toString() const override; diff --git a/clients/cpp/model/UnitAction.cpp b/clients/cpp/model/UnitAction.cpp index f6d8f21..621e2ac 100644 --- a/clients/cpp/model/UnitAction.cpp +++ b/clients/cpp/model/UnitAction.cpp @@ -1,7 +1,7 @@ #include "UnitAction.hpp" UnitAction::UnitAction() { } -UnitAction::UnitAction(double velocity, bool jump, bool jumpDown, Vec2Double aim, bool shoot, bool swapWeapon, bool plantMine) : velocity(velocity), jump(jump), jumpDown(jumpDown), aim(aim), shoot(shoot), swapWeapon(swapWeapon), plantMine(plantMine) { } +UnitAction::UnitAction(double velocity, bool jump, bool jumpDown, Vec2Double aim, bool shoot, bool reload, bool swapWeapon, bool plantMine) : velocity(velocity), jump(jump), jumpDown(jumpDown), aim(aim), shoot(shoot), reload(reload), swapWeapon(swapWeapon), plantMine(plantMine) { } UnitAction UnitAction::readFrom(InputStream& stream) { UnitAction result; result.velocity = stream.readDouble(); @@ -9,6 +9,7 @@ UnitAction UnitAction::readFrom(InputStream& stream) { result.jumpDown = stream.readBool(); result.aim = Vec2Double::readFrom(stream); result.shoot = stream.readBool(); + result.reload = stream.readBool(); result.swapWeapon = stream.readBool(); result.plantMine = stream.readBool(); return result; @@ -19,6 +20,7 @@ void UnitAction::writeTo(OutputStream& stream) const { stream.write(jumpDown); aim.writeTo(stream); stream.write(shoot); + stream.write(reload); stream.write(swapWeapon); stream.write(plantMine); } @@ -29,6 +31,7 @@ std::string UnitAction::toString() const { (jumpDown ? "true" : "false") + aim.toString() + (shoot ? "true" : "false") + + (reload ? "true" : "false") + (swapWeapon ? "true" : "false") + (plantMine ? "true" : "false") + ")"; diff --git a/clients/cpp/model/UnitAction.hpp b/clients/cpp/model/UnitAction.hpp index 127c906..e606bab 100644 --- a/clients/cpp/model/UnitAction.hpp +++ b/clients/cpp/model/UnitAction.hpp @@ -13,10 +13,11 @@ class UnitAction { bool jumpDown; Vec2Double aim; bool shoot; + bool reload; bool swapWeapon; bool plantMine; UnitAction(); - UnitAction(double velocity, bool jump, bool jumpDown, Vec2Double aim, bool shoot, bool swapWeapon, bool plantMine); + UnitAction(double velocity, bool jump, bool jumpDown, Vec2Double aim, bool shoot, bool reload, bool swapWeapon, bool plantMine); static UnitAction readFrom(InputStream& stream); void writeTo(OutputStream& stream) const; std::string toString() const; diff --git a/clients/cpp/model/Versioned.cpp b/clients/cpp/model/Versioned.cpp new file mode 100644 index 0000000..d88f3d7 --- /dev/null +++ b/clients/cpp/model/Versioned.cpp @@ -0,0 +1,31 @@ +#include "Versioned.hpp" + +Versioned::Versioned() { } +Versioned::Versioned(std::unordered_map inner) : inner(inner) { } +Versioned Versioned::readFrom(InputStream& stream) { + Versioned result; + size_t innerSize = stream.readInt(); + result.inner = std::unordered_map(); + result.inner.reserve(innerSize); + for (size_t i = 0; i < innerSize; i++) { + int innerKey; + innerKey = stream.readInt(); + UnitAction innerValue; + innerValue = UnitAction::readFrom(stream); + result.inner.emplace(std::make_pair(innerKey, innerValue)); + } + return result; +} +void Versioned::writeTo(OutputStream& stream) const { + stream.write(43981); + stream.write((int)(inner.size())); + for (const auto& innerEntry : inner) { + stream.write(innerEntry.first); + innerEntry.second.writeTo(stream); + } +} +std::string Versioned::toString() const { + return std::string("Versioned") + "(" + + "TODO" + + ")"; +} diff --git a/clients/cpp/model/Versioned.hpp b/clients/cpp/model/Versioned.hpp new file mode 100644 index 0000000..d37610d --- /dev/null +++ b/clients/cpp/model/Versioned.hpp @@ -0,0 +1,22 @@ +#ifndef _MODEL_VERSIONED_HPP_ +#define _MODEL_VERSIONED_HPP_ + +#include "../Stream.hpp" +#include +#include +#include +#include "UnitAction.hpp" +#include +#include "Vec2Double.hpp" + +class Versioned { +public: + std::unordered_map inner; + Versioned(); + Versioned(std::unordered_map inner); + static Versioned readFrom(InputStream& stream); + void writeTo(OutputStream& stream) const; + std::string toString() const; +}; + +#endif diff --git a/clients/csharp/Model/PlayerMessageGame.cs b/clients/csharp/Model/PlayerMessageGame.cs index 054e648..5b94dff 100644 --- a/clients/csharp/Model/PlayerMessageGame.cs +++ b/clients/csharp/Model/PlayerMessageGame.cs @@ -41,38 +41,22 @@ public override void WriteTo(System.IO.BinaryWriter writer) public class ActionMessage : PlayerMessageGame { public const int TAG = 1; - public System.Collections.Generic.IDictionary Action { get; set; } + public Model.Versioned Action { get; set; } public ActionMessage() {} - public ActionMessage(System.Collections.Generic.IDictionary action) + public ActionMessage(Model.Versioned action) { this.Action = action; } public static new ActionMessage ReadFrom(System.IO.BinaryReader reader) { var result = new ActionMessage(); - int ActionSize = reader.ReadInt32(); - result.Action = new System.Collections.Generic.Dictionary(ActionSize); - for (int i = 0; i < ActionSize; i++) - { - int ActionKey; - ActionKey = reader.ReadInt32(); - Model.UnitAction ActionValue; - ActionValue = Model.UnitAction.ReadFrom(reader); - result.Action.Add(ActionKey, ActionValue); - } + result.Action = Model.Versioned.ReadFrom(reader); return result; } public override void WriteTo(System.IO.BinaryWriter writer) { writer.Write(TAG); - writer.Write(Action.Count); - foreach (var ActionEntry in Action) - { - var ActionKey = ActionEntry.Key; - var ActionValue = ActionEntry.Value; - writer.Write(ActionKey); - ActionValue.WriteTo(writer); - } + Action.WriteTo(writer); } } } diff --git a/clients/csharp/Model/UnitAction.cs b/clients/csharp/Model/UnitAction.cs index 1ee88ff..c3d6571 100644 --- a/clients/csharp/Model/UnitAction.cs +++ b/clients/csharp/Model/UnitAction.cs @@ -7,15 +7,17 @@ public struct UnitAction public bool JumpDown { get; set; } public Model.Vec2Double Aim { get; set; } public bool Shoot { get; set; } + public bool Reload { get; set; } public bool SwapWeapon { get; set; } public bool PlantMine { get; set; } - public UnitAction(double velocity, bool jump, bool jumpDown, Model.Vec2Double aim, bool shoot, bool swapWeapon, bool plantMine) + public UnitAction(double velocity, bool jump, bool jumpDown, Model.Vec2Double aim, bool shoot, bool reload, bool swapWeapon, bool plantMine) { this.Velocity = velocity; this.Jump = jump; this.JumpDown = jumpDown; this.Aim = aim; this.Shoot = shoot; + this.Reload = reload; this.SwapWeapon = swapWeapon; this.PlantMine = plantMine; } @@ -27,6 +29,7 @@ public static UnitAction ReadFrom(System.IO.BinaryReader reader) result.JumpDown = reader.ReadBoolean(); result.Aim = Model.Vec2Double.ReadFrom(reader); result.Shoot = reader.ReadBoolean(); + result.Reload = reader.ReadBoolean(); result.SwapWeapon = reader.ReadBoolean(); result.PlantMine = reader.ReadBoolean(); return result; @@ -38,6 +41,7 @@ public void WriteTo(System.IO.BinaryWriter writer) writer.Write(JumpDown); Aim.WriteTo(writer); writer.Write(Shoot); + writer.Write(Reload); writer.Write(SwapWeapon); writer.Write(PlantMine); } diff --git a/clients/csharp/Model/Versioned.cs b/clients/csharp/Model/Versioned.cs new file mode 100644 index 0000000..194ecea --- /dev/null +++ b/clients/csharp/Model/Versioned.cs @@ -0,0 +1,38 @@ +namespace AiCup2019.Model +{ + public struct Versioned + { + public System.Collections.Generic.IDictionary Inner { get; set; } + public Versioned(System.Collections.Generic.IDictionary inner) + { + this.Inner = inner; + } + public static Versioned ReadFrom(System.IO.BinaryReader reader) + { + var result = new Versioned(); + int InnerSize = reader.ReadInt32(); + result.Inner = new System.Collections.Generic.Dictionary(InnerSize); + for (int i = 0; i < InnerSize; i++) + { + int InnerKey; + InnerKey = reader.ReadInt32(); + Model.UnitAction InnerValue; + InnerValue = Model.UnitAction.ReadFrom(reader); + result.Inner.Add(InnerKey, InnerValue); + } + return result; + } + public void WriteTo(System.IO.BinaryWriter writer) + { + writer.Write(43981); + writer.Write(Inner.Count); + foreach (var InnerEntry in Inner) + { + var InnerKey = InnerEntry.Key; + var InnerValue = InnerEntry.Value; + writer.Write(InnerKey); + InnerValue.WriteTo(writer); + } + } + } +} diff --git a/clients/csharp/MyStrategy.cs b/clients/csharp/MyStrategy.cs index 3d2bf1d..22c865a 100644 --- a/clients/csharp/MyStrategy.cs +++ b/clients/csharp/MyStrategy.cs @@ -62,6 +62,7 @@ public UnitAction GetAction(Unit unit, Game game, Debug debug) action.JumpDown = !jump; action.Aim = aim; action.Shoot = true; + action.Reload = false; action.SwapWeapon = false; action.PlantMine = false; return action; diff --git a/clients/csharp/Runner.cs b/clients/csharp/Runner.cs index 747f5b5..3e8d4bb 100644 --- a/clients/csharp/Runner.cs +++ b/clients/csharp/Runner.cs @@ -42,7 +42,7 @@ public void Run() actions.Add(unit.Id, myStrategy.GetAction(unit, playerView.Game, debug)); } } - new Model.PlayerMessageGame.ActionMessage(actions).WriteTo(writer); + new Model.PlayerMessageGame.ActionMessage(new Model.Versioned(actions)).WriteTo(writer); writer.Flush(); } } diff --git a/clients/dlang/source/app.d b/clients/dlang/source/app.d index 6fe32b2..831cb77 100644 --- a/clients/dlang/source/app.d +++ b/clients/dlang/source/app.d @@ -58,7 +58,7 @@ class Runner { actions[unit.id] = myStrategy.getAction(unit, playerView.game, debugger); } } - new PlayerMessageGame.ActionMessage(actions).writeTo(stream); + new PlayerMessageGame.ActionMessage(Versioned(actions)).writeTo(stream); stream.flush(); } } diff --git a/clients/dlang/source/model/package.d b/clients/dlang/source/model/package.d index b2b7e8d..7b40b70 100644 --- a/clients/dlang/source/model/package.d +++ b/clients/dlang/source/model/package.d @@ -5,6 +5,7 @@ public import text_alignment; public import custom_data; public import vec2_double; public import unit_action; +public import versioned; public import player_message_game; public import weapon_type; public import bullet_parameters; diff --git a/clients/dlang/source/model/player_message_game.d b/clients/dlang/source/model/player_message_game.d index 4c751b1..18e2470 100644 --- a/clients/dlang/source/model/player_message_game.d +++ b/clients/dlang/source/model/player_message_game.d @@ -41,31 +41,19 @@ abstract class PlayerMessageGame { static class ActionMessage : PlayerMessageGame { static const int TAG = 1; - UnitAction[int] action; + Versioned action; this() {} - this(UnitAction[int] action) { + this(Versioned action) { this.action = action; } static ActionMessage readFrom(Stream reader) { auto result = new ActionMessage(); - int actionSize = reader.readInt(); - result.action.clear(); - for (int i = 0; i < actionSize; i++) { - int actionKey; - actionKey = reader.readInt(); - UnitAction actionValue; - actionValue = UnitAction.readFrom(reader); - result.action[actionKey] = actionValue; - } + result.action = Versioned.readFrom(reader); return result; } override void writeTo(Stream writer) const { writer.write(TAG); - writer.write(cast(int)(action.length)); - foreach (actionKey, actionValue; action) { - writer.write(actionKey); - actionValue.writeTo(writer); - } + action.writeTo(writer); } override string toString() const { return "ActionMessage" ~ "(" ~ diff --git a/clients/dlang/source/model/unit_action.d b/clients/dlang/source/model/unit_action.d index fb830dc..f342401 100644 --- a/clients/dlang/source/model/unit_action.d +++ b/clients/dlang/source/model/unit_action.d @@ -9,14 +9,16 @@ struct UnitAction { bool jumpDown; Vec2Double aim; bool shoot; + bool reload; bool swapWeapon; bool plantMine; - this(double velocity, bool jump, bool jumpDown, Vec2Double aim, bool shoot, bool swapWeapon, bool plantMine) { + this(double velocity, bool jump, bool jumpDown, Vec2Double aim, bool shoot, bool reload, bool swapWeapon, bool plantMine) { this.velocity = velocity; this.jump = jump; this.jumpDown = jumpDown; this.aim = aim; this.shoot = shoot; + this.reload = reload; this.swapWeapon = swapWeapon; this.plantMine = plantMine; } @@ -27,6 +29,7 @@ struct UnitAction { result.jumpDown = reader.readBool(); result.aim = Vec2Double.readFrom(reader); result.shoot = reader.readBool(); + result.reload = reader.readBool(); result.swapWeapon = reader.readBool(); result.plantMine = reader.readBool(); return result; @@ -37,6 +40,7 @@ struct UnitAction { writer.write(jumpDown); aim.writeTo(writer); writer.write(shoot); + writer.write(reload); writer.write(swapWeapon); writer.write(plantMine); } @@ -47,6 +51,7 @@ struct UnitAction { to!string(jumpDown) ~ to!string(aim) ~ to!string(shoot) ~ + to!string(reload) ~ to!string(swapWeapon) ~ to!string(plantMine) ~ ")"; diff --git a/clients/dlang/source/model/versioned.d b/clients/dlang/source/model/versioned.d new file mode 100644 index 0000000..5cff3b1 --- /dev/null +++ b/clients/dlang/source/model/versioned.d @@ -0,0 +1,37 @@ +import model; +import stream; +import std.conv; +import std.typecons : Nullable; + +struct Versioned { + UnitAction[int] inner; + this(UnitAction[int] inner) { + this.inner = inner; + } + static Versioned readFrom(Stream reader) { + auto result = Versioned(); + int innerSize = reader.readInt(); + result.inner.clear(); + for (int i = 0; i < innerSize; i++) { + int innerKey; + innerKey = reader.readInt(); + UnitAction innerValue; + innerValue = UnitAction.readFrom(reader); + result.inner[innerKey] = innerValue; + } + return result; + } + void writeTo(Stream writer) const { + writer.write(43981); + writer.write(cast(int)(inner.length)); + foreach (innerKey, innerValue; inner) { + writer.write(innerKey); + innerValue.writeTo(writer); + } + } + string toString() const { + return "Versioned" ~ "(" ~ + to!string(inner) ~ + ")"; + } +} diff --git a/clients/dlang/source/my_strategy.d b/clients/dlang/source/my_strategy.d index 2130f54..e36f122 100644 --- a/clients/dlang/source/my_strategy.d +++ b/clients/dlang/source/my_strategy.d @@ -56,6 +56,7 @@ class MyStrategy { action.jumpDown = !jump; action.aim = aim; action.shoot = true; + action.reload = false; action.swapWeapon = false; action.plantMine = false; return action; diff --git a/clients/fsharp/Model/PlayerMessageGame.fs b/clients/fsharp/Model/PlayerMessageGame.fs index f2c04b0..5506b44 100644 --- a/clients/fsharp/Model/PlayerMessageGame.fs +++ b/clients/fsharp/Model/PlayerMessageGame.fs @@ -12,21 +12,13 @@ type PlayerMessageGameCustomDataMessage = { } type PlayerMessageGameActionMessage = { - Action: Map; + Action: Versioned; } with member this.writeTo(writer: System.IO.BinaryWriter) = writer.Write 1 - writer.Write this.Action.Count - this.Action |> Map.iter (fun key value -> - writer.Write key - value.writeTo writer - ) + this.Action.writeTo writer static member readFrom(reader: System.IO.BinaryReader) = { - Action = [for _ in 1 .. reader.ReadInt32() do - let key = reader.ReadInt32() - let value = UnitAction.readFrom reader - yield (key, value) - ] |> Map.ofList + Action = Versioned.readFrom reader } type PlayerMessageGame = | CustomDataMessage of PlayerMessageGameCustomDataMessage diff --git a/clients/fsharp/Model/UnitAction.fs b/clients/fsharp/Model/UnitAction.fs index 735a921..d27796b 100644 --- a/clients/fsharp/Model/UnitAction.fs +++ b/clients/fsharp/Model/UnitAction.fs @@ -6,6 +6,7 @@ type UnitAction = { JumpDown: bool; Aim: Vec2Double; Shoot: bool; + Reload: bool; SwapWeapon: bool; PlantMine: bool; } with @@ -15,6 +16,7 @@ type UnitAction = { writer.Write this.JumpDown this.Aim.writeTo writer writer.Write this.Shoot + writer.Write this.Reload writer.Write this.SwapWeapon writer.Write this.PlantMine static member readFrom(reader: System.IO.BinaryReader) = { @@ -23,6 +25,7 @@ type UnitAction = { JumpDown = reader.ReadBoolean() Aim = Vec2Double.readFrom reader Shoot = reader.ReadBoolean() + Reload = reader.ReadBoolean() SwapWeapon = reader.ReadBoolean() PlantMine = reader.ReadBoolean() } diff --git a/clients/fsharp/Model/Versioned.fs b/clients/fsharp/Model/Versioned.fs new file mode 100644 index 0000000..dcb6b97 --- /dev/null +++ b/clients/fsharp/Model/Versioned.fs @@ -0,0 +1,19 @@ +#nowarn "0058" +namespace AiCup2019.Model +type Versioned = { + Inner: Map; + } with + member this.writeTo(writer: System.IO.BinaryWriter) = + writer.Write 43981 + writer.Write this.Inner.Count + this.Inner |> Map.iter (fun key value -> + writer.Write key + value.writeTo writer + ) + static member readFrom(reader: System.IO.BinaryReader) = { + Inner = [for _ in 1 .. reader.ReadInt32() do + let key = reader.ReadInt32() + let value = UnitAction.readFrom reader + yield (key, value) + ] |> Map.ofList + } diff --git a/clients/fsharp/MyStrategy.fs b/clients/fsharp/MyStrategy.fs index f9576c2..6e12fc8 100644 --- a/clients/fsharp/MyStrategy.fs +++ b/clients/fsharp/MyStrategy.fs @@ -41,6 +41,7 @@ type MyStrategy() = JumpDown = not jump Aim = aim Shoot = true + Reload = false SwapWeapon = false PlantMine = false } diff --git a/clients/fsharp/Runner.fs b/clients/fsharp/Runner.fs index 2fda603..47e1d7b 100644 --- a/clients/fsharp/Runner.fs +++ b/clients/fsharp/Runner.fs @@ -31,7 +31,7 @@ module Runner = |> Array.map(fun x -> (x.Id, myStrategy.getAction(x, playerView.Game, debug))) |> Map.ofArray - (Model.PlayerMessageGame.ActionMessage {Action = actions}).writeTo writer + (Model.PlayerMessageGame.ActionMessage {Action = {Inner = actions}}).writeTo writer writer.Flush() loop() | None -> () diff --git a/clients/fsharp/aicup2019.fsproj b/clients/fsharp/aicup2019.fsproj index 805494a..72dec00 100644 --- a/clients/fsharp/aicup2019.fsproj +++ b/clients/fsharp/aicup2019.fsproj @@ -32,6 +32,7 @@ + diff --git a/clients/go/main.go b/clients/go/main.go index 28614e6..799d303 100644 --- a/clients/go/main.go +++ b/clients/go/main.go @@ -51,7 +51,9 @@ func (runner Runner) Run() { } } PlayerMessageGameActionMessage { - Action: actions, + Action: Versioned { + Inner: actions, + }, }.Write(runner.writer) err := runner.writer.Flush() if err != nil { diff --git a/clients/go/model/player_message_game.go b/clients/go/model/player_message_game.go index 89348b5..eb462d3 100644 --- a/clients/go/model/player_message_game.go +++ b/clients/go/model/player_message_game.go @@ -35,31 +35,19 @@ func (value PlayerMessageGameCustomDataMessage) Write(writer io.Writer) { } type PlayerMessageGameActionMessage struct { - Action map[int32]UnitAction + Action Versioned } -func NewPlayerMessageGameActionMessage(action map[int32]UnitAction) PlayerMessageGameActionMessage { +func NewPlayerMessageGameActionMessage(action Versioned) PlayerMessageGameActionMessage { return PlayerMessageGameActionMessage { Action: action, } } func ReadPlayerMessageGameActionMessage(reader io.Reader) PlayerMessageGameActionMessage { result := PlayerMessageGameActionMessage {} - ActionSize := ReadInt32(reader) - result.Action = make(map[int32]UnitAction) - for i := int32(0); i < ActionSize; i++ { - var ActionKey int32 - ActionKey = ReadInt32(reader) - var ActionValue UnitAction - ActionValue = ReadUnitAction(reader) - result.Action[ActionKey] = ActionValue - } + result.Action = ReadVersioned(reader) return result } func (value PlayerMessageGameActionMessage) Write(writer io.Writer) { WriteInt32(writer, 1) - WriteInt32(writer, int32(len(value.Action))) - for ActionKey, ActionValue := range value.Action { - WriteInt32(writer, ActionKey) - ActionValue.Write(writer) - } + value.Action.Write(writer) } diff --git a/clients/go/model/unit_action.go b/clients/go/model/unit_action.go index 57c5b9c..216cb0b 100644 --- a/clients/go/model/unit_action.go +++ b/clients/go/model/unit_action.go @@ -9,16 +9,18 @@ type UnitAction struct { JumpDown bool Aim Vec2Float64 Shoot bool + Reload bool SwapWeapon bool PlantMine bool } -func NewUnitAction(velocity float64, jump bool, jumpDown bool, aim Vec2Float64, shoot bool, swapWeapon bool, plantMine bool) UnitAction { +func NewUnitAction(velocity float64, jump bool, jumpDown bool, aim Vec2Float64, shoot bool, reload bool, swapWeapon bool, plantMine bool) UnitAction { return UnitAction { Velocity: velocity, Jump: jump, JumpDown: jumpDown, Aim: aim, Shoot: shoot, + Reload: reload, SwapWeapon: swapWeapon, PlantMine: plantMine, } @@ -30,6 +32,7 @@ func ReadUnitAction(reader io.Reader) UnitAction { result.JumpDown = ReadBool(reader) result.Aim = ReadVec2Float64(reader) result.Shoot = ReadBool(reader) + result.Reload = ReadBool(reader) result.SwapWeapon = ReadBool(reader) result.PlantMine = ReadBool(reader) return result @@ -40,6 +43,7 @@ func (value UnitAction) Write(writer io.Writer) { WriteBool(writer, value.JumpDown) value.Aim.Write(writer) WriteBool(writer, value.Shoot) + WriteBool(writer, value.Reload) WriteBool(writer, value.SwapWeapon) WriteBool(writer, value.PlantMine) } diff --git a/clients/go/model/versioned.go b/clients/go/model/versioned.go new file mode 100644 index 0000000..731fc30 --- /dev/null +++ b/clients/go/model/versioned.go @@ -0,0 +1,34 @@ +package model + +import "io" +import . "aicup2019/stream" + +type Versioned struct { + Inner map[int32]UnitAction +} +func NewVersioned(inner map[int32]UnitAction) Versioned { + return Versioned { + Inner: inner, + } +} +func ReadVersioned(reader io.Reader) Versioned { + result := Versioned {} + InnerSize := ReadInt32(reader) + result.Inner = make(map[int32]UnitAction) + for i := int32(0); i < InnerSize; i++ { + var InnerKey int32 + InnerKey = ReadInt32(reader) + var InnerValue UnitAction + InnerValue = ReadUnitAction(reader) + result.Inner[InnerKey] = InnerValue + } + return result +} +func (value Versioned) Write(writer io.Writer) { + WriteInt32(writer, 43981) + WriteInt32(writer, int32(len(value.Inner))) + for InnerKey, InnerValue := range value.Inner { + WriteInt32(writer, InnerKey) + InnerValue.Write(writer) + } +} diff --git a/clients/go/my_strategy.go b/clients/go/my_strategy.go index 8b4a65a..eebc450 100644 --- a/clients/go/my_strategy.go +++ b/clients/go/my_strategy.go @@ -68,5 +68,6 @@ func (strategy MyStrategy) getAction(unit Unit, game Game, debug Debug) UnitActi SwapWeapon: false, PlantMine: false, Shoot: true, + Reload: false, } } diff --git a/clients/java/src/main/java/MyStrategy.java b/clients/java/src/main/java/MyStrategy.java index 3969801..d034187 100644 --- a/clients/java/src/main/java/MyStrategy.java +++ b/clients/java/src/main/java/MyStrategy.java @@ -51,6 +51,7 @@ public UnitAction getAction(Unit unit, Game game, Debug debug) { action.setJumpDown(!jump); action.setAim(aim); action.setShoot(true); + action.setReload(false); action.setSwapWeapon(false); action.setPlantMine(false); return action; diff --git a/clients/java/src/main/java/Runner.java b/clients/java/src/main/java/Runner.java index bd3c017..cfd11e7 100644 --- a/clients/java/src/main/java/Runner.java +++ b/clients/java/src/main/java/Runner.java @@ -37,7 +37,7 @@ void run() throws IOException { actions.put(unit.getId(), myStrategy.getAction(unit, playerView.getGame(), debug)); } } - new model.PlayerMessageGame.ActionMessage(actions).writeTo(outputStream); + new model.PlayerMessageGame.ActionMessage(new model.Versioned(actions)).writeTo(outputStream); outputStream.flush(); } } diff --git a/clients/java/src/main/java/model/PlayerMessageGame.java b/clients/java/src/main/java/model/PlayerMessageGame.java index f55e22c..0d6efa5 100644 --- a/clients/java/src/main/java/model/PlayerMessageGame.java +++ b/clients/java/src/main/java/model/PlayerMessageGame.java @@ -38,36 +38,22 @@ public void writeTo(java.io.OutputStream stream) throws java.io.IOException { public static class ActionMessage extends PlayerMessageGame { public static final int TAG = 1; - private java.util.Map action; - public java.util.Map getAction() { return action; } - public void setAction(java.util.Map action) { this.action = action; } + private model.Versioned action; + public model.Versioned getAction() { return action; } + public void setAction(model.Versioned action) { this.action = action; } public ActionMessage() {} - public ActionMessage(java.util.Map action) { + public ActionMessage(model.Versioned action) { this.action = action; } public static ActionMessage readFrom(java.io.InputStream stream) throws java.io.IOException { ActionMessage result = new ActionMessage(); - int actionSize = StreamUtil.readInt(stream); - result.action = new java.util.HashMap<>(actionSize); - for (int i = 0; i < actionSize; i++) { - int actionKey; - actionKey = StreamUtil.readInt(stream); - model.UnitAction actionValue; - actionValue = model.UnitAction.readFrom(stream); - result.action.put(actionKey, actionValue); - } + result.action = model.Versioned.readFrom(stream); return result; } @Override public void writeTo(java.io.OutputStream stream) throws java.io.IOException { StreamUtil.writeInt(stream, TAG); - StreamUtil.writeInt(stream, action.size()); - for (java.util.Map.Entry actionEntry : action.entrySet()) { - int actionKey = actionEntry.getKey(); - model.UnitAction actionValue = actionEntry.getValue(); - StreamUtil.writeInt(stream, actionKey); - actionValue.writeTo(stream); - } + action.writeTo(stream); } } } diff --git a/clients/java/src/main/java/model/UnitAction.java b/clients/java/src/main/java/model/UnitAction.java index 27ac054..18a40dd 100644 --- a/clients/java/src/main/java/model/UnitAction.java +++ b/clients/java/src/main/java/model/UnitAction.java @@ -18,6 +18,9 @@ public class UnitAction { private boolean shoot; public boolean isShoot() { return shoot; } public void setShoot(boolean shoot) { this.shoot = shoot; } + private boolean reload; + public boolean isReload() { return reload; } + public void setReload(boolean reload) { this.reload = reload; } private boolean swapWeapon; public boolean isSwapWeapon() { return swapWeapon; } public void setSwapWeapon(boolean swapWeapon) { this.swapWeapon = swapWeapon; } @@ -25,12 +28,13 @@ public class UnitAction { public boolean isPlantMine() { return plantMine; } public void setPlantMine(boolean plantMine) { this.plantMine = plantMine; } public UnitAction() {} - public UnitAction(double velocity, boolean jump, boolean jumpDown, model.Vec2Double aim, boolean shoot, boolean swapWeapon, boolean plantMine) { + public UnitAction(double velocity, boolean jump, boolean jumpDown, model.Vec2Double aim, boolean shoot, boolean reload, boolean swapWeapon, boolean plantMine) { this.velocity = velocity; this.jump = jump; this.jumpDown = jumpDown; this.aim = aim; this.shoot = shoot; + this.reload = reload; this.swapWeapon = swapWeapon; this.plantMine = plantMine; } @@ -41,6 +45,7 @@ public static UnitAction readFrom(java.io.InputStream stream) throws java.io.IOE result.jumpDown = StreamUtil.readBoolean(stream); result.aim = model.Vec2Double.readFrom(stream); result.shoot = StreamUtil.readBoolean(stream); + result.reload = StreamUtil.readBoolean(stream); result.swapWeapon = StreamUtil.readBoolean(stream); result.plantMine = StreamUtil.readBoolean(stream); return result; @@ -51,6 +56,7 @@ public void writeTo(java.io.OutputStream stream) throws java.io.IOException { StreamUtil.writeBoolean(stream, jumpDown); aim.writeTo(stream); StreamUtil.writeBoolean(stream, shoot); + StreamUtil.writeBoolean(stream, reload); StreamUtil.writeBoolean(stream, swapWeapon); StreamUtil.writeBoolean(stream, plantMine); } diff --git a/clients/java/src/main/java/model/Versioned.java b/clients/java/src/main/java/model/Versioned.java new file mode 100644 index 0000000..ddcb781 --- /dev/null +++ b/clients/java/src/main/java/model/Versioned.java @@ -0,0 +1,36 @@ +package model; + +import util.StreamUtil; + +public class Versioned { + private java.util.Map inner; + public java.util.Map getInner() { return inner; } + public void setInner(java.util.Map inner) { this.inner = inner; } + public Versioned() {} + public Versioned(java.util.Map inner) { + this.inner = inner; + } + public static Versioned readFrom(java.io.InputStream stream) throws java.io.IOException { + Versioned result = new Versioned(); + int innerSize = StreamUtil.readInt(stream); + result.inner = new java.util.HashMap<>(innerSize); + for (int i = 0; i < innerSize; i++) { + int innerKey; + innerKey = StreamUtil.readInt(stream); + model.UnitAction innerValue; + innerValue = model.UnitAction.readFrom(stream); + result.inner.put(innerKey, innerValue); + } + return result; + } + public void writeTo(java.io.OutputStream stream) throws java.io.IOException { + StreamUtil.writeInt(stream, 43981); + StreamUtil.writeInt(stream, inner.size()); + for (java.util.Map.Entry innerEntry : inner.entrySet()) { + int innerKey = innerEntry.getKey(); + model.UnitAction innerValue = innerEntry.getValue(); + StreamUtil.writeInt(stream, innerKey); + innerValue.writeTo(stream); + } + } +} diff --git a/clients/kotlin/src/main/kotlin/MyStrategy.kt b/clients/kotlin/src/main/kotlin/MyStrategy.kt index 782097e..8354932 100644 --- a/clients/kotlin/src/main/kotlin/MyStrategy.kt +++ b/clients/kotlin/src/main/kotlin/MyStrategy.kt @@ -46,6 +46,7 @@ class MyStrategy { action.jumpDown = !jump action.aim = aim action.shoot = true + action.reload = false action.swapWeapon = false action.plantMine = false return action diff --git a/clients/kotlin/src/main/kotlin/Runner.kt b/clients/kotlin/src/main/kotlin/Runner.kt index 54376f4..7bb1c23 100644 --- a/clients/kotlin/src/main/kotlin/Runner.kt +++ b/clients/kotlin/src/main/kotlin/Runner.kt @@ -34,7 +34,7 @@ internal constructor(host: String, port: Int, token: String) { actions[unit.id] = myStrategy.getAction(unit, playerView.game, debug) } } - model.PlayerMessageGame.ActionMessage(actions).writeTo(outputStream) + model.PlayerMessageGame.ActionMessage(model.Versioned(actions)).writeTo(outputStream) outputStream.flush() } } diff --git a/clients/kotlin/src/main/kotlin/model/PlayerMessageGame.kt b/clients/kotlin/src/main/kotlin/model/PlayerMessageGame.kt index 0d4648d..1982aa7 100644 --- a/clients/kotlin/src/main/kotlin/model/PlayerMessageGame.kt +++ b/clients/kotlin/src/main/kotlin/model/PlayerMessageGame.kt @@ -39,9 +39,9 @@ abstract class PlayerMessageGame { } class ActionMessage : PlayerMessageGame { - lateinit var action: MutableMap + lateinit var action: model.Versioned constructor() {} - constructor(action: MutableMap) { + constructor(action: model.Versioned) { this.action = action } companion object { @@ -49,26 +49,14 @@ abstract class PlayerMessageGame { @Throws(java.io.IOException::class) fun readFrom(stream: java.io.InputStream): ActionMessage { val result = ActionMessage() - val actionSize = StreamUtil.readInt(stream) - result.action = mutableMapOf() - for (i in 0 until actionSize) { - var actionKey: Int - actionKey = StreamUtil.readInt(stream) - var actionValue: model.UnitAction - actionValue = model.UnitAction.readFrom(stream) - result.action.put(actionKey, actionValue) - } + result.action = model.Versioned.readFrom(stream) return result } } @Throws(java.io.IOException::class) override fun writeTo(stream: java.io.OutputStream) { StreamUtil.writeInt(stream, TAG) - StreamUtil.writeInt(stream, action.size) - for (actionEntry in action) { - StreamUtil.writeInt(stream, actionEntry.key) - actionEntry.value.writeTo(stream) - } + action.writeTo(stream) } } } diff --git a/clients/kotlin/src/main/kotlin/model/UnitAction.kt b/clients/kotlin/src/main/kotlin/model/UnitAction.kt index 3f40335..1b59517 100644 --- a/clients/kotlin/src/main/kotlin/model/UnitAction.kt +++ b/clients/kotlin/src/main/kotlin/model/UnitAction.kt @@ -8,15 +8,17 @@ class UnitAction { var jumpDown: Boolean = false lateinit var aim: model.Vec2Double var shoot: Boolean = false + var reload: Boolean = false var swapWeapon: Boolean = false var plantMine: Boolean = false constructor() {} - constructor(velocity: Double, jump: Boolean, jumpDown: Boolean, aim: model.Vec2Double, shoot: Boolean, swapWeapon: Boolean, plantMine: Boolean) { + constructor(velocity: Double, jump: Boolean, jumpDown: Boolean, aim: model.Vec2Double, shoot: Boolean, reload: Boolean, swapWeapon: Boolean, plantMine: Boolean) { this.velocity = velocity this.jump = jump this.jumpDown = jumpDown this.aim = aim this.shoot = shoot + this.reload = reload this.swapWeapon = swapWeapon this.plantMine = plantMine } @@ -29,6 +31,7 @@ class UnitAction { result.jumpDown = StreamUtil.readBoolean(stream) result.aim = model.Vec2Double.readFrom(stream) result.shoot = StreamUtil.readBoolean(stream) + result.reload = StreamUtil.readBoolean(stream) result.swapWeapon = StreamUtil.readBoolean(stream) result.plantMine = StreamUtil.readBoolean(stream) return result @@ -41,6 +44,7 @@ class UnitAction { StreamUtil.writeBoolean(stream, jumpDown) aim.writeTo(stream) StreamUtil.writeBoolean(stream, shoot) + StreamUtil.writeBoolean(stream, reload) StreamUtil.writeBoolean(stream, swapWeapon) StreamUtil.writeBoolean(stream, plantMine) } diff --git a/clients/kotlin/src/main/kotlin/model/Versioned.kt b/clients/kotlin/src/main/kotlin/model/Versioned.kt new file mode 100644 index 0000000..8d200db --- /dev/null +++ b/clients/kotlin/src/main/kotlin/model/Versioned.kt @@ -0,0 +1,36 @@ +package model + +import util.StreamUtil + +class Versioned { + lateinit var inner: MutableMap + constructor() {} + constructor(inner: MutableMap) { + this.inner = inner + } + companion object { + @Throws(java.io.IOException::class) + fun readFrom(stream: java.io.InputStream): Versioned { + val result = Versioned() + val innerSize = StreamUtil.readInt(stream) + result.inner = mutableMapOf() + for (i in 0 until innerSize) { + var innerKey: Int + innerKey = StreamUtil.readInt(stream) + var innerValue: model.UnitAction + innerValue = model.UnitAction.readFrom(stream) + result.inner.put(innerKey, innerValue) + } + return result + } + } + @Throws(java.io.IOException::class) + fun writeTo(stream: java.io.OutputStream) { + StreamUtil.writeInt(stream, 43981) + StreamUtil.writeInt(stream, inner.size) + for (innerEntry in inner) { + StreamUtil.writeInt(stream, innerEntry.key) + innerEntry.value.writeTo(stream) + } + } +} diff --git a/clients/python/main.py b/clients/python/main.py index 8af356d..0c423a4 100644 --- a/clients/python/main.py +++ b/clients/python/main.py @@ -33,7 +33,7 @@ def run(self): actions[unit.id] = strategy.get_action( unit, player_view.game, debug) model.PlayerMessageGame.ActionMessage( - actions).write_to(self.writer) + model.Versioned(actions)).write_to(self.writer) self.writer.flush() diff --git a/clients/python/model/__init__.py b/clients/python/model/__init__.py index 4a3c772..364daea 100644 --- a/clients/python/model/__init__.py +++ b/clients/python/model/__init__.py @@ -5,6 +5,7 @@ from .custom_data import CustomData from .vec2_double import Vec2Double from .unit_action import UnitAction +from .versioned import Versioned from .player_message_game import PlayerMessageGame from .weapon_type import WeaponType from .bullet_params import BulletParams diff --git a/clients/python/model/player_message_game.py b/clients/python/model/player_message_game.py index e28566f..ce1302c 100644 --- a/clients/python/model/player_message_game.py +++ b/clients/python/model/player_message_game.py @@ -25,25 +25,18 @@ def __repr__(self): repr(self.data) + \ ")" PlayerMessageGame.CustomDataMessage = CustomDataMessage -from .unit_action import UnitAction +from .versioned import Versioned class ActionMessage(PlayerMessageGame): TAG = 1 def __init__(self, action): self.action = action @staticmethod def read_from(stream): - action = {} - for _ in range(stream.read_int()): - action_key = stream.read_int() - action_value = UnitAction.read_from(stream) - action[action_key] = action_value + action = Versioned.read_from(stream) return ActionMessage(action) def write_to(self, stream): stream.write_int(self.TAG) - stream.write_int(len(self.action)) - for key, value in self.action.items(): - stream.write_int(key) - value.write_to(stream) + self.action.write_to(stream) def __repr__(self): return "ActionMessage(" + \ repr(self.action) + \ diff --git a/clients/python/model/unit_action.py b/clients/python/model/unit_action.py index 12092bd..87f4f4d 100644 --- a/clients/python/model/unit_action.py +++ b/clients/python/model/unit_action.py @@ -1,11 +1,12 @@ from .vec2_double import Vec2Double class UnitAction: - def __init__(self, velocity, jump, jump_down, aim, shoot, swap_weapon, plant_mine): + def __init__(self, velocity, jump, jump_down, aim, shoot, reload, swap_weapon, plant_mine): self.velocity = velocity self.jump = jump self.jump_down = jump_down self.aim = aim self.shoot = shoot + self.reload = reload self.swap_weapon = swap_weapon self.plant_mine = plant_mine @staticmethod @@ -15,15 +16,17 @@ def read_from(stream): jump_down = stream.read_bool() aim = Vec2Double.read_from(stream) shoot = stream.read_bool() + reload = stream.read_bool() swap_weapon = stream.read_bool() plant_mine = stream.read_bool() - return UnitAction(velocity, jump, jump_down, aim, shoot, swap_weapon, plant_mine) + return UnitAction(velocity, jump, jump_down, aim, shoot, reload, swap_weapon, plant_mine) def write_to(self, stream): stream.write_double(self.velocity) stream.write_bool(self.jump) stream.write_bool(self.jump_down) self.aim.write_to(stream) stream.write_bool(self.shoot) + stream.write_bool(self.reload) stream.write_bool(self.swap_weapon) stream.write_bool(self.plant_mine) def __repr__(self): @@ -33,6 +36,7 @@ def __repr__(self): repr(self.jump_down) + "," + \ repr(self.aim) + "," + \ repr(self.shoot) + "," + \ + repr(self.reload) + "," + \ repr(self.swap_weapon) + "," + \ repr(self.plant_mine) + \ ")" diff --git a/clients/python/model/versioned.py b/clients/python/model/versioned.py new file mode 100644 index 0000000..956e9ce --- /dev/null +++ b/clients/python/model/versioned.py @@ -0,0 +1,22 @@ +from .unit_action import UnitAction +class Versioned: + def __init__(self, inner): + self.inner = inner + @staticmethod + def read_from(stream): + inner = {} + for _ in range(stream.read_int()): + inner_key = stream.read_int() + inner_value = UnitAction.read_from(stream) + inner[inner_key] = inner_value + return Versioned(inner) + def write_to(self, stream): + stream.write_int(43981) + stream.write_int(len(self.inner)) + for key, value in self.inner.items(): + stream.write_int(key) + value.write_to(stream) + def __repr__(self): + return "Versioned(" + \ + repr(self.inner) + \ + ")" diff --git a/clients/python/my_strategy.py b/clients/python/my_strategy.py index 1e5c3ef..be24e51 100644 --- a/clients/python/my_strategy.py +++ b/clients/python/my_strategy.py @@ -40,5 +40,6 @@ def distance_sqr(a, b): jump_down=not jump, aim=aim, shoot=True, + reload=False, swap_weapon=False, plant_mine=False) diff --git a/clients/ruby/main.rb b/clients/ruby/main.rb index 7507be6..ff60b9f 100644 --- a/clients/ruby/main.rb +++ b/clients/ruby/main.rb @@ -55,7 +55,7 @@ def run() actions[unit.id] = strategy.get_action(unit, player_view.game, debug) end end - PlayerMessageGame::ActionMessage.new(actions).write_to(@writer) + PlayerMessageGame::ActionMessage.new(Versioned.new(actions)).write_to(@writer) @writer.flush() end end diff --git a/clients/ruby/model.rb b/clients/ruby/model.rb index 2770dd0..fc3b71d 100644 --- a/clients/ruby/model.rb +++ b/clients/ruby/model.rb @@ -5,6 +5,7 @@ require_relative 'model/custom_data' require_relative 'model/vec2_double' require_relative 'model/unit_action' +require_relative 'model/versioned' require_relative 'model/player_message_game' require_relative 'model/weapon_type' require_relative 'model/bullet_params' diff --git a/clients/ruby/model/player_message_game.rb b/clients/ruby/model/player_message_game.rb index bedd3eb..91bc335 100644 --- a/clients/ruby/model/player_message_game.rb +++ b/clients/ruby/model/player_message_game.rb @@ -1,5 +1,5 @@ require_relative 'custom_data' -require_relative 'unit_action' +require_relative 'versioned' class PlayerMessageGame def self.read_from(stream) discriminant = stream.read_int() @@ -34,21 +34,12 @@ def initialize(action) @action = action end def self.read_from(stream) - action = Hash.new - stream.read_int().times do |_| - action_key = stream.read_int() - action_value = UnitAction.read_from(stream) - action[action_key] = action_value - end + action = Versioned.read_from(stream) ActionMessage.new(action) end def write_to(stream) stream.write_int(TAG) - stream.write_int(@action.length()) - @action.each do |key, value| - stream.write_int(key) - value.write_to(stream) - end + @action.write_to(stream) end end end diff --git a/clients/ruby/model/unit_action.rb b/clients/ruby/model/unit_action.rb index 9b8a290..0e3043d 100644 --- a/clients/ruby/model/unit_action.rb +++ b/clients/ruby/model/unit_action.rb @@ -5,14 +5,16 @@ class UnitAction attr_accessor :jump_down attr_accessor :aim attr_accessor :shoot + attr_accessor :reload attr_accessor :swap_weapon attr_accessor :plant_mine - def initialize(velocity, jump, jump_down, aim, shoot, swap_weapon, plant_mine) + def initialize(velocity, jump, jump_down, aim, shoot, reload, swap_weapon, plant_mine) @velocity = velocity @jump = jump @jump_down = jump_down @aim = aim @shoot = shoot + @reload = reload @swap_weapon = swap_weapon @plant_mine = plant_mine end @@ -22,9 +24,10 @@ def self.read_from(stream) jump_down = stream.read_bool() aim = Vec2Double.read_from(stream) shoot = stream.read_bool() + reload = stream.read_bool() swap_weapon = stream.read_bool() plant_mine = stream.read_bool() - UnitAction.new(velocity, jump, jump_down, aim, shoot, swap_weapon, plant_mine) + UnitAction.new(velocity, jump, jump_down, aim, shoot, reload, swap_weapon, plant_mine) end def write_to(stream) stream.write_double(@velocity) @@ -32,6 +35,7 @@ def write_to(stream) stream.write_bool(@jump_down) @aim.write_to(stream) stream.write_bool(@shoot) + stream.write_bool(@reload) stream.write_bool(@swap_weapon) stream.write_bool(@plant_mine) end diff --git a/clients/ruby/model/versioned.rb b/clients/ruby/model/versioned.rb new file mode 100644 index 0000000..405fed0 --- /dev/null +++ b/clients/ruby/model/versioned.rb @@ -0,0 +1,24 @@ +require_relative 'unit_action' +class Versioned + attr_accessor :inner + def initialize(inner) + @inner = inner + end + def self.read_from(stream) + inner = Hash.new + stream.read_int().times do |_| + inner_key = stream.read_int() + inner_value = UnitAction.read_from(stream) + inner[inner_key] = inner_value + end + Versioned.new(inner) + end + def write_to(stream) + stream.write_int(43981) + stream.write_int(@inner.length()) + @inner.each do |key, value| + stream.write_int(key) + value.write_to(stream) + end + end +end diff --git a/clients/ruby/my_strategy.rb b/clients/ruby/my_strategy.rb index 59fbc44..684f3e9 100644 --- a/clients/ruby/my_strategy.rb +++ b/clients/ruby/my_strategy.rb @@ -46,8 +46,9 @@ def distance_sqr(a, b) jump_down = !jump aim = aim shoot = true + reload = false swap_weapon = false plant_mine = false - UnitAction.new(velocity, jump, jump_down, aim, shoot, swap_weapon, plant_mine) + UnitAction.new(velocity, jump, jump_down, aim, shoot, reload, swap_weapon, plant_mine) end end \ No newline at end of file diff --git a/clients/rust/model/src/lib.rs b/clients/rust/model/src/lib.rs index 0008fdf..4a380a1 100644 --- a/clients/rust/model/src/lib.rs +++ b/clients/rust/model/src/lib.rs @@ -20,6 +20,9 @@ pub use self::vec2_f64::*; mod unit_action; pub use self::unit_action::*; +mod versioned; +pub use self::versioned::*; + mod player_message_game; pub use self::player_message_game::*; diff --git a/clients/rust/model/src/player_message_game.rs b/clients/rust/model/src/player_message_game.rs index c196960..a8067b3 100644 --- a/clients/rust/model/src/player_message_game.rs +++ b/clients/rust/model/src/player_message_game.rs @@ -5,6 +5,6 @@ pub enum PlayerMessageGame { data: CustomData, }, ActionMessage { - action: std::collections::HashMap, + action: Versioned, }, } diff --git a/clients/rust/model/src/unit_action.rs b/clients/rust/model/src/unit_action.rs index 83edf12..e07fc74 100644 --- a/clients/rust/model/src/unit_action.rs +++ b/clients/rust/model/src/unit_action.rs @@ -6,6 +6,7 @@ pub struct UnitAction { pub jump_down: bool, pub aim: Vec2F64, pub shoot: bool, + pub reload: bool, pub swap_weapon: bool, pub plant_mine: bool, } diff --git a/clients/rust/model/src/versioned.rs b/clients/rust/model/src/versioned.rs new file mode 100644 index 0000000..0c74023 --- /dev/null +++ b/clients/rust/model/src/versioned.rs @@ -0,0 +1,6 @@ +use crate::*; +#[derive(Clone, Debug, trans::Trans)] +#[trans(magic = "43981")] +pub struct Versioned { + pub inner: std::collections::HashMap, +} diff --git a/clients/rust/model/trans/derive/src/lib.rs b/clients/rust/model/trans/derive/src/lib.rs index 4914b64..77186aa 100644 --- a/clients/rust/model/trans/derive/src/lib.rs +++ b/clients/rust/model/trans/derive/src/lib.rs @@ -5,12 +5,47 @@ use quote::quote; use proc_macro2::TokenStream; -#[proc_macro_derive(Trans)] +#[proc_macro_derive(Trans, attributes(trans))] pub fn derive_trans(input: proc_macro::TokenStream) -> proc_macro::TokenStream { let input: TokenStream = input.into(); let result: TokenStream = { let ast: syn::DeriveInput = syn::parse_str(&input.to_string()).unwrap(); let input_type = &ast.ident; + let mut magic: Option = None; + for attr in &ast.attrs { + if let Ok(syn::Meta::List(syn::MetaList { + path: ref meta_path, + nested: ref nested, + .. + })) = attr.parse_meta() + { + if meta_path.is_ident("trans") { + for inner in nested { + if let syn::NestedMeta::Meta(syn::Meta::NameValue(syn::MetaNameValue { + path: ref meta_path, + lit: syn::Lit::Str(ref lit), + .. + })) = *inner + { + if meta_path.is_ident("magic") { + magic = Some(syn::parse_str(&lit.value()).unwrap()); + } + } + } + } + } + } + let (magic_write, magic_read) = match magic { + Some(magic) => ( + quote! { + trans::Trans::write_to(&#magic, &mut writer)?; + }, + quote! { + assert_eq!(::read_from(&mut reader)?, #magic); + }, + ), + None => (quote! {}, quote! {}), + }; match ast.data { syn::Data::Struct(syn::DataStruct { ref fields, .. }) => { let field_tys: Vec<_> = fields.iter().map(|field| &field.ty).collect(); @@ -40,10 +75,12 @@ pub fn derive_trans(input: proc_macro::TokenStream) -> proc_macro::TokenStream { let expanded = quote! { impl #impl_generics trans::Trans for #input_type #ty_generics #where_clause { fn write_to(&self, mut writer: impl std::io::Write) -> std::io::Result<()> { + #magic_write #(trans::Trans::write_to(&self.#field_names, &mut writer)?;)* Ok(()) } fn read_from(mut reader: impl std::io::Read) -> std::io::Result { + #magic_read Ok(Self { #(#field_names: trans::Trans::read_from(&mut reader)?),* }) diff --git a/clients/rust/src/main.rs b/clients/rust/src/main.rs index f3e6a9a..efbaf66 100644 --- a/clients/rust/src/main.rs +++ b/clients/rust/src/main.rs @@ -73,7 +73,9 @@ impl Runner { strategy.get_action(unit, &player_view.game, &mut Debug(&mut self.writer)); actions.insert(unit.id, action); } - let message = model::PlayerMessageGame::ActionMessage { action: actions }; + let message = model::PlayerMessageGame::ActionMessage { + action: model::Versioned { inner: actions }, + }; message.write_to(&mut self.writer)?; self.writer.flush()?; } diff --git a/clients/rust/src/my_strategy.rs b/clients/rust/src/my_strategy.rs index 456c681..7e42075 100644 --- a/clients/rust/src/my_strategy.rs +++ b/clients/rust/src/my_strategy.rs @@ -76,6 +76,7 @@ impl MyStrategy { jump_down: target_pos.y < unit.position.y, aim, shoot: true, + reload: false, swap_weapon: false, plant_mine: false, } diff --git a/clients/scala/src/main/scala/MyStrategy.scala b/clients/scala/src/main/scala/MyStrategy.scala index 5b728f0..9497783 100644 --- a/clients/scala/src/main/scala/MyStrategy.scala +++ b/clients/scala/src/main/scala/MyStrategy.scala @@ -39,6 +39,7 @@ class MyStrategy { jumpDown = !jump, aim = aim, shoot = true, + reload = false, swapWeapon = false, plantMine = false) } diff --git a/clients/scala/src/main/scala/Runner.scala b/clients/scala/src/main/scala/Runner.scala index 19710f1..c17e7cc 100644 --- a/clients/scala/src/main/scala/Runner.scala +++ b/clients/scala/src/main/scala/Runner.scala @@ -35,7 +35,7 @@ object Runner extends App { .map(x => (x.id, myStrategy.getAction(x, playerView.game, debug))) .toMap - ActionMessage(actions).writeTo(outputStream) + ActionMessage(model.Versioned(actions)).writeTo(outputStream) outputStream.flush() } } diff --git a/clients/scala/src/main/scala/model/PlayerMessageGame.scala b/clients/scala/src/main/scala/model/PlayerMessageGame.scala index 1851890..a50e95c 100644 --- a/clients/scala/src/main/scala/model/PlayerMessageGame.scala +++ b/clients/scala/src/main/scala/model/PlayerMessageGame.scala @@ -19,24 +19,16 @@ object PlayerMessageGame { ) } - case class ActionMessage(action: Map[Int, model.UnitAction]) extends PlayerMessageGame { + case class ActionMessage(action: model.Versioned) extends PlayerMessageGame { override def writeTo(stream: java.io.OutputStream) { StreamUtil.writeInt(stream, ActionMessage.TAG) - StreamUtil.writeInt(stream, action.size) - action.foreach { case (key, value) => - StreamUtil.writeInt(stream, key) - value.writeTo(stream) - } + action.writeTo(stream) } } object ActionMessage { val TAG: Int = 1 def readFrom(stream: java.io.InputStream): ActionMessage = ActionMessage( - (0 until StreamUtil.readInt(stream)).map { _ => ( - StreamUtil.readInt(stream) - , - model.UnitAction.readFrom(stream) - )}.toMap + model.Versioned.readFrom(stream) ) } diff --git a/clients/scala/src/main/scala/model/UnitAction.scala b/clients/scala/src/main/scala/model/UnitAction.scala index b9ccc07..b198a1b 100644 --- a/clients/scala/src/main/scala/model/UnitAction.scala +++ b/clients/scala/src/main/scala/model/UnitAction.scala @@ -2,13 +2,14 @@ package model import util.StreamUtil -case class UnitAction(velocity: Double, jump: Boolean, jumpDown: Boolean, aim: model.Vec2Double, shoot: Boolean, swapWeapon: Boolean, plantMine: Boolean) { +case class UnitAction(velocity: Double, jump: Boolean, jumpDown: Boolean, aim: model.Vec2Double, shoot: Boolean, reload: Boolean, swapWeapon: Boolean, plantMine: Boolean) { def writeTo(stream: java.io.OutputStream) { StreamUtil.writeDouble(stream, velocity) StreamUtil.writeBoolean(stream, jump) StreamUtil.writeBoolean(stream, jumpDown) aim.writeTo(stream) StreamUtil.writeBoolean(stream, shoot) + StreamUtil.writeBoolean(stream, reload) StreamUtil.writeBoolean(stream, swapWeapon) StreamUtil.writeBoolean(stream, plantMine) } @@ -28,5 +29,7 @@ object UnitAction { StreamUtil.readBoolean(stream) , StreamUtil.readBoolean(stream) + , + StreamUtil.readBoolean(stream) ) } diff --git a/clients/scala/src/main/scala/model/Versioned.scala b/clients/scala/src/main/scala/model/Versioned.scala new file mode 100644 index 0000000..e17ab2d --- /dev/null +++ b/clients/scala/src/main/scala/model/Versioned.scala @@ -0,0 +1,23 @@ +package model + +import util.StreamUtil + +case class Versioned(inner: Map[Int, model.UnitAction]) { + def writeTo(stream: java.io.OutputStream) { + StreamUtil.writeInt(stream, 43981) + StreamUtil.writeInt(stream, inner.size) + inner.foreach { case (key, value) => + StreamUtil.writeInt(stream, key) + value.writeTo(stream) + } + } +} +object Versioned { + def readFrom(stream: java.io.InputStream): Versioned = Versioned( + (0 until StreamUtil.readInt(stream)).map { _ => ( + StreamUtil.readInt(stream) + , + model.UnitAction.readFrom(stream) + )}.toMap + ) +} diff --git a/docs/en/API.tex b/docs/en/API.tex index 0e2a408..1d8c050 100644 --- a/docs/en/API.tex +++ b/docs/en/API.tex @@ -254,6 +254,7 @@ \subsection{UnitAction} \item $jump\_down : boolean$ --- whether to jump down through platforms/go down ladders \item $aim : Vec2 \langle float64 \rangle$ --- aiming direction. Ignored if length is less than $0.5$ \item $shoot : boolean$ --- controls shooting/reloading + \item $reload : boolean$ --- whether to reload your weapon \item $swap\_weapon : boolean$ --- whether to swap weapon with the one in a loot box \item $plant\_mine : boolean$ --- controls planting mines \end{itemize} diff --git a/docs/en/Doc.tex b/docs/en/Doc.tex index b91e019..f36426a 100644 --- a/docs/en/Doc.tex +++ b/docs/en/Doc.tex @@ -29,7 +29,7 @@ \textsc{\Huge CodeSide 2019}\\ \vspace{0.50in} \textsc{\LARGE Rules}\\ -\textsc{\small Version 0.1.2}\\ +\textsc{\small Version 0.2.0}\\ \vspace{2.75in} } diff --git a/docs/en/Rules.tex b/docs/en/Rules.tex index 8307ea1..917ff6a 100644 --- a/docs/en/Rules.tex +++ b/docs/en/Rules.tex @@ -210,10 +210,8 @@ \section{Shooting} For the first tick upon picking a weapon, this value is absent. \end{itemize} -Reloading a weapon happens automatically. First, when the weapon is just picked up. -Then, if ammo in current magazine reaches zero, -or if your strategy tells the unit to stop shooting while the magazine is not full, -unit also reloads the weapon. +When weapon is first picked up, it starts with being reloaded. +Reloading a weapon also happens automatically if ammo in current magazine reaches zero. \section{Mines} diff --git a/docs/ru/API.tex b/docs/ru/API.tex index 634a00d..48fe9bb 100644 --- a/docs/ru/API.tex +++ b/docs/ru/API.tex @@ -255,6 +255,7 @@ \subsection{UnitAction} \item $jump\_down : boolean$ --- спрыгивать с/сквозь платформы/вниз по лестнице \item $aim : Vec2 \langle float64 \rangle$ --- направление прицеливания. Игнорируется если длина меньше $0.5$ \item $shoot : boolean$ --- контролирует стрельбу/перезарядку + \item $reload : boolean$ --- перезарядка оружия \item $swap\_weapon : boolean$ --- поменять оружие \item $plant\_mine : boolean$ --- установить мину \end{itemize} diff --git a/docs/ru/Doc.tex b/docs/ru/Doc.tex index 047a3e2..a989a20 100644 --- a/docs/ru/Doc.tex +++ b/docs/ru/Doc.tex @@ -29,7 +29,7 @@ \textsc{\Huge CodeSide 2019}\\ \vspace{0.50in} \textsc{\LARGE Правила}\\ -\textsc{\small Версия 0.1.2}\\ +\textsc{\small Версия 0.2.0}\\ \vspace{2.75in} } diff --git a/docs/ru/Rules.tex b/docs/ru/Rules.tex index ec1edad..9acb3bf 100644 --- a/docs/ru/Rules.tex +++ b/docs/ru/Rules.tex @@ -212,8 +212,8 @@ \section{Стрельба} Во время первого тика после подбора оружия, это значение отсутствует. \end{itemize} -Перезарядка оружия происходит автоматически. Первый раз --- при подборе оружия. -Затем, в случаях если текущая обойма пустая, а так же если стратегия указывает юниту прекратить огонь при неполной обойме. +При подборе оружия происходит перезарядка. +Также перезарядка происходит автоматически в случае пустой обоймы. \section{Мины}