On main: temporary stash before history cleanup
This commit is contained in:
@@ -276,7 +276,7 @@ namespace PaperRacing.WebService
|
|||||||
// Запускаем сервер
|
// Запускаем сервер
|
||||||
var port = Environment.GetEnvironmentVariable("PORT") ?? "5000";
|
var port = Environment.GetEnvironmentVariable("PORT") ?? "5000";
|
||||||
Console.WriteLine("╔════════════════════════════════════════════════════════════╗");
|
Console.WriteLine("╔════════════════════════════════════════════════════════════╗");
|
||||||
Console.WriteLine("║ Paper Racing A* Solver - Web Service ║");
|
Console.WriteLine("║ Paper Racing A* Solver - Web Service ║");
|
||||||
Console.WriteLine("╚════════════════════════════════════════════════════════════╝");
|
Console.WriteLine("╚════════════════════════════════════════════════════════════╝");
|
||||||
Console.WriteLine($"\n🚀 Server starting on http://localhost:{port}");
|
Console.WriteLine($"\n🚀 Server starting on http://localhost:{port}");
|
||||||
Console.WriteLine($"\nEndpoints:");
|
Console.WriteLine($"\nEndpoints:");
|
||||||
|
|||||||
@@ -1,10 +1,11 @@
|
|||||||
# Результаты тестирования A* алгоритма с новыми правилами
|
# Результаты тестирования A* алгоритма
|
||||||
|
|
||||||
## Новые правила
|
## Правила
|
||||||
1. **Препятствия**: Можно проезжать через камни, но нельзя на них останавливаться
|
1. **Обычная дорога (0)**: Ускорение от -2 до +2
|
||||||
2. **Снег (тип 2)**: Ускорение ограничено диапазоном от -1 до +1
|
2. **Препятствия (1)**: Можно проезжать через камни, но нельзя на них останавливаться
|
||||||
3. **Лёд (тип 3)**: Ускорение нельзя менять (только сохранение текущей скорости)
|
3. **Снег (2)**: Ускорение ограничено диапазоном от -1 до +1
|
||||||
4. **Обычная дорога (тип 0)**: Ускорение от -2 до +2
|
4. **Лёд (3)**: Ускорение нельзя менять (только сохранение текущей скорости)
|
||||||
|
5. **Чекпоинт (4)**: Ускорение от -2 до +2
|
||||||
|
|
||||||
## Тестовые карты
|
## Тестовые карты
|
||||||
|
|
||||||
|
|||||||
@@ -292,3 +292,5 @@ racing-tools/
|
|||||||
**Лицензия:** MIT
|
**Лицензия:** MIT
|
||||||
**Автор:** Racing Team
|
**Автор:** Racing Team
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -41,3 +41,5 @@ echo " • Нарисуйте карту, обязательно добавьт
|
|||||||
echo " • Экспортируйте в JSON для использования в решателе"
|
echo " • Экспортируйте в JSON для использования в решателе"
|
||||||
echo " • Для визуализации решений откройте ./open-player.sh"
|
echo " • Для визуализации решений откройте ./open-player.sh"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -42,3 +42,5 @@ echo " • Затем загрузите решение (🎬 Загрузит
|
|||||||
echo " • Используйте кнопки управления для анимации"
|
echo " • Используйте кнопки управления для анимации"
|
||||||
echo " • Демо-файлы: demo-with-start.json и demo-with-start-solution.json"
|
echo " • Демо-файлы: demo-with-start.json и demo-with-start-solution.json"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -25,10 +25,12 @@
|
|||||||
<h3>📂 Загрузка файлов</h3>
|
<h3>📂 Загрузка файлов</h3>
|
||||||
<div class="buttons">
|
<div class="buttons">
|
||||||
<button class="btn-primary" id="loadMapBtn" onclick="document.getElementById('mapInput').click()">📂 Загрузить карту</button>
|
<button class="btn-primary" id="loadMapBtn" onclick="document.getElementById('mapInput').click()">📂 Загрузить карту</button>
|
||||||
|
<button class="btn-primary" id="solveBtn" onclick="solveMap()" disabled>🧠 Найти решение</button>
|
||||||
<button class="btn-success" id="loadSolutionBtn" onclick="document.getElementById('solutionInput').click()">🎬 Загрузить решение</button>
|
<button class="btn-success" id="loadSolutionBtn" onclick="document.getElementById('solutionInput').click()">🎬 Загрузить решение</button>
|
||||||
</div>
|
</div>
|
||||||
<input type="file" id="mapInput" accept=".json" onchange="loadMap(event)">
|
<input type="file" id="mapInput" accept=".json" onchange="loadMap(event)">
|
||||||
<input type="file" id="solutionInput" accept=".json" onchange="loadSolution(event)">
|
<input type="file" id="solutionInput" accept=".json" onchange="loadSolution(event)">
|
||||||
|
<div id="solverStatus" class="solver-status"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="playbackControls" class="visualization-panel">
|
<div id="playbackControls" class="visualization-panel">
|
||||||
|
|||||||
@@ -287,6 +287,9 @@ function loadMap(event) {
|
|||||||
resizeCanvas();
|
resizeCanvas();
|
||||||
drawMap();
|
drawMap();
|
||||||
|
|
||||||
|
// Включаем кнопку "Найти решение" после загрузки карты
|
||||||
|
document.getElementById('solveBtn').disabled = false;
|
||||||
|
|
||||||
document.getElementById('loadMapBtn').textContent = '✓ Карта загружена';
|
document.getElementById('loadMapBtn').textContent = '✓ Карта загружена';
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
document.getElementById('loadMapBtn').textContent = '📂 Загрузить карту';
|
document.getElementById('loadMapBtn').textContent = '📂 Загрузить карту';
|
||||||
@@ -505,6 +508,125 @@ function clearVisualization() {
|
|||||||
drawMap();
|
drawMap();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Решение карты через API
|
||||||
|
async function solveMap() {
|
||||||
|
const solveBtn = document.getElementById('solveBtn');
|
||||||
|
const statusDiv = document.getElementById('solverStatus');
|
||||||
|
|
||||||
|
// Проверяем, что карта загружена
|
||||||
|
if (!map || map.length === 0) {
|
||||||
|
alert('⚠️ Сначала загрузите карту!');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Находим стартовую позицию
|
||||||
|
startPosition = findStartPosition(map, width, height);
|
||||||
|
if (!startPosition) {
|
||||||
|
alert('⚠️ На карте не найдена точка старта (тип 5)!');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Проверяем наличие чекпоинтов
|
||||||
|
let hasCheckpoint = false;
|
||||||
|
for (let y = 0; y < height; y++) {
|
||||||
|
for (let x = 0; x < width; x++) {
|
||||||
|
if (map[y][x] === 4) {
|
||||||
|
hasCheckpoint = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (hasCheckpoint) break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!hasCheckpoint) {
|
||||||
|
alert('⚠️ На карте нет чекпоинтов (тип 4)!');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Отключаем кнопку и показываем статус
|
||||||
|
solveBtn.disabled = true;
|
||||||
|
solveBtn.textContent = '⏳ Поиск решения...';
|
||||||
|
statusDiv.innerHTML = '<div style="color: #ff9800;">⏳ Отправка запроса на сервер...</div>';
|
||||||
|
|
||||||
|
try {
|
||||||
|
const requestData = {
|
||||||
|
map: map,
|
||||||
|
maxIterations: 5000000
|
||||||
|
};
|
||||||
|
|
||||||
|
const response = await fetch('http://localhost:5000/solve', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json'
|
||||||
|
},
|
||||||
|
body: JSON.stringify(requestData)
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error(`HTTP error! status: ${response.status}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
const result = await response.json();
|
||||||
|
|
||||||
|
if (result.success) {
|
||||||
|
// Успешно найдено решение
|
||||||
|
const stats = result.statistics;
|
||||||
|
statusDiv.innerHTML = `
|
||||||
|
<div style="color: #4caf50; font-weight: bold;">✅ Решение найдено!</div>
|
||||||
|
<div style="font-size: 12px; margin-top: 5px;">
|
||||||
|
📊 Шагов: ${stats.steps}<br>
|
||||||
|
🎯 Чекпоинтов: ${stats.checkpoints}<br>
|
||||||
|
⚡ Макс. скорость: ${stats.maxSpeed}<br>
|
||||||
|
⏱️ Время: ${stats.computeTimeSeconds.toFixed(2)}s
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
|
||||||
|
// Загружаем решение напрямую
|
||||||
|
solution = result.solution;
|
||||||
|
trajectory = simulateTrajectory(solution, startPosition);
|
||||||
|
currentStep = 0;
|
||||||
|
|
||||||
|
// Обновляем состояние кнопок и информацию
|
||||||
|
updateControlsState();
|
||||||
|
updateStepInfo();
|
||||||
|
drawMap();
|
||||||
|
|
||||||
|
// Автоматически начинаем воспроизведение
|
||||||
|
setTimeout(() => {
|
||||||
|
playVisualization();
|
||||||
|
}, 500);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// Решение не найдено
|
||||||
|
statusDiv.innerHTML = `
|
||||||
|
<div style="color: #f44336; font-weight: bold;">❌ Решение не найдено</div>
|
||||||
|
<div style="font-size: 12px; margin-top: 5px;">${result.error || 'Неизвестная ошибка'}</div>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Ошибка при решении карты:', error);
|
||||||
|
|
||||||
|
if (error.message.includes('Failed to fetch') || error.message.includes('NetworkError')) {
|
||||||
|
statusDiv.innerHTML = `
|
||||||
|
<div style="color: #f44336; font-weight: bold;">❌ Сервер недоступен</div>
|
||||||
|
<div style="font-size: 12px; margin-top: 5px;">
|
||||||
|
Убедитесь, что сервер запущен:<br>
|
||||||
|
<code style="background: #333; padding: 2px 5px; border-radius: 3px;">./run-webservice.sh</code>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
} else {
|
||||||
|
statusDiv.innerHTML = `
|
||||||
|
<div style="color: #f44336; font-weight: bold;">❌ Ошибка</div>
|
||||||
|
<div style="font-size: 12px; margin-top: 5px;">${error.message}</div>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
// Включаем кнопку обратно
|
||||||
|
solveBtn.disabled = false;
|
||||||
|
solveBtn.textContent = '🧠 Найти решение';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
canvas.addEventListener('mousedown', (e) => {
|
canvas.addEventListener('mousedown', (e) => {
|
||||||
if (e.button === 2 || e.shiftKey) {
|
if (e.button === 2 || e.shiftKey) {
|
||||||
isPanning = true;
|
isPanning = true;
|
||||||
|
|||||||
Reference in New Issue
Block a user