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