284 lines
7.2 KiB
Markdown
284 lines
7.2 KiB
Markdown
# Racing A* Solver - API Documentation
|
||
|
||
Микросервис для решения задачи "Гонки на бумаге" с использованием алгоритма A*.
|
||
|
||
## Запуск сервиса
|
||
|
||
```bash
|
||
# Сборка и запуск
|
||
./run-webservice.sh
|
||
|
||
# Или напрямую через dotnet
|
||
dotnet run --project racing-webservice.csproj
|
||
|
||
# Запуск на другом порту
|
||
PORT=8080 dotnet run --project racing-webservice.csproj
|
||
```
|
||
|
||
По умолчанию сервис запускается на `http://localhost:5000`
|
||
|
||
## API Endpoints
|
||
|
||
### 1. GET / - Информация об API
|
||
|
||
Возвращает информацию о сервисе и доступных endpoints.
|
||
|
||
**Request:**
|
||
```bash
|
||
curl http://localhost:5000/
|
||
```
|
||
|
||
**Response:**
|
||
```json
|
||
{
|
||
"service": "Paper Racing A* Solver",
|
||
"version": "1.0.0",
|
||
"endpoints": {
|
||
"health": "GET /health",
|
||
"solve": "POST /solve",
|
||
"info": "GET /"
|
||
},
|
||
"documentation": "POST /solve with JSON body containing 'map' field (2D array of integers)"
|
||
}
|
||
```
|
||
|
||
### 2. GET /health - Health Check
|
||
|
||
Проверка работоспособности сервиса.
|
||
|
||
**Request:**
|
||
```bash
|
||
curl http://localhost:5000/health
|
||
```
|
||
|
||
**Response:**
|
||
```json
|
||
{
|
||
"status": "healthy",
|
||
"version": "1.0.0",
|
||
"timestamp": "2025-10-20T12:00:00Z"
|
||
}
|
||
```
|
||
|
||
### 3. POST /solve - Решение задачи
|
||
|
||
Основной endpoint для решения карты гонок.
|
||
|
||
**Request:**
|
||
```bash
|
||
curl -X POST http://localhost:5000/solve \
|
||
-H "Content-Type: application/json" \
|
||
-d @maps/simple-test.json
|
||
```
|
||
|
||
**Request Body:**
|
||
```json
|
||
{
|
||
"map": [
|
||
[0, 0, 0, 0, 0],
|
||
[0, 1, 1, 1, 0],
|
||
[0, 0, 4, 0, 0],
|
||
[0, 1, 1, 1, 0],
|
||
[5, 0, 0, 0, 0]
|
||
],
|
||
"maxIterations": 5000000,
|
||
"timeoutSeconds": 60
|
||
}
|
||
```
|
||
|
||
**Формат карты:**
|
||
- `0` - дорога (первая ячейка дороги - старт по умолчанию)
|
||
- `1` - препятствие (камень)
|
||
- `2` - снег (ограниченное ускорение ±1)
|
||
- `3` - лёд (нельзя менять ускорение)
|
||
- `4` - чекпоинт (нужно посетить все)
|
||
- `5` - старт (приоритетная стартовая позиция)
|
||
|
||
**Response (успех):**
|
||
```json
|
||
{
|
||
"success": true,
|
||
"solution": [
|
||
[0, 0],
|
||
[1, 1],
|
||
[1, 0],
|
||
[0, -1],
|
||
...
|
||
],
|
||
"statistics": {
|
||
"steps": 15,
|
||
"checkpoints": 1,
|
||
"iterations": 1234,
|
||
"computeTimeSeconds": 0.52,
|
||
"maxSpeed": 6
|
||
}
|
||
}
|
||
```
|
||
|
||
**Response (ошибка):**
|
||
```json
|
||
{
|
||
"success": false,
|
||
"error": "No solution found within the iteration limit",
|
||
"solution": null,
|
||
"statistics": null
|
||
}
|
||
```
|
||
|
||
**Формат решения:**
|
||
Массив ускорений `[ax, ay]` для каждого шага:
|
||
- `ax` - ускорение по оси X
|
||
- `ay` - ускорение по оси Y (инвертировано для JSON формата)
|
||
|
||
## Примеры использования
|
||
|
||
### Python
|
||
|
||
```python
|
||
import requests
|
||
import json
|
||
|
||
# Загружаем карту
|
||
with open('maps/simple-test.json', 'r') as f:
|
||
map_data = json.load(f)
|
||
|
||
# Отправляем запрос
|
||
response = requests.post(
|
||
'http://localhost:5000/solve',
|
||
json=map_data
|
||
)
|
||
|
||
result = response.json()
|
||
|
||
if result['success']:
|
||
print(f"✓ Решение найдено!")
|
||
print(f" Шагов: {result['statistics']['steps']}")
|
||
print(f" Время: {result['statistics']['computeTimeSeconds']:.2f}s")
|
||
|
||
# Сохраняем решение
|
||
with open('solution.json', 'w') as f:
|
||
json.dump({'solution': result['solution']}, f, indent=2)
|
||
else:
|
||
print(f"✗ Ошибка: {result['error']}")
|
||
```
|
||
|
||
### JavaScript/Node.js
|
||
|
||
```javascript
|
||
const fs = require('fs');
|
||
const fetch = require('node-fetch');
|
||
|
||
async function solveMap(mapFile) {
|
||
// Читаем карту
|
||
const mapData = JSON.parse(fs.readFileSync(mapFile, 'utf8'));
|
||
|
||
// Отправляем запрос
|
||
const response = await fetch('http://localhost:5000/solve', {
|
||
method: 'POST',
|
||
headers: { 'Content-Type': 'application/json' },
|
||
body: JSON.stringify(mapData)
|
||
});
|
||
|
||
const result = await response.json();
|
||
|
||
if (result.success) {
|
||
console.log('✓ Решение найдено!');
|
||
console.log(` Шагов: ${result.statistics.steps}`);
|
||
console.log(` Время: ${result.statistics.computeTimeSeconds.toFixed(2)}s`);
|
||
|
||
// Сохраняем решение
|
||
fs.writeFileSync('solution.json',
|
||
JSON.stringify({ solution: result.solution }, null, 2));
|
||
} else {
|
||
console.log(`✗ Ошибка: ${result.error}`);
|
||
}
|
||
}
|
||
|
||
solveMap('maps/simple-test.json');
|
||
```
|
||
|
||
### cURL
|
||
|
||
```bash
|
||
# Решить простую карту
|
||
curl -X POST http://localhost:5000/solve \
|
||
-H "Content-Type: application/json" \
|
||
-d @maps/simple-test.json \
|
||
| jq '.'
|
||
|
||
# Решить карту с кастомными параметрами
|
||
curl -X POST http://localhost:5000/solve \
|
||
-H "Content-Type: application/json" \
|
||
-d '{
|
||
"map": [[0,4,0],[5,0,0],[0,0,0]],
|
||
"maxIterations": 1000000
|
||
}' \
|
||
| jq '.'
|
||
|
||
# Сохранить решение в файл
|
||
curl -X POST http://localhost:5000/solve \
|
||
-H "Content-Type: application/json" \
|
||
-d @maps/racing-map-15x15.json \
|
||
| jq '.solution | {solution: .}' > solution.json
|
||
```
|
||
|
||
## Docker Support (опционально)
|
||
|
||
Создайте `Dockerfile`:
|
||
|
||
```dockerfile
|
||
FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
|
||
WORKDIR /app
|
||
COPY . .
|
||
RUN dotnet publish racing-webservice.csproj -c Release -o out
|
||
|
||
FROM mcr.microsoft.com/dotnet/aspnet:8.0
|
||
WORKDIR /app
|
||
COPY --from=build /app/out .
|
||
ENV PORT=5000
|
||
EXPOSE 5000
|
||
ENTRYPOINT ["dotnet", "racing-webservice.dll"]
|
||
```
|
||
|
||
Запуск в Docker:
|
||
```bash
|
||
docker build -t racing-solver .
|
||
docker run -p 5000:5000 racing-solver
|
||
```
|
||
|
||
## Производительность
|
||
|
||
- Простые карты (до 5 чекпоинтов): < 1 секунда
|
||
- Средние карты (5-15 чекпоинтов): 1-10 секунд
|
||
- Сложные карты (15+ чекпоинтов): 10-120 секунд
|
||
|
||
Рекомендуется устанавливать `maxIterations` в зависимости от сложности карты.
|
||
|
||
## Ограничения
|
||
|
||
- Максимальный размер карты: 200x200 (ограничено памятью)
|
||
- Максимальное количество чекпоинтов: ~100 (зависит от сложности)
|
||
- Максимальное время выполнения: зависит от параметра `maxIterations`
|
||
|
||
## Устранение неполадок
|
||
|
||
### Сервис не запускается
|
||
```bash
|
||
# Проверьте, свободен ли порт
|
||
netstat -tuln | grep 5000
|
||
|
||
# Используйте другой порт
|
||
PORT=8080 ./run-webservice.sh
|
||
```
|
||
|
||
### Решение не найдено
|
||
- Увеличьте `maxIterations`
|
||
- Проверьте, что все чекпоинты достижимы
|
||
- Упростите карту (уберите препятствия, лёд, снег)
|
||
|
||
### Медленная работа
|
||
- Уменьшите количество чекпоинтов
|
||
- Уменьшите размер карты
|
||
- Оптимизируйте расположение чекпоинтов (по порядку)
|
||
|