Files
Elvenbane/common.py
2026-02-20 02:09:43 +03:00

75 lines
2.9 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import os
import json
import uuid
from dataclasses import dataclass, field
from copy import deepcopy
from collections import defaultdict
from heapq import heappush, heappop
import pygame
import pygame_gui
from classes import Rock
def path_exists(data, path):
current = data
for key in path:
if isinstance(current, dict) and key in current:
current = current[key]
else:
return False
return True
def find_way(cells, start, goal):
"""Находит путь от start=(row, col) к goal=(row, col). row=y (строка), col=x (столбец)"""
rows = len(cells)
if rows == 0:
return None
cols = len(cells[0])
def is_passable(cell):
# Проходимо, если НЕ Rock в terrain И creature_obj отсутствует
return (cell.terrain_obj is None or not isinstance(cell.terrain_obj, Rock))
# Проверка границ и проходимости старт/гол
s_row, s_col = start
g_row, g_col = goal
if not (0 <= s_row < rows and 0 <= s_col < cols and 0 <= g_row < rows and 0 <= g_col < cols):
return None
start_cell = cells[s_row][s_col]
goal_cell = cells[g_row][g_col]
if not is_passable(start_cell) or not is_passable(goal_cell):
print(f"Старт/гол непроходимы: start={is_passable(start_cell)}, goal={is_passable(goal_cell)}")
return None
# A* поиск (используем прямые row,col вместо ID для простоты)
directions = [(-1, 0), (1, 0), (0, -1), (0, 1)] # вверх, вниз, лево, право
open_set = []
# f_score = g + h (h=манхэттен)
h = abs(s_row - g_row) + abs(s_col - g_col)
heappush(open_set, (h, 0, s_row, s_col)) # f, g, row, col
came_from = {}
g_score = defaultdict(lambda: float('inf'))
g_score[(s_row, s_col)] = 0
while open_set:
_, _, row, col = heappop(open_set)
if (row, col) == (g_row, g_col):
# Восстанавливаем путь
path = []
current = (row, col)
while current in came_from:
path.append(current)
current = came_from[current]
path.append(start)
return path[::-1]
for dr, dc in directions:
nr, nc = row + dr, col + dc
if 0 <= nr < rows and 0 <= nc < cols:
if is_passable(cells[nr][nc]):
tentative_g = g_score[(row, col)] + 1
pos = (nr, nc)
if tentative_g < g_score[pos]:
came_from[pos] = (row, col)
g_score[pos] = tentative_g
f = tentative_g + abs(nr - g_row) + abs(nc - g_col)
heappush(open_set, (f, tentative_g, nr, nc))
print("Путь не найден (нет связи)")
return None