add web-service
This commit is contained in:
283
API-DOCUMENTATION.md
Normal file
283
API-DOCUMENTATION.md
Normal file
@@ -0,0 +1,283 @@
|
||||
# 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`
|
||||
- Проверьте, что все чекпоинты достижимы
|
||||
- Упростите карту (уберите препятствия, лёд, снег)
|
||||
|
||||
### Медленная работа
|
||||
- Уменьшите количество чекпоинтов
|
||||
- Уменьшите размер карты
|
||||
- Оптимизируйте расположение чекпоинтов (по порядку)
|
||||
|
||||
Reference in New Issue
Block a user