7.2 KiB
7.2 KiB
Примеры конфигураций карт
Простая карта (обучение)
int width = 15;
int height = 15;
var start = new Point(1, 1);
var checkpoints = new Dictionary<int, Point>
{
{ 1, new Point(5, 5) },
{ 2, new Point(10, 10) }
};
var obstacles = new HashSet<Point>();
// Простая стена
for (int x = 3; x <= 8; x++)
obstacles.Add(new Point(x, 7));
Ожидаемое время:
- BFS: < 1 сек
- A*: < 0.5 сек
Средняя сложность (лабиринт)
int width = 25;
int height = 25;
var start = new Point(2, 2);
var checkpoints = new Dictionary<int, Point>
{
{ 1, new Point(8, 8) },
{ 2, new Point(20, 20) },
{ 3, new Point(22, 5) }
};
var obstacles = new HashSet<Point>();
// Горизонтальные стены
for (int x = 5; x <= 15; x++)
{
obstacles.Add(new Point(x, 10));
obstacles.Add(new Point(x + 5, 15));
}
// Вертикальные стены
for (int y = 5; y <= 15; y++)
{
obstacles.Add(new Point(12, y));
obstacles.Add(new Point(18, y));
}
// Блок препятствий
for (int x = 8; x <= 10; x++)
for (int y = 3; y <= 5; y++)
obstacles.Add(new Point(x, y));
Ожидаемое время:
- BFS: 5-15 сек
- A*: 1-3 сек
Высокая сложность (большая карта)
int width = 42;
int height = 42;
var start = new Point(2, 2);
var checkpoints = new Dictionary<int, Point>
{
{ 1, new Point(10, 10) },
{ 2, new Point(30, 35) },
{ 3, new Point(38, 8) },
{ 4, new Point(15, 30) },
{ 5, new Point(25, 15) }
};
var obstacles = new HashSet<Point>();
// Спиральный лабиринт
for (int x = 5; x <= 35; x++)
obstacles.Add(new Point(x, 15));
for (int y = 5; y <= 35; y++)
obstacles.Add(new Point(20, y));
for (int x = 10; x <= 30; x++)
obstacles.Add(new Point(x, 25));
// Диагональные стены
for (int i = 0; i <= 15; i++)
{
obstacles.Add(new Point(25 + i, 25 + i));
obstacles.Add(new Point(10 + i, 5 + i));
}
// Комнаты
CreateRoom(obstacles, 35, 18, 3, 3);
CreateRoom(obstacles, 8, 32, 4, 4);
void CreateRoom(HashSet<Point> obs, int startX, int startY, int w, int h)
{
for (int x = startX; x < startX + w; x++)
for (int y = startY; y < startY + h; y++)
obs.Add(new Point(x, y));
}
Ожидаемое время:
- BFS: >30 сек (или не найдет)
- A*: 1-5 сек
Экстремальная сложность (гоночная трасса)
int width = 60;
int height = 60;
var start = new Point(3, 3);
var checkpoints = new Dictionary<int, Point>
{
{ 1, new Point(15, 10) },
{ 2, new Point(45, 15) },
{ 3, new Point(50, 45) },
{ 4, new Point(25, 50) },
{ 5, new Point(10, 35) },
{ 6, new Point(30, 30) }
};
var obstacles = new HashSet<Point>();
// Внешняя граница трассы
for (int i = 5; i <= 55; i++)
{
obstacles.Add(new Point(i, 5));
obstacles.Add(new Point(i, 55));
obstacles.Add(new Point(5, i));
obstacles.Add(new Point(55, i));
}
// Внутренние препятствия - создаем узкие проходы
for (int y = 10; y <= 50; y += 10)
{
for (int x = 10; x <= 45; x++)
{
if (x % 15 < 3) // Оставляем проходы
obstacles.Add(new Point(x, y));
}
}
// S-образные повороты
for (int i = 0; i <= 20; i++)
{
obstacles.Add(new Point(20 + i, 20 + i / 2));
obstacles.Add(new Point(40 - i, 30 + i / 2));
}
Ожидаемое время:
- BFS: Может не найти решение
- A*: 5-20 сек
Тестирование физики (ускорение)
// Длинная прямая дорога - тестирует высокие скорости
int width = 80;
int height = 20;
var start = new Point(2, 10);
var checkpoints = new Dictionary<int, Point>
{
{ 1, new Point(75, 10) }
};
var obstacles = new HashSet<Point>();
// Граничные стены
for (int x = 0; x < width; x++)
{
obstacles.Add(new Point(x, 0));
obstacles.Add(new Point(x, 19));
}
Ожидаемый результат:
- Машина должна разогнаться до максимальной скорости
- Оптимальное решение: ~10-12 ходов
Челлендж: Узкие проходы
int width = 30;
int height = 30;
var start = new Point(2, 2);
var checkpoints = new Dictionary<int, Point>
{
{ 1, new Point(15, 15) },
{ 2, new Point(27, 27) }
};
var obstacles = new HashSet<Point>();
// Создаем зигзагообразный узкий коридор
for (int y = 5; y <= 25; y++)
{
int offset = (y / 5) % 2 == 0 ? 0 : 10;
for (int x = 8 + offset; x <= 20 + offset; x++)
{
if (x < 10 + offset || x > 18 + offset)
obstacles.Add(new Point(x, y));
}
}
Челлендж:
- Требует точного управления скоростью
- Нельзя разгоняться слишком сильно
- Тестирует алгоритм торможения
Как использовать
- Скопируйте нужную конфигурацию
- Замените код в
Mainметод вProgram.csилиProgramAStar.cs - Запустите программу
- Сравните время работы BFS и A*
Генератор случайных карт
public static HashSet<Point> GenerateRandomObstacles(int width, int height, int density)
{
var random = new Random();
var obstacles = new HashSet<Point>();
int totalCells = width * height;
int obstacleCount = totalCells * density / 100;
while (obstacles.Count < obstacleCount)
{
int x = random.Next(width);
int y = random.Next(height);
obstacles.Add(new Point(x, y));
}
return obstacles;
}
// Использование:
var obstacles = GenerateRandomObstacles(40, 40, 15); // 15% препятствий
Советы по созданию интересных карт
- Баланс сложности: 10-20% препятствий от площади поля
- Проходы: Всегда оставляйте пути между чекпоинтами
- Узкие места: Создают интересные челленджи для алгоритма
- Длинные прямые: Позволяют разгоняться
- Зигзаги: Требуют точного управления скоростью
- Комнаты: Добавляют разнообразие
Тестирование масштабируемости
# Маленькая карта (15×15, 2 чекпоинта)
# Ожидается: BFS и A* одинаково быстрые
# Средняя карта (30×30, 3 чекпоинта)
# Ожидается: A* в 2-3 раза быстрее
# Большая карта (50×50, 4 чекпоинта)
# Ожидается: A* в 5-10 раз быстрее
# Огромная карта (80×80, 5+ чекпоинтов)
# Ожидается: BFS не справится, A* найдет решение