AI TCP Server
This commit is contained in:
@@ -0,0 +1,71 @@
|
||||
# AI TCP API
|
||||
|
||||
The AI handler listens on `127.0.0.1:8765` by default. Set `AI_HOST`,
|
||||
`AI_PORT`, or `AI_MAX_WORKERS` to change the server configuration. Messages
|
||||
are UTF-8 JSON objects separated by newlines. The connection stays open for
|
||||
multiple requests.
|
||||
|
||||
## Ping
|
||||
|
||||
Request: `{"type":"ping"}`
|
||||
|
||||
Response: `{"ok":true,"type":"pong"}`
|
||||
|
||||
## Start a simulation
|
||||
|
||||
The server chooses the map. For the first training simulation it selects the
|
||||
map closest to difficulty 0. After a simulation finishes, the server computes
|
||||
each model's score from coins, progress toward the finish, and whether it won.
|
||||
The best score becomes the next training difficulty. Validation requests ignore
|
||||
the training score and randomly select a map with difficulty at least 70, or
|
||||
any map when no such map exists.
|
||||
|
||||
The score is from 0 to 100:
|
||||
|
||||
`40 * coin_progress + 40 * distance_progress + 20 * won`
|
||||
|
||||
where `coin_progress` is collected coins divided by the map's total coins,
|
||||
`distance_progress` is progress from the spawn point to the finish, and `won`
|
||||
is 1 when the finish was reached and 0 when the model stopped elsewhere,
|
||||
including on spikes.
|
||||
|
||||
Send one model entry per model. The model entries contain only an ID; moves
|
||||
are requested separately on every turn.
|
||||
|
||||
```json
|
||||
{"type":"simulate","validation":false,"models":[{"id":"model-a"},{"id":"model-b"}]}
|
||||
```
|
||||
|
||||
Every model gets a separate `Game` instance and can run in parallel. Valid
|
||||
requests. Valid moves are `left_down`, `left`, `left_up`, `up`, `right_up`,
|
||||
`right`, and `right_down`. Send `null` for a model when it has no more moves;
|
||||
that model is stopped for the current generation.
|
||||
|
||||
The response identifies the selected map and returns the initial state:
|
||||
|
||||
```json
|
||||
{
|
||||
"ok":true,
|
||||
"type":"move_request",
|
||||
"map":{"name":"default","difficulty":30.0,"layout":[["stone", "stone"]]},
|
||||
"results":{"model-a":{"won":false,"coins":0,"moves":0,"position":[1,4],"finished":false},"model-b":{"won":false,"coins":0,"moves":0,"position":[1,4],"finished":false}}
|
||||
}
|
||||
```
|
||||
|
||||
## Advance one turn
|
||||
|
||||
The client must send exactly one move for every model on each turn. The server
|
||||
advances all model simulations in parallel and replies before the client must
|
||||
predict the next moves.
|
||||
|
||||
```json
|
||||
{"type":"step","moves":{"model-a":"right","model-b":null}}
|
||||
```
|
||||
|
||||
The response is `move_request` with the selected map and updated per-model states, asking the
|
||||
client for the next move of every model. When every model has finished, the
|
||||
response type becomes `simulation_result` and includes the best model's
|
||||
server-computed `score`, which is used to choose the next training map.
|
||||
|
||||
The result score is `1000` for a win, plus `10` per coin, minus the number of
|
||||
moves. Malformed requests receive `{"ok":false,"error":"..."}`.
|
||||
Reference in New Issue
Block a user