diff --git a/clients/elixir_client/README.md b/clients/elixir_client/README.md new file mode 100644 index 0000000..7e5ea4f --- /dev/null +++ b/clients/elixir_client/README.md @@ -0,0 +1,9 @@ +# elx_small_http_cowboy + +Elixir client + +Build: +> mix deps.get + +Run: +> WORLD_NAME="hostname" SOLUTION_ID="123" iex -S mix diff --git a/clients/elixir_client/lib/elixir_client.ex b/clients/elixir_client/lib/elixir_client.ex new file mode 100644 index 0000000..48dc728 --- /dev/null +++ b/clients/elixir_client/lib/elixir_client.ex @@ -0,0 +1,49 @@ +defmodule ElixirClient do + use Application + import Supervisor.Spec + + def start(_type, _args) do + + host = case System.get_env()["WORLD_NAME"] do + nil -> fatal_error("env WORLD_NAME not set") + world_name -> world_name + end + + solution_id = case System.get_env()["SOLUTION_ID"] do + nil -> fatal_error("env SOLUTION_ID not set") + str_solution_id -> + {solution_id, _} = Integer.parse(str_solution_id) + solution_id + end + + IO.puts "Host: #{host}" + ip = case :inet.gethostbyname(String.to_char_list(host)) do + {:ok, {:hostent, _, [], :inet, 4, ip_list}} -> + ip_list + |> hd() + |> :inet_parse.ntoa() + |> to_string() + {:error, :nxdomain} -> + fatal_error("Can't determine host") + end + + port = 8000 + + IO.puts "IPv4 address: #{inspect ip}" + IO.puts "Port: #{inspect port}" + IO.puts "SOLUTION_ID: #{inspect solution_id}" + + childrens = [ + worker(Strategy, []), + worker(ElixirClient.Api, []), + worker(ElixirClient.Client, [{host, port, solution_id}]) + ] + + Supervisor.start_link(childrens, strategy: :one_for_one) + end + + defp fatal_error(message) do + IO.puts(message) + throw(message) + end +end diff --git a/clients/elixir_client/lib/elixir_client/api.ex b/clients/elixir_client/lib/elixir_client/api.ex new file mode 100644 index 0000000..529c70b --- /dev/null +++ b/clients/elixir_client/lib/elixir_client/api.ex @@ -0,0 +1,105 @@ +defmodule Elevator do + defstruct id: nil, y: nil, passengers: nil, state: nil, + speed: nil, floor: nil, next_floor: nil, + time_on_floor: nil, type: nil + + use ExConstructor + # goToFloor + def go_to_floor(elevator, floor) do + cmd_map = %{command: "go_to_floor", + args: %{ + elevator_id: elevator.id, + floor: floor + }} + ElixirClient.Api.add_command(cmd_map) + end +end + +defmodule Passenger do + defstruct id: nil, elevator: nil, x: nil, y: nil, state: nil, + time_to_away: nil, from_floor: nil, + dest_floor: nil, type: nil, floor: nil + + use ExConstructor + def has_elevator(passenger) do + passenger.elevator != nil + end + + def set_elevator(passenger, elevator) do + cmd_map = %{command: "set_elevator_to_passenger", + args: %{ + elevator_id: elevator.id, + passenger_id: passenger.id + }} + ElixirClient.Api.add_command(cmd_map) + end +end + + +defmodule ElixirClient.Api do + use GenServer + require Logger + + def start_link() do + GenServer.start_link(__MODULE__, :ok, name: __MODULE__) + end + + def init(:ok) do + # Logger.info "api init" + {:ok, %{commands: []}} + end + + def generate_actions(json_actions) do + # Logger.info "api generate_actions" + :gen_server.cast(__MODULE__, {:generate_actions, json_actions}) + end + + def add_command(command) do + # Logger.info "api generate_actions" + :gen_server.cast(__MODULE__, {:add_command, command}) + end + + def get_state() do + # Logger.info "api generate_actions" + :gen_server.call(__MODULE__, :get_state) + end + + def handle_cast({:generate_actions, json_actions}, state) do + # Logger.info "api generate_actions rcv json=#{inspect json_actions}" + + # обработка входящих и генерация исходящих + my_elevators = ElixirClient.Api.parse_elevators(json_actions["my_elevators"]) + my_passengers = ElixirClient.Api.parse_passengers(json_actions["my_passengers"]) + enemy_elevators = ElixirClient.Api.parse_elevators(json_actions["enemy_elevators"]) + enemy_passengers = ElixirClient.Api.parse_passengers(json_actions["enemy_passengers"]) + + Strategy.on_tick(my_elevators, my_passengers, enemy_elevators, enemy_passengers) + + array_actions = Enum.reverse(state.commands) + + # отправка + ElixirClient.Client.send_actions(array_actions) + + {:noreply, %{state | commands: [] }} + end + + def handle_cast({:add_command, command}, state) do + # Logger.info "api generate_actions rcv json=#{inspect json_actions}" + + {:noreply, %{state | commands: [command] ++ state.commands}} + end + + def handle_call(:get_state, _from, state) do + {:reply, Enum.reverse(state.commands), state} + end + + def parse_elevators(data) do + Enum.map(data, fn(el) -> + new_el = Elevator.new(el) + %{new_el | passengers: parse_passengers(new_el.passengers)} + end) + end + + def parse_passengers(data), do: Enum.map(data, &Passenger.new(&1)) + +end diff --git a/clients/elixir_client/lib/elixir_client/client.ex b/clients/elixir_client/lib/elixir_client/client.ex new file mode 100644 index 0000000..69af658 --- /dev/null +++ b/clients/elixir_client/lib/elixir_client/client.ex @@ -0,0 +1,94 @@ +defmodule ElixirClient.Client do + use GenServer + require Logger + + def start_link(options) do + GenServer.start_link(__MODULE__, options, name: __MODULE__) + end + + def send_actions(json_actions) do + :gen_server.cast(__MODULE__, {:send_actions, json_actions}) + end + + # Server Callbacks + + def init({host, port, solution_id} = options) do + Logger.info "client init #{inspect options}" + + {:ok, socket} = :gen_tcp.connect(String.to_char_list(host), + port, [:binary, {:packet, :line}, {:active, true}]) + + json = Poison.encode!(%{solution_id: solution_id}) <> "\n" + msg = String.to_char_list(json) + :gen_tcp.send(socket, msg) + + {:ok, %{options: options, socket: socket, transmitting: false, sdata: ""}} + end + + def handle_cast({:send_actions, json_actions}, state) do + # Logger.info "client send_actions #{inspect json_actions}" + json = Poison.encode!(json_actions) <> "\n" + msg = String.to_char_list(json) + :gen_tcp.send(state.socket, msg) + {:noreply, state} + end + + def handle_info({:tcp, _port, msg}, state) do + rcvd = state.sdata <> msg + + case String.contains?(rcvd, "\n") do + true -> + array_of_json = String.split(rcvd, "\n") + # Logger.debug ">>>> array_of_json=#{inspect array_of_json}" + # spawn(__MODULE__, :parse_jsons, [array_of_json]) + parse_jsons(array_of_json) + + {:noreply, %{state | sdata: List.last(array_of_json) }} + _else -> + {:noreply, %{state | sdata: rcvd }} + end + end + + def handle_info({:data_to_decode, data}, state) do + # Logger.info "handle_info data_to_decode data=#{inspect data}" + json = Poison.decode!(data) + handle_json(state, json) + # {:noreply, state} + end + + def handle_info(_msg, state) do + # Logger.info "handle_info msg=#{inspect msg}" + + {:noreply, state} + end + + def parse_jsons([""]) do + "" + end + def parse_jsons([not_ended_tail]) do + not_ended_tail + end + def parse_jsons([head | tail]) do + send(self(), {:data_to_decode, head}) + parse_jsons(tail) + end + + defp handle_json(state, %{"message" => "beginning"} = _json) do + Logger.info "client beginning" + {:noreply, %{state | transmitting: true}} + end + + defp handle_json(state, %{"message" => "down"} = _json) do + Logger.info "client down" + :gen_tcp.close(state.socket) + {:noreply, %{state | socket: nil, transmitting: false}} + end + + # сообщение не beginning и не down + defp handle_json(state, json) do + # Logger.info "client rcv json=#{inspect json}" + ElixirClient.Api.generate_actions(json) + {:noreply, state} + end + +end \ No newline at end of file diff --git a/clients/elixir_client/lib/strategy.ex b/clients/elixir_client/lib/strategy.ex new file mode 100644 index 0000000..a2f4c8e --- /dev/null +++ b/clients/elixir_client/lib/strategy.ex @@ -0,0 +1,39 @@ +defmodule Strategy do + # модуль стратегии - генсервер. на случай, если в стратегии + # захочется хранить какое-то состояние между тиками + use GenServer + require Logger + + # Коды состояний лифтов ELEVATOR_STATE + @timeout_check + @waiting 0 + @moving 1 + @opening 2 + @filling 3 # забирает и/или высаживает пассажиров + @closing 4 + + # Коды состояний пассажиров PASSENGER_STATE + @waiting_for_elevator 1 # ждет лифт + @moving_to_elevator 2 # идет к лифту + @returning 3 # возвращается обратно, если лифт уехал + @moving_to_floor 4 # идет по лестнице + @using_elevator 5 # едет в лифте + @exiting 6 # выходит из лифта + + def on_tick(my_elevators, my_passengers, enemy_elevators, enemy_passengers) do + # Enum.map(my_elevators, fn(el) -> + # Elevator.go_to_floor(el, 1) + # end) + # hd(my_passengers) + # |> Passenger.set_elevator(hd(my_elevators)) + end + + def start_link() do + GenServer.start_link(__MODULE__, %{}, name: __MODULE__) + end + + def init(state) do + Logger.info "Strategy init state=#{inspect state}" + {:ok, state} + end +end diff --git a/clients/elixir_client/mix.exs b/clients/elixir_client/mix.exs new file mode 100644 index 0000000..ce60d78 --- /dev/null +++ b/clients/elixir_client/mix.exs @@ -0,0 +1,24 @@ +defmodule ElixirClient.Mixfile do + use Mix.Project + + def project do + [app: :elixir_client, + version: "0.1.0", + elixir: "~> 1.3", + build_embedded: Mix.env == :prod, + start_permanent: Mix.env == :prod, + deps: deps()] + end + + def application do + [applications: [:logger, :exconstructor], + mod: {ElixirClient, []}] + end + + defp deps do + [ + {:poison, "~> 3.1"}, + {:exconstructor, "~> 1.1.0"} + ] + end +end diff --git a/clients/elixir_client/mix.lock b/clients/elixir_client/mix.lock new file mode 100644 index 0000000..219446c --- /dev/null +++ b/clients/elixir_client/mix.lock @@ -0,0 +1,7 @@ +%{"cowboy": {:hex, :cowboy, "1.1.2", "61ac29ea970389a88eca5a65601460162d370a70018afe6f949a29dca91f3bb0", [], [{:cowlib, "~> 1.0.2", [hex: :cowlib, repo: "hexpm", optional: false]}, {:ranch, "~> 1.3.2", [hex: :ranch, repo: "hexpm", optional: false]}], "hexpm"}, + "cowlib": {:hex, :cowlib, "1.0.2", "9d769a1d062c9c3ac753096f868ca121e2730b9a377de23dec0f7e08b1df84ee", [], [], "hexpm"}, + "exconstructor": {:hex, :exconstructor, "1.1.0", "272623a7b203cb2901c20cbb92c5c3ab103cc0087ff7c881979e046043346752", [], [], "hexpm"}, + "mime": {:hex, :mime, "1.1.0", "01c1d6f4083d8aa5c7b8c246ade95139620ef8effb009edde934e0ec3b28090a", [], [], "hexpm"}, + "plug": {:hex, :plug, "1.4.3", "236d77ce7bf3e3a2668dc0d32a9b6f1f9b1f05361019946aae49874904be4aed", [], [{:cowboy, "~> 1.0.1 or ~> 1.1", [hex: :cowboy, repo: "hexpm", optional: true]}, {:mime, "~> 1.0", [hex: :mime, repo: "hexpm", optional: false]}], "hexpm"}, + "poison": {:hex, :poison, "3.1.0", "d9eb636610e096f86f25d9a46f35a9facac35609a7591b3be3326e99a0484665", [], [], "hexpm"}, + "ranch": {:hex, :ranch, "1.3.2", "e4965a144dc9fbe70e5c077c65e73c57165416a901bd02ea899cfd95aa890986", [], [], "hexpm"}} diff --git a/clients/elixir_client/priv/from_cli.json b/clients/elixir_client/priv/from_cli.json new file mode 100644 index 0000000..5292945 --- /dev/null +++ b/clients/elixir_client/priv/from_cli.json @@ -0,0 +1 @@ +[{"args": {"elevator_id": 1, "floor": 1}, "command": "go_to_floor"}, {"args": {"elevator_id": 1, "floor": 1}, "command": "go_to_floor"}, {"args": {"elevator_id": 1, "floor": 6}, "command": "go_to_floor"}, {"args": {"elevator_id": 2, "floor": 1}, "command": "go_to_floor"}, {"args": {"elevator_id": 2, "floor": 1}, "command": "go_to_floor"}, {"args": {"elevator_id": 3, "floor": 1}, "command": "go_to_floor"}, {"args": {"elevator_id": 3, "floor": 1}, "command": "go_to_floor"}, {"args": {"elevator_id": 4, "floor": 1}, "command": "go_to_floor"}, {"args": {"elevator_id": 4, "floor": 1}, "command": "go_to_floor"}, {"args": {"passenger_id": 8, "elevator_id": 1}, "command": "set_elevator_to_passenger"}, {"args": {"passenger_id": 8, "elevator_id": 2}, "command": "set_elevator_to_passenger"}, {"args": {"passenger_id": 8, "elevator_id": 3}, "command": "set_elevator_to_passenger"}, {"args": {"passenger_id": 8, "elevator_id": 4}, "command": "set_elevator_to_passenger"}, {"args": {"passenger_id": 10, "elevator_id": 1}, "command": "set_elevator_to_passenger"}, {"args": {"passenger_id": 10, "elevator_id": 2}, "command": "set_elevator_to_passenger"}, {"args": {"passenger_id": 10, "elevator_id": 3}, "command": "set_elevator_to_passenger"}, {"args": {"passenger_id": 10, "elevator_id": 4}, "command": "set_elevator_to_passenger"}] diff --git a/clients/elixir_client/priv/from_cli.py b/clients/elixir_client/priv/from_cli.py new file mode 100644 index 0000000..206be42 --- /dev/null +++ b/clients/elixir_client/priv/from_cli.py @@ -0,0 +1,3 @@ +import json +js = [{u'args': {u'elevator_id': 1, u'floor': 1}, u'command': u'go_to_floor'}, {u'args': {u'elevator_id': 1, u'floor': 1}, u'command': u'go_to_floor'}, {u'args': {u'elevator_id': 1, u'floor': 6}, u'command': u'go_to_floor'}, {u'args': {u'elevator_id': 2, u'floor': 1}, u'command': u'go_to_floor'}, {u'args': {u'elevator_id': 2, u'floor': 1}, u'command': u'go_to_floor'}, {u'args': {u'elevator_id': 3, u'floor': 1}, u'command': u'go_to_floor'}, {u'args': {u'elevator_id': 3, u'floor': 1}, u'command': u'go_to_floor'}, {u'args': {u'elevator_id': 4, u'floor': 1}, u'command': u'go_to_floor'}, {u'args': {u'elevator_id': 4, u'floor': 1}, u'command': u'go_to_floor'}, {u'args': {u'passenger_id': 8, u'elevator_id': 1}, u'command': u'set_elevator_to_passenger'}, {u'args': {u'passenger_id': 8, u'elevator_id': 2}, u'command': u'set_elevator_to_passenger'}, {u'args': {u'passenger_id': 8, u'elevator_id': 3}, u'command': u'set_elevator_to_passenger'}, {u'args': {u'passenger_id': 8, u'elevator_id': 4}, u'command': u'set_elevator_to_passenger'}, {u'args': {u'passenger_id': 10, u'elevator_id': 1}, u'command': u'set_elevator_to_passenger'}, {u'args': {u'passenger_id': 10, u'elevator_id': 2}, u'command': u'set_elevator_to_passenger'}, {u'args': {u'passenger_id': 10, u'elevator_id': 3}, u'command': u'set_elevator_to_passenger'}, {u'args': {u'passenger_id': 10, u'elevator_id': 4}, u'command': u'set_elevator_to_passenger'}] +print json.dumps(js) \ No newline at end of file diff --git a/clients/elixir_client/priv/from_cli.txt b/clients/elixir_client/priv/from_cli.txt new file mode 100644 index 0000000..faad7c1 --- /dev/null +++ b/clients/elixir_client/priv/from_cli.txt @@ -0,0 +1 @@ +[{u'args': {u'elevator_id': 1, u'floor': 1}, u'command': u'go_to_floor'}, {u'args': {u'elevator_id': 1, u'floor': 1}, u'command': u'go_to_floor'}, {u'args': {u'elevator_id': 1, u'floor': 6}, u'command': u'go_to_floor'}, {u'args': {u'elevator_id': 2, u'floor': 1}, u'command': u'go_to_floor'}, {u'args': {u'elevator_id': 2, u'floor': 1}, u'command': u'go_to_floor'}, {u'args': {u'elevator_id': 3, u'floor': 1}, u'command': u'go_to_floor'}, {u'args': {u'elevator_id': 3, u'floor': 1}, u'command': u'go_to_floor'}, {u'args': {u'elevator_id': 4, u'floor': 1}, u'command': u'go_to_floor'}, {u'args': {u'elevator_id': 4, u'floor': 1}, u'command': u'go_to_floor'}, {u'args': {u'passenger_id': 8, u'elevator_id': 1}, u'command': u'set_elevator_to_passenger'}, {u'args': {u'passenger_id': 8, u'elevator_id': 2}, u'command': u'set_elevator_to_passenger'}, {u'args': {u'passenger_id': 8, u'elevator_id': 3}, u'command': u'set_elevator_to_passenger'}, {u'args': {u'passenger_id': 8, u'elevator_id': 4}, u'command': u'set_elevator_to_passenger'}, {u'args': {u'passenger_id': 10, u'elevator_id': 1}, u'command': u'set_elevator_to_passenger'}, {u'args': {u'passenger_id': 10, u'elevator_id': 2}, u'command': u'set_elevator_to_passenger'}, {u'args': {u'passenger_id': 10, u'elevator_id': 3}, u'command': u'set_elevator_to_passenger'}, {u'args': {u'passenger_id': 10, u'elevator_id': 4}, u'command': u'set_elevator_to_passenger'}] diff --git a/clients/elixir_client/priv/to_cli.json b/clients/elixir_client/priv/to_cli.json new file mode 100644 index 0000000..e6bfd47 --- /dev/null +++ b/clients/elixir_client/priv/to_cli.json @@ -0,0 +1 @@ +{"my_elevators": [{"passengers": [{"dest_floor": 6, "state": 5, "floor": 1, "y": 1, "x": 60, "time_to_away": 418, "type": "FIRST_PLAYER", "from_floor": 1, "elevator": 1, "id": 1}, {"dest_floor": 2, "state": 5, "floor": 1, "y": 1, "x": 60, "time_to_away": 438, "type": "FIRST_PLAYER", "from_floor": 1, "elevator": 1, "id": 3}, {"dest_floor": 3, "state": 5, "floor": 1, "y": 1, "x": 60, "time_to_away": 458, "type": "FIRST_PLAYER", "from_floor": 1, "elevator": 1, "id": 5}], "state": 4, "time_on_floor": 85, "next_floor": 6, "floor": 1, "y": 1, "speed": 0.01557632741922111, "type": "SECOND_PLAYER", "id": 1}, {"passengers": [], "state": 3, "time_on_floor": 85, "next_floor": 1, "floor": 1, "y": 1, "speed": 0.02, "type": "SECOND_PLAYER", "id": 2}, {"passengers": [], "state": 3, "time_on_floor": 85, "next_floor": 1, "floor": 1, "y": 1, "speed": 0.02, "type": "SECOND_PLAYER", "id": 3}, {"passengers": [], "state": 3, "time_on_floor": 85, "next_floor": 1, "floor": 1, "y": 1, "speed": 0.02, "type": "SECOND_PLAYER", "id": 4}], "my_passengers": [{"dest_floor": 6, "state": 5, "floor": 1, "y": 1, "x": -60, "time_to_away": 418, "type": "SECOND_PLAYER", "from_floor": 1, "elevator": 1, "id": 2}, {"dest_floor": 2, "state": 5, "floor": 1, "y": 1, "x": -60, "time_to_away": 438, "type": "SECOND_PLAYER", "from_floor": 1, "elevator": 1, "id": 4}, {"dest_floor": 3, "state": 5, "floor": 1, "y": 1, "x": -60, "time_to_away": 458, "type": "SECOND_PLAYER", "from_floor": 1, "elevator": 1, "id": 6}, {"dest_floor": 5, "state": 3, "floor": 1, "y": 1, "x": -18, "time_to_away": 475, "type": "SECOND_PLAYER", "from_floor": 1, "elevator": null, "id": 8}, {"dest_floor": 7, "state": 2, "floor": 1, "y": 1, "x": 20, "time_to_away": 495, "type": "SECOND_PLAYER", "from_floor": 1, "elevator": 2, "id": 10}], "enemy_passengers": [{"dest_floor": 6, "state": 5, "floor": 1, "y": 1, "x": 60, "time_to_away": 418, "type": "FIRST_PLAYER", "from_floor": 1, "elevator": 1, "id": 1}, {"dest_floor": 2, "state": 5, "floor": 1, "y": 1, "x": 60, "time_to_away": 438, "type": "FIRST_PLAYER", "from_floor": 1, "elevator": 1, "id": 3}, {"dest_floor": 3, "state": 5, "floor": 1, "y": 1, "x": 60, "time_to_away": 458, "type": "FIRST_PLAYER", "from_floor": 1, "elevator": 1, "id": 5}, {"dest_floor": 5, "state": 3, "floor": 1, "y": 1, "x": 18, "time_to_away": 475, "type": "FIRST_PLAYER", "from_floor": 1, "elevator": null, "id": 7}, {"dest_floor": 7, "state": 2, "floor": 1, "y": 1, "x": -20, "time_to_away": 495, "type": "FIRST_PLAYER", "from_floor": 1, "elevator": 2, "id": 9}], "enemy_elevators": [{"passengers": [{"dest_floor": 6, "state": 5, "floor": 1, "y": 1, "x": -60, "time_to_away": 418, "type": "SECOND_PLAYER", "from_floor": 1, "elevator": 1, "id": 2}, {"dest_floor": 2, "state": 5, "floor": 1, "y": 1, "x": -60, "time_to_away": 438, "type": "SECOND_PLAYER", "from_floor": 1, "elevator": 1, "id": 4}, {"dest_floor": 3, "state": 5, "floor": 1, "y": 1, "x": -60, "time_to_away": 458, "type": "SECOND_PLAYER", "from_floor": 1, "elevator": 1, "id": 6}], "state": 4, "time_on_floor": 85, "next_floor": 6, "floor": 1, "y": 1, "speed": 0.01557632741922111, "type": "FIRST_PLAYER", "id": 1}, {"passengers": [], "state": 3, "time_on_floor": 85, "next_floor": 1, "floor": 1, "y": 1, "speed": 0.02, "type": "FIRST_PLAYER", "id": 2}, {"passengers": [], "state": 3, "time_on_floor": 85, "next_floor": 1, "floor": 1, "y": 1, "speed": 0.02, "type": "FIRST_PLAYER", "id": 3}, {"passengers": [], "state": 3, "time_on_floor": 85, "next_floor": 1, "floor": 1, "y": 1, "speed": 0.02, "type": "FIRST_PLAYER", "id": 4}]} diff --git a/clients/elixir_client/priv/to_cli.py b/clients/elixir_client/priv/to_cli.py new file mode 100644 index 0000000..d1d63d1 --- /dev/null +++ b/clients/elixir_client/priv/to_cli.py @@ -0,0 +1,3 @@ +import json +js = {u'my_elevators': [{u'passengers': [{u'dest_floor': 6, u'floor': 1, u'time_to_away': 418, u'from_floor': 1, u'elevator': 1, u'state': 5, u'y': 1, u'x': 60, u'type': u'FIRST_PLAYER', u'id': 1}, {u'dest_floor': 2, u'floor': 1, u'time_to_away': 438, u'from_floor': 1, u'elevator': 1, u'state': 5, u'y': 1, u'x': 60, u'type': u'FIRST_PLAYER', u'id': 3}, {u'dest_floor': 3, u'floor': 1, u'time_to_away': 458, u'from_floor': 1, u'elevator': 1, u'state': 5, u'y': 1, u'x': 60, u'type': u'FIRST_PLAYER', u'id': 5}], u'time_on_floor': 85, u'floor': 1, u'type': u'SECOND_PLAYER', u'state': 4, u'next_floor': 6, u'y': 1, u'speed': 0.01557632741922111, u'id': 1}, {u'passengers': [], u'time_on_floor': 85, u'floor': 1, u'type': u'SECOND_PLAYER', u'state': 3, u'next_floor': 1, u'y': 1, u'speed': 0.02, u'id': 2}, {u'passengers': [], u'time_on_floor': 85, u'floor': 1, u'type': u'SECOND_PLAYER', u'state': 3, u'next_floor': 1, u'y': 1, u'speed': 0.02, u'id': 3}, {u'passengers': [], u'time_on_floor': 85, u'floor': 1, u'type': u'SECOND_PLAYER', u'state': 3, u'next_floor': 1, u'y': 1, u'speed': 0.02, u'id': 4}], u'my_passengers': [{u'dest_floor': 6, u'floor': 1, u'time_to_away': 418, u'from_floor': 1, u'elevator': 1, u'state': 5, u'y': 1, u'x': -60, u'type': u'SECOND_PLAYER', u'id': 2}, {u'dest_floor': 2, u'floor': 1, u'time_to_away': 438, u'from_floor': 1, u'elevator': 1, u'state': 5, u'y': 1, u'x': -60, u'type': u'SECOND_PLAYER', u'id': 4}, {u'dest_floor': 3, u'floor': 1, u'time_to_away': 458, u'from_floor': 1, u'elevator': 1, u'state': 5, u'y': 1, u'x': -60, u'type': u'SECOND_PLAYER', u'id': 6}, {u'dest_floor': 5, u'floor': 1, u'time_to_away': 475, u'from_floor': 1, u'elevator': None, u'state': 3, u'y': 1, u'x': -18, u'type': u'SECOND_PLAYER', u'id': 8}, {u'dest_floor': 7, u'floor': 1, u'time_to_away': 495, u'from_floor': 1, u'elevator': 2, u'state': 2, u'y': 1, u'x': 20, u'type': u'SECOND_PLAYER', u'id': 10}], u'enemy_passengers': [{u'dest_floor': 6, u'floor': 1, u'time_to_away': 418, u'from_floor': 1, u'elevator': 1, u'state': 5, u'y': 1, u'x': 60, u'type': u'FIRST_PLAYER', u'id': 1}, {u'dest_floor': 2, u'floor': 1, u'time_to_away': 438, u'from_floor': 1, u'elevator': 1, u'state': 5, u'y': 1, u'x': 60, u'type': u'FIRST_PLAYER', u'id': 3}, {u'dest_floor': 3, u'floor': 1, u'time_to_away': 458, u'from_floor': 1, u'elevator': 1, u'state': 5, u'y': 1, u'x': 60, u'type': u'FIRST_PLAYER', u'id': 5}, {u'dest_floor': 5, u'floor': 1, u'time_to_away': 475, u'from_floor': 1, u'elevator': None, u'state': 3, u'y': 1, u'x': 18, u'type': u'FIRST_PLAYER', u'id': 7}, {u'dest_floor': 7, u'floor': 1, u'time_to_away': 495, u'from_floor': 1, u'elevator': 2, u'state': 2, u'y': 1, u'x': -20, u'type': u'FIRST_PLAYER', u'id': 9}], u'enemy_elevators': [{u'passengers': [{u'dest_floor': 6, u'floor': 1, u'time_to_away': 418, u'from_floor': 1, u'elevator': 1, u'state': 5, u'y': 1, u'x': -60, u'type': u'SECOND_PLAYER', u'id': 2}, {u'dest_floor': 2, u'floor': 1, u'time_to_away': 438, u'from_floor': 1, u'elevator': 1, u'state': 5, u'y': 1, u'x': -60, u'type': u'SECOND_PLAYER', u'id': 4}, {u'dest_floor': 3, u'floor': 1, u'time_to_away': 458, u'from_floor': 1, u'elevator': 1, u'state': 5, u'y': 1, u'x': -60, u'type': u'SECOND_PLAYER', u'id': 6}], u'time_on_floor': 85, u'floor': 1, u'type': u'FIRST_PLAYER', u'state': 4, u'next_floor': 6, u'y': 1, u'speed': 0.01557632741922111, u'id': 1}, {u'passengers': [], u'time_on_floor': 85, u'floor': 1, u'type': u'FIRST_PLAYER', u'state': 3, u'next_floor': 1, u'y': 1, u'speed': 0.02, u'id': 2}, {u'passengers': [], u'time_on_floor': 85, u'floor': 1, u'type': u'FIRST_PLAYER', u'state': 3, u'next_floor': 1, u'y': 1, u'speed': 0.02, u'id': 3}, {u'passengers': [], u'time_on_floor': 85, u'floor': 1, u'type': u'FIRST_PLAYER', u'state': 3, u'next_floor': 1, u'y': 1, u'speed': 0.02, u'id': 4}]} +print json.dumps(js) diff --git a/clients/elixir_client/priv/to_cli.txt b/clients/elixir_client/priv/to_cli.txt new file mode 100644 index 0000000..7ce50db --- /dev/null +++ b/clients/elixir_client/priv/to_cli.txt @@ -0,0 +1 @@ +{u'my_elevators': [{u'passengers': [{u'dest_floor': 6, u'floor': 1, u'time_to_away': 418, u'from_floor': 1, u'elevator': 1, u'state': 5, u'y': 1, u'x': 60, u'type': u'FIRST_PLAYER', u'id': 1}, {u'dest_floor': 2, u'floor': 1, u'time_to_away': 438, u'from_floor': 1, u'elevator': 1, u'state': 5, u'y': 1, u'x': 60, u'type': u'FIRST_PLAYER', u'id': 3}, {u'dest_floor': 3, u'floor': 1, u'time_to_away': 458, u'from_floor': 1, u'elevator': 1, u'state': 5, u'y': 1, u'x': 60, u'type': u'FIRST_PLAYER', u'id': 5}], u'time_on_floor': 85, u'floor': 1, u'type': u'SECOND_PLAYER', u'state': 4, u'next_floor': 6, u'y': 1, u'speed': 0.01557632741922111, u'id': 1}, {u'passengers': [], u'time_on_floor': 85, u'floor': 1, u'type': u'SECOND_PLAYER', u'state': 3, u'next_floor': 1, u'y': 1, u'speed': 0.02, u'id': 2}, {u'passengers': [], u'time_on_floor': 85, u'floor': 1, u'type': u'SECOND_PLAYER', u'state': 3, u'next_floor': 1, u'y': 1, u'speed': 0.02, u'id': 3}, {u'passengers': [], u'time_on_floor': 85, u'floor': 1, u'type': u'SECOND_PLAYER', u'state': 3, u'next_floor': 1, u'y': 1, u'speed': 0.02, u'id': 4}], u'my_passengers': [{u'dest_floor': 6, u'floor': 1, u'time_to_away': 418, u'from_floor': 1, u'elevator': 1, u'state': 5, u'y': 1, u'x': -60, u'type': u'SECOND_PLAYER', u'id': 2}, {u'dest_floor': 2, u'floor': 1, u'time_to_away': 438, u'from_floor': 1, u'elevator': 1, u'state': 5, u'y': 1, u'x': -60, u'type': u'SECOND_PLAYER', u'id': 4}, {u'dest_floor': 3, u'floor': 1, u'time_to_away': 458, u'from_floor': 1, u'elevator': 1, u'state': 5, u'y': 1, u'x': -60, u'type': u'SECOND_PLAYER', u'id': 6}, {u'dest_floor': 5, u'floor': 1, u'time_to_away': 475, u'from_floor': 1, u'elevator': None, u'state': 3, u'y': 1, u'x': -18, u'type': u'SECOND_PLAYER', u'id': 8}, {u'dest_floor': 7, u'floor': 1, u'time_to_away': 495, u'from_floor': 1, u'elevator': 2, u'state': 2, u'y': 1, u'x': 20, u'type': u'SECOND_PLAYER', u'id': 10}], u'enemy_passengers': [{u'dest_floor': 6, u'floor': 1, u'time_to_away': 418, u'from_floor': 1, u'elevator': 1, u'state': 5, u'y': 1, u'x': 60, u'type': u'FIRST_PLAYER', u'id': 1}, {u'dest_floor': 2, u'floor': 1, u'time_to_away': 438, u'from_floor': 1, u'elevator': 1, u'state': 5, u'y': 1, u'x': 60, u'type': u'FIRST_PLAYER', u'id': 3}, {u'dest_floor': 3, u'floor': 1, u'time_to_away': 458, u'from_floor': 1, u'elevator': 1, u'state': 5, u'y': 1, u'x': 60, u'type': u'FIRST_PLAYER', u'id': 5}, {u'dest_floor': 5, u'floor': 1, u'time_to_away': 475, u'from_floor': 1, u'elevator': None, u'state': 3, u'y': 1, u'x': 18, u'type': u'FIRST_PLAYER', u'id': 7}, {u'dest_floor': 7, u'floor': 1, u'time_to_away': 495, u'from_floor': 1, u'elevator': 2, u'state': 2, u'y': 1, u'x': -20, u'type': u'FIRST_PLAYER', u'id': 9}], u'enemy_elevators': [{u'passengers': [{u'dest_floor': 6, u'floor': 1, u'time_to_away': 418, u'from_floor': 1, u'elevator': 1, u'state': 5, u'y': 1, u'x': -60, u'type': u'SECOND_PLAYER', u'id': 2}, {u'dest_floor': 2, u'floor': 1, u'time_to_away': 438, u'from_floor': 1, u'elevator': 1, u'state': 5, u'y': 1, u'x': -60, u'type': u'SECOND_PLAYER', u'id': 4}, {u'dest_floor': 3, u'floor': 1, u'time_to_away': 458, u'from_floor': 1, u'elevator': 1, u'state': 5, u'y': 1, u'x': -60, u'type': u'SECOND_PLAYER', u'id': 6}], u'time_on_floor': 85, u'floor': 1, u'type': u'FIRST_PLAYER', u'state': 4, u'next_floor': 6, u'y': 1, u'speed': 0.01557632741922111, u'id': 1}, {u'passengers': [], u'time_on_floor': 85, u'floor': 1, u'type': u'FIRST_PLAYER', u'state': 3, u'next_floor': 1, u'y': 1, u'speed': 0.02, u'id': 2}, {u'passengers': [], u'time_on_floor': 85, u'floor': 1, u'type': u'FIRST_PLAYER', u'state': 3, u'next_floor': 1, u'y': 1, u'speed': 0.02, u'id': 3}, {u'passengers': [], u'time_on_floor': 85, u'floor': 1, u'type': u'FIRST_PLAYER', u'state': 3, u'next_floor': 1, u'y': 1, u'speed': 0.02, u'id': 4}]} diff --git a/clients/elixir_client/priv/tst.py b/clients/elixir_client/priv/tst.py new file mode 100644 index 0000000..fb20a30 --- /dev/null +++ b/clients/elixir_client/priv/tst.py @@ -0,0 +1,3 @@ +import json +js = {u'123': 418} +print json.dumps(js) \ No newline at end of file diff --git a/clients/elixir_client/test/elixir_client_test.exs b/clients/elixir_client/test/elixir_client_test.exs new file mode 100644 index 0000000..fd887f7 --- /dev/null +++ b/clients/elixir_client/test/elixir_client_test.exs @@ -0,0 +1,103 @@ +defmodule ElixirClient.Test do + use ExUnit.Case + + test "elevator_json" do + elevator_map = Poison.decode!(elevator_json()) + + elevator = Elevator.new(elevator_map) + + # IO.puts "elevator_json=#{inspect elevator_json}" + # IO.puts "elevator_map=#{inspect elevator_map}" + # IO.puts "elevator=#{inspect elevator}" + end + + test "passenger_json" do + passenger_map = Poison.decode!(passenger_json()) + + passenger = Passenger.new(passenger_map) + + # IO.puts "passenger_json=#{inspect passenger_json}" + # IO.puts "passenger_map=#{inspect passenger_map}" + # IO.puts "passenger=#{inspect passenger}" + end + + test "passengers" do + pj = passenger_json() + passengers_json = "[#{pj},#{pj}]" + passengers_array = Poison.decode!(passengers_json) + passengers = passengers_array + |> Enum.map(&Passenger.new(&1)) + + # IO.puts "passengers_json=#{inspect passengers_json}" + # IO.puts "passengers_array=#{inspect passengers_array}" + # IO.puts "passengers=#{inspect passengers}" + end + + test "to_client" do + {:ok, to_cli_json} = File.read("./priv/to_cli.json") + + # далее - такой же код, как будет в приеме данных от сервера + json_actions = Poison.decode!(to_cli_json) + + my_elevators = ElixirClient.Api.parse_elevators(json_actions["my_elevators"]) + my_passengers = ElixirClient.Api.parse_passengers(json_actions["my_passengers"]) + enemy_elevators = ElixirClient.Api.parse_elevators(json_actions["enemy_elevators"]) + enemy_passengers = ElixirClient.Api.parse_passengers(json_actions["enemy_passengers"]) + + array_actions = Strategy.on_tick(my_elevators, my_passengers, enemy_elevators, enemy_passengers) + + commands = ElixirClient.Api.get_state() + IO.puts "commands = #{inspect commands}" + + + # IO.puts "my_elevators = #{inspect my_elevators}" + # IO.puts "enemy_elevators = #{inspect enemy_elevators}" + # IO.puts "my_passengers = #{inspect my_passengers}" + # IO.puts "enemy_passengers = #{inspect enemy_passengers}" + + # IO.puts "array_actions = #{inspect array_actions}" + + end + + test "from_client" do + {:ok, from_cli_json} = File.read("./priv/from_cli.json") + json_actions = Poison.decode!(from_cli_json) + # IO.puts "from_cli_json = #{inspect from_cli_json}" + IO.puts "json_actions = #{inspect json_actions}" + end + + defp elevator_json() do + """ + { + \"id\":1, + \"y\":2, + \"passengers\":3, + \"state\":4, + \"speed\":5, + \"floor\":6, + \"next_floor\":7, + \"time_on_floor\":8, + \"type\":9 + } + + """ + end + + defp passenger_json() do + """ + { + \"id\":1, + \"elevator\":2, + \"x\":3, + \"y\":4, + \"state\":5, + \"time_to_away\":6, + \"from_floor\":7, + \"dest_floor\":8, + \"type\":9, + \"floor\":10 + } + """ + end + +end diff --git a/clients/elixir_client/test/test_helper.exs b/clients/elixir_client/test/test_helper.exs new file mode 100644 index 0000000..869559e --- /dev/null +++ b/clients/elixir_client/test/test_helper.exs @@ -0,0 +1 @@ +ExUnit.start()