# -*- coding: utf-8 -*-
"""
Created on Tue May 28 15:14:12 2024

@author: Stéphane Pasquet
"""

from random import randint, shuffle
from PyQt5.QtWidgets import QApplication, QWidget, QLabel, QPushButton, QVBoxLayout, QLineEdit, QFrame
from PyQt5.QtGui import QPainter, QPen
from PyQt5.QtCore import Qt

class Labyrinthe(QWidget):
    def __init__(self, mursH, mursV, globNbrColonnes, globNbrLignes):
        super().__init__()
        self.mursH = mursH
        self.mursV = mursV
        self.globNbrColonnes = globNbrColonnes
        self.globNbrLignes = globNbrLignes
        self.initUI()

    def initUI(self):
        self.setWindowTitle('Labyrinthe')
        self.setGeometry(100, 100, (self.globNbrColonnes + 1) * 20 + 40, (self.globNbrLignes + 1) * 20 + 40)
        self.show()

    def paintEvent(self, event):
        qp = QPainter(self)
        delta = 20
        dim = 20
        qp.setPen(QPen(Qt.black, 2, Qt.SolidLine))

        # Dessiner les murs horizontaux
        for ligne in range(self.globNbrLignes + 1):
            for colonne in range(self.globNbrColonnes):
                if self.mursH[ligne][colonne]:
                    qp.drawLine(int(delta + colonne * dim), int(delta + ligne * dim), 
                                int(delta + (colonne + 1) * dim), int(delta + ligne * dim))

        # Dessiner les murs verticaux
        for ligne in range(self.globNbrLignes):
            for colonne in range(self.globNbrColonnes + 1):
                if self.mursV[ligne][colonne]:
                    qp.drawLine(int(delta + colonne * dim), int(delta + ligne * dim), 
                                int(delta + colonne * dim), int(delta + (ligne + 1) * dim))

class Window(QWidget):
    def __init__(self):
        super().__init__()
        self.initUI()

    def initUI(self):
        self.setWindowTitle('Labyrinthe')
        self.setGeometry(100, 100, 300, 400)

        vbox = QVBoxLayout()
        self.setLayout(vbox)

        label1 = QLabel("Génération du labyrinthe", self)
        label1.setStyleSheet("font: 20pt Arial")
        label1.setAlignment(Qt.AlignCenter)
        vbox.addWidget(label1)

        line1 = QFrame(self)
        line1.setFrameShape(QFrame.HLine)
        line1.setFrameShadow(QFrame.Sunken)
        vbox.addWidget(line1)

        label2 = QLabel("Nombre de colonnes (10 minimum, 99 maximum)", self)
        vbox.addWidget(label2)

        self.nbrCols = QLineEdit(self)
        vbox.addWidget(self.nbrCols)

        label3 = QLabel("Nombre de lignes (10 minimum, 99 maximum)", self)
        vbox.addWidget(label3)

        self.nbrLignes = QLineEdit(self)
        vbox.addWidget(self.nbrLignes)

        line2 = QFrame(self)
        line2.setFrameShape(QFrame.HLine)
        line2.setFrameShadow(QFrame.Sunken)
        vbox.addWidget(line2)

        btnGenerer = QPushButton("Générer le labyrinthe", self)
        btnGenerer.clicked.connect(self.generer_labyrinthe)
        vbox.addWidget(btnGenerer)

    def generer_labyrinthe(self):
        try:
            globNbrColonnes = int(self.nbrCols.text())
            globNbrLignes = int(self.nbrLignes.text())
        except ValueError:
            return

        if globNbrColonnes < 10:
            globNbrColonnes = 10
        if globNbrColonnes > 99:
            globNbrColonnes = 99
        if globNbrLignes < 10:
            globNbrLignes = 10
        if globNbrLignes > 99:
            globNbrLignes = 99

        MursH = [[True for _ in range(globNbrColonnes)] for _ in range(globNbrLignes + 1)]
        MursV = [[True for _ in range(globNbrColonnes + 1)] for _ in range(globNbrLignes)]

        self.explore(globNbrColonnes, globNbrLignes, MursH, MursV)

        self.labyrinthe = Labyrinthe(MursH, MursV, globNbrColonnes, globNbrLignes)
        self.labyrinthe.show()

    def explore(self, globNbrColonnes, globNbrLignes, MursH, MursV):
        visited = [[False for _ in range(globNbrColonnes)] for _ in range(globNbrLignes)]
        
        def carve_passages_from(cx, cy):
            directions = [(cx - 1, cy, 'N'), (cx + 1, cy, 'S'), (cx, cy - 1, 'W'), (cx, cy + 1, 'E')]
            shuffle(directions)
            for nx, ny, direction in directions:
                if 0 <= nx < globNbrLignes and 0 <= ny < globNbrColonnes and not visited[nx][ny]:
                    visited[nx][ny] = True
                    if direction == 'N':
                        MursH[cx][cy] = False
                    elif direction == 'S':
                        MursH[nx][ny] = False
                    elif direction == 'W':
                        MursV[cx][cy] = False
                    elif direction == 'E':
                        MursV[nx][ny] = False
                    carve_passages_from(nx, ny)
        
        start_x, start_y = randint(0, globNbrLignes - 1), randint(0, globNbrColonnes - 1)
        visited[start_x][start_y] = True
        carve_passages_from(start_x, start_y)

if __name__ == '__main__':
    app = QApplication([])
    window = Window()
    window.show()
    app.exec_()
