# Plateau hexagonal en coordonnees axiales (q, r), rayon 4 : 61 salles.
# Les salles sont des sols (cout 1) ou des cellules de mur (cout COUT_MUR).
import heapq
from collections import deque
import matplotlib.pyplot as plt
import numpy as np
R = 4
def est_dans_anneau(q, r):
return max(abs(q), abs(r), abs(q + r)) <= R
# Les six swaps generateurs : les six directions du pavage hexagonal.
VOISINS = [(1, 0), (1, -1), (0, -1), (-1, 0), (-1, 1), (0, 1)]
def voisins_case(q, r):
return [(q + dq, r + dr) for dq, dr in VOISINS if est_dans_anneau(q + dq, r + dr)]
salles = {(q, r): 'sol' for q in range(-R, R + 1) for r in range(-R, R + 1)
if est_dans_anneau(q, r)}
START, TARGET = (-4, 0), (4, -4)
# Le mur : deux chaines pleines, adjacentes (double epaisseur).
# A : q = -1, r = -3..4 (8 cellules). B : q = 0, r = -4..4 (9 cellules),
# etendue jusqu'au coin sud de l'anneau : pas de porte derobee, la bande est
# etanche de haut en bas — aucune ronde ne traverse sans payer au moins deux murs.
for r in range(-3, 5):
salles[(-1, r)] = 'mur'
for r in range(-4, 5):
salles[(0, r)] = 'mur'
# Palissade : deux cellules pendues au bord sud, cote cible (point de passage critique).
for r in range(-4, -2):
salles[(2, r)] = 'mur'
COUT_MUR, COUT_SOL = 3, 1
COUT_ENV = COUT_MUR
def set_cout_mur(cw):
global COUT_ENV
COUT_ENV = cw
def cout(q, r):
return COUT_ENV if salles[(q, r)] == 'mur' else COUT_SOL
def dessiner(titre, chemin=None):
fig, ax = plt.subplots(figsize=(6.6, 6.0))
s = 0.42
for (q, r), typ in salles.items():
x = s * np.sqrt(3) * (q + r / 2.0)
y = s * 1.5 * r
couleur = '#c8b6a0' if typ == 'mur' else '#e8f2e8'
poly = plt.Polygon([[x + s * np.cos(a), y + s * np.sin(a)]
for a in np.linspace(0, 2 * np.pi, 7)],
closed=True, facecolor=couleur, edgecolor='#556',
linewidth=0.6)
ax.add_patch(poly)
if chemin:
xs = [s * np.sqrt(3) * (q + r / 2.0) for q, r in chemin]
ys = [s * 1.5 * r for q, r in chemin]
ax.plot(xs, ys, 'r-', linewidth=2.2, zorder=5)
for pos, marqueur, couleur in ((START, 'o', '#d62728'), (TARGET, 'o', '#1f77b4')):
x = s * np.sqrt(3) * (pos[0] + pos[1] / 2.0)
y = s * 1.5 * pos[1]
ax.plot(x, y, marqueur, markersize=9, color=couleur, zorder=6)
ax.set_aspect('equal')
ax.axis('off')
ax.set_title(titre)
plt.show()
n_mur = sum(1 for v in salles.values() if v == 'mur')
print(f"salles totales : {len(salles)} (sol : {len(salles) - n_mur}, mur : {n_mur})")
print(f"START = {START}, TARGET = {TARGET}, cout mur = {COUT_MUR}, cout sol = {COUT_SOL}")
dessiner("Plateau hexagonal : sol (vert pâle), mur (beige), S (rouge), T (bleu)")