add web-service

This commit is contained in:
2025-10-20 23:07:10 +05:00
parent a74b8bbb5d
commit 4f9417a032
10 changed files with 1266 additions and 282 deletions

283
API-DOCUMENTATION.md Normal file
View 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`
- Проверьте, что все чекпоинты достижимы
- Упростите карту (уберите препятствия, лёд, снег)
### Медленная работа
- Уменьшите количество чекпоинтов
- Уменьшите размер карты
- Оптимизируйте расположение чекпоинтов (по порядку)