Python :: Aufgabe #65 :: Lösung #1

1 Lösung Lösung öffentlich
#65

Lösen eines Labyrinths

Fortgeschrittener - Python von eulerscheZhl - 13.12.2014 um 16:37 Uhr
Schreibe ein Programm, das in der Lage ist, ein Labyrinth zu lösen.
Regeln:
- das Startfeld ist im Eck unten links, das Ziel ist oben rechts
- ein Feld kann nur dann betreten werden, wenn es direkt an das aktuelle Feld angrenzt (diagonale Felder zählen nicht als angrenzend)
- bei der Lösung darf jedes Feld nur einmal durchquert werden

Das Programm kann das Labyrinth z.B. aus einer Textdatei entgegennehmen und soll dann den Weg vom Start zum Ziel ausgeben (siehe Screenshot im Anhang).
Es sind Beispiellabyrinthe mit unterschiedlicher Größe angefügt. Diese sind alle eindeutig lösbar.

Bonusaufgabe:
Schreibe eine Funktion, die Breite und Höhe entgegennimmt und dann zufällig ein Labyrinth erzeugt.
#1
vote_ok
von AlexGroeg (2010 Punkte) - 29.03.2021 um 07:46 Uhr
Quellcode ausblenden Python-Code

# -*- coding: utf-8 -*-
# Python 3.8.5


# -- labyrinth lösen -------------------------

import pygame, random
from pygame.locals import *


# -- Labyrint aus Datei einlesen -------------

datei = 'labyrinth/labyrinth_20_22.txt'
fd = open(datei)
inhalt = fd.read()    # Lese die gesamte Datei
#print(inhalt)
fd.close()

l = []
lab = []

for char in inhalt:   # Labyrinth in Matrix einlesen 
    if char != '\n':  # bis Zeilenende
        if char == '#':
            l.append(1)
        else:
            l.append(0)
    else:
        lab.append(l.copy())
        breite = len(l)
        l.clear()

höhe = len(lab)

#for i in lab:
#    print(i)

ax = 1; ay = höhe -2        # Startpunkt
zx = breite -2; zy = 1      # Zielpunkt


# -- GUI ----------------------------------------

ORANGE      = ( 255, 140,   0)  # genutzte Farben
BLUE        = (  21, 116, 193)
SCHWARZ     = (   0,   0,   0)
hintergrund = ( 255, 255,  50)
ROT         = ( 255,   0,   0)
farbe       = [ ORANGE, BLUE, SCHWARZ, ROT ]
fb          = 0
          
MULTIPLIKATOR = 10             # Größen Multiplikator

fenster = pygame.display.set_mode((breite *MULTIPLIKATOR, höhe *MULTIPLIKATOR))  # Fenster erzeugen über Berechnung
pygame.display.set_caption("Labyrinth")                                          # Titel für Fensterkopf
clock = pygame.time.Clock()                                                      # Bildschirm Aktualisierungen einstellen


def kor(zahl):
    ''' Korrekturfaktor berechnen '''
    zahl = zahl * MULTIPLIKATOR
    return zahl

def element_zeichnen(spalte,reihe):
    ''' Spielelement zeichnen '''
    pygame.draw.rect(fenster, farbe[fb], [kor(spalte), kor(reihe),kor(1),kor(1)]) 

def element(karte,farbe):
    ''' Ausgabe Mauersteine im Spielfenster '''
    global breite, höhe, fb
    for x in range(breite):
        for y in range(höhe):
            if karte[y][x] == 1:
                fb = farbe
                element_zeichnen(x,y)
            if karte[y][x] == 2:
                fb = 3
                element_zeichnen(x,y)
                
def weg(x,y,farbe):
    ''' Zeichne Weg '''
    global fb
    fb = farbe
    element_zeichnen(x,y)
    
   
# -- Lösungsansatz --------------------------------------------

def umfeld(x,y):
    ''' Umfeld kontrollieren '''
    oben, rechts, links, unten = 1, 1, 1, 1
    
    try:
        if lab[y -1][x] == 0:  oben =   0; #print('oben frei')       
        if lab[y][x +1] == 0:  rechts = 0; #print('rechts frei')
        if lab[y][x -1] == 0:  links =  0; #print('links frei')
        if lab[y +1][x] == 0:  unten =  0; #print('unten frei')
        
    except:
        oben, rechts, links, unten = None, None, None, None  #print('Fehler*)
        
    summe = oben + rechts + links + unten
    
    #print(oben,rechts,links,unten, summe)    
    return oben, rechts, links, unten, summe
        
def schritt(x,y,richtung): 
    ''' Wenn frei Schritt '''
    ob, re, li, un, summe = umfeld(x,y)     # test Umfeld
       
    if ob == 0 and richtung ==  0:  y -= 1  # wenn frei gehe nach oben
    if re == 0 and richtung ==  1:  x += 1  # wenn frei gehe nach rechts
    if li == 0 and richtung == -1:  x -= 1  # wenn frei gehe nach links
    if un == 0 and richtung ==  2:  y += 1  # wenn frei gehe nach unten
              
    if [x,y] not in pos :
        pos.append([x,y])
    
    return summe


# -- Start -----------------------------------------------------------------------

pos = [[ax,ay]]
sx, sy = ax, ay
n = 0
l = 0
s = 1

while sy != zy or sx != zx:             # solange Zielposition noch nicht erreicht
    
    fenster.fill(hintergrund)           # GUI starten
    element(lab,0)                      # Labyrinth zeichnen
    weg(zx,zy,1)                        # Endpunkt zeichnen
        
    l = len(pos)                        # Anzahl Positionen bei letzter Position
    try:
        sx, sy = pos[-1]                # letzte Position
    except:
        pass
        
    richtung = random.randint(-1,2);    #print(richtung)
    
    s = schritt(sx, sy, richtung)       # mache Schritt wenn frei
    
    for i in pos:
        weg(i[0],i[1],2)                # Weg zeichnen
        
    pygame.display.flip()               # Fenster aktualisieren
    #clock.tick(10)                      # Refresh-Zeit festlegen     
    
    if len(pos) == l:                   # wenn rückwärts       
        if s > 2:                       # einen Schritt Vorschau
            xp, yp = pos.pop(-1)
            try:  
                lab[yp][xp] = 2
            except:
                pass            
    
    n +=1                               # Durchläufe zählen


# -- Ausgabe ---------------------

#print(pos)
#for item in lab:
 #   print(item)
 
print('\nDurchläufe:', n)

be = []

for i in pos:
    if i[0] > ax: be.append('r')
    if i[0] < ax: be.append('l')
    if i[1] > ay: be.append('u')
    if i[1] < ay: be.append('o')
    ax, ay = i[0], i[1]   

print('Schritte:',len(be))

for i in be:
    print(i, end='')


# -- Ende ----------------------

clock.tick(0.05)    
pygame.quit()

Kommentare:

Für diese Lösung gibt es noch keinen Kommentar

Bitte melden Sie sich an um eine Kommentar zu schreiben.
Kommentar schreiben