Hallo zusammen,
Ich muss als Aufgabe eine "City-Simulation" Application programmieren.
Es geht darum eine random Karte zu generieren, diese grafisch (so rastermässig) auszugeben und dann ein paar Autos und Menschen automatisch drüber laufen zu lassen. Sprich das das Programm alle paar Sekunden von selbst aktualisiert und dann wie erwähnt die Autos fahren und die Menschen über die Strassen umherlaufen.
Anbei habe ich einmal alles was ich schon habe reinkopiert... Irgendwie hänge ich aber nun ein wenig wie es weiter geht. Zudem bin ich mir bewusst, dass mein Programm schon noch sehr kompliziert und umständlich aussieht. Da ich aber noch ein ziemlicher Amateur bin dachte ich mir das ich zuerst einmal schaue das es irgendwie läuft und ich dann zum Schluss beginne alles zu überarbeiten.
Kann mir jemand einen Tipp geben wie ich weiterfahren soll? bzw. wie ich das Programmieren könnte das sich Autos etc. über die Karte bewegen können?
Vielen Dank für die Hilfe
class Car:
def __init__(self):
self.car = ("\U0001F697")
class Person:
def __init__(self):
self.person = ("\U0001F6B9")
class Create: #Hier wird die Grundkarte erstellt
def __init__(self):
self.grid = None
self.starttime = None
self.endtime= None
self.vote = None
gras = "\033[32m\U0001F7E9" #gestrichelt
water = "\033[34m\U0001F7E6" #blue / getrichelt
empty_street = "\033[37m\U00002B1C" #white/grey
house = "\033[30m\U00002B1B" #black
self.symbols = [self.empty_street, water, house, gras]
def choice(self): #Hier hat der Benutzer die Wahl ob er eine random Karte will oder eine bestehende basierend auf einer bekannten stadt...
self.vote = int(input('Wollen Sie eine zufällige Karte (1) erstellen, oder einen Karten-Ausschnitt von xyz (2) wählen? '))
return self.vote
def random_grid_maker(self):
x1 = random.randint(1, 30)
x2 = random.randint(1, 30)
x3 = random.randint(1, 30)
x4 = random.randint(1, 30)
x5 = random.randint(1, 30)
n = 30
self.grid = [[0] * n for i in range(n)]
for i in range(n):
for j in range(n):
if i == x1 or i == x2 or i == x3 or i == x4 or i == x5:
self.grid[j] = "\033[37m\U00002B1C" #white/grey
elif j == x1 or j == x2 or j == x3 or j == x4 or j == x5:
self.grid[j] = "\033[37m\U00002B1C" #white/grey
elif i == x1+1 or i == x2+1 or i == x3+1 or i == x4+1 or i == x5+1:
self.grid[j] = "\033[30m\U00002B1B" #black
elif j == x1+1 or j == x2+1 or j == x3+1 or j == x4+1 or j == x5+1:
self.grid[j] = "\033[30m\U00002B1B" #black
elif i == x1-1 or i == x2-1 or i == x3-1 or i == x4-1 or i == x5-1:
self.grid[j] = "\033[30m\U00002B1B" #black
elif j == x1-1 or j == x2-1 or j == x3-1 or j == x4-1 or j == x5-1:
self.grid[j] = "\033[30m\U00002B1B" #black
else:
self.grid[j] = "\033[32m\U0001F7E9" #grün gestrichelt
for row in self.grid:
print(''.join([str(elem) for elem in row]))
return self.grid
def realistic(self):
x1 = 5
x2 = 10
x3 = 15
x4 = 20
x5 = 25
n = 30
self.grid = [[0] * n for i in range(n)]
for i in range(n):
for j in range(n):
if i == x1 or i == x2 or i == x3 or i == x4 or i == x5:
self.grid[j] = "\033[37m\U00002B1C" #white/grey
elif j == x1 or j == x2 or j == x3 or j == x4 or j == x5:
self.grid[j] = "\033[37m\U00002B1C" #white/grey
elif i == x1+1 or i == x2+1 or i == x3+1 or i == x4+1 or i == x5+1:
self.grid[j] = "\033[30m\U00002B1B" #black
elif j == x1+1 or j == x2+1 or j == x3+1 or j == x4+1 or j == x5+1:
self.grid[i][j] = "\033[30m\U00002B1B" #black
elif i == x1-1 or i == x2-1 or i == x3-1 or i == x4-1 or i == x5-1:
self.grid[i][j] = "\033[30m\U00002B1B" #black
elif j == x1-1 or j == x2-1 or j == x3-1 or j == x4-1 or j == x5-1:
self.grid[i][j] = "\033[30m\U00002B1B" #black
else:
self.grid[i][j] = "\033[32m\U0001F7E9" #grün gestrichelt
for row in self.grid:
print(''.join([str(elem) for elem in row]))
return self.grid
def execute_1(self): # Hier wird alles aufgerufen, dass man nicht alles separat aufrufen muss...
self.choice()
if self.vote == 1:
self.random_grid_maker()
elif self.vote == 2:
self.realistic()
else:
raise Exception('Falsche Eingabe, Sie müssen die Zahl 1 oder zwei wählen')
self.execute_1()
class City_Game(Create): #Hier wird das eigentliche Spiel gestartet... damit es
def __init__(self):
Create.__init__(self)
self.grid2 = self.grid
def aufgabe_1(self):
# Hier wird der Task 1 programmiert
return
def ausgabe_2(self):
return
def update(self):
#Hier wird das Programm laufend udated... sprich der Spielfluss...
return
if __name__ == "__main__":
a = Create()
a.execute_1()
print(a)
#zip funktion... um farbe und farbcodierung hinzuzufügen...
Python city Simulator
Bitte benutz die Code-Tags im Forum für Quelltext, denn in der jetzigen Form ist das nur schwer zu lesen.Ronald_MacDonald hat geschrieben: Mittwoch 13. Mai 2020, 14:27 Kann mir jemand einen Tipp geben wie ich weiterfahren soll? bzw. wie ich das Programmieren könnte das sich Autos etc. über die Karte bewegen können?
Für Einsteiger ist das eine ganz schön heftige Aufgabe, finde ich. Alleine schon das Erzeugen einer halbwegs plausiblen Karte ist alles andere als trivial (eine Stichwort zum Suchen wäre hier "procedural generation"). Grundsätzlich würde ich das runden-basiert implementieren ähnlich, wie man auch zum Beispiel ein Rouge-like oder auch Conways Game of Life umsetzt. D.h. du hast eine zugrunde liegende Datenstruktur für ein 2D-Grid bzw. einen Graphen. Jeder Knoten bzw. jede Zelle ist ein Spielfeld in deiner Simulation und enthält z.B. Informationen den Geländetype, die Entitäten, die sich dort befinden, welche Felder benachbart sind, etc.. Die eigentliche Simulation läuft dann Runden basiert, indem du dein Level Feld für Feld durchgehst und für jedes der dortigen Elemente die damit verknüpfte Aktion durchführst. Die Ergebnisse schreibst du in eine neue Variante deiner Datenstruktur, die am Ende der Runde die bisher ersetzt. Das wäre ein mögliches Konzept, für die grobe Architektur. Dann ist aber noch viel Detailarbeit zu leisten.
-
- User
- Beiträge: 4
- Registriert: Mittwoch 13. Mai 2020, 14:12
Super, Vielen Dank für die schnelle Antwort... Dann werde ich einmal ein wenig recherchieren...
Die Klassen Car und Person sind noch nicht sehr sinnvoll.
Wenn die Symbole konstant sind, dann sollten das auch Klassenkonstanten sein und vielleicht SYMBOL heißen.
Klassen sollten nach Zuständen und nicht nach Tätigkeiten benannt werden, im Gegensatz zu Methoden, wo es genau umgekehrt ist: Create -> Map, random_grid_maker -> make_random_grid.
Der Kommentar zeigt auch deutlich, dass Du hier eher eine Funktion meinst, statt einer Klasse.
Die Methode choice hat als Methode auf der Klasse nichts zu suchen.
`self.empty_street` ist nicht definiert.
Wenn man Variablen durchnummeriert, will man eigentlich Listen benutzen. Dann sind die Tests mit `in` auch viel einfacher.
Wenn Du schon Namen für die Symbole vergeben hast, dann verwende die auch.
Statt eine Liste mit Dummy-Werten zu initialisieren und dann zu überschreiben, erstellt man die Listen direkt mit den richtigen Werten.
Die Elemente sind schon Strings, so dass es nicht nötig ist, die nochmal mit str umzuwandeln.
Eine Funktion, die ein Attribut füllt, sollte das nicht auch noch zurückgeben.
Ausgabe sollte in eine eigene Methode.
Was soll denn das 1 bei `execute`?
Warum bindest Du grid zusätzlich an grid2 in City_Game? Vererbung ist hier auch die falsche Struktur. Ein City_Game ist ja keine Karte, sondern enthält vielleicht eine Karte.
Wenn die Symbole konstant sind, dann sollten das auch Klassenkonstanten sein und vielleicht SYMBOL heißen.
Code: Alles auswählen
class Car:
SYMBOL = "\U0001F697"
class Person:
SYMBOL = "\U0001F6B9"
Der Kommentar zeigt auch deutlich, dass Du hier eher eine Funktion meinst, statt einer Klasse.
Die Methode choice hat als Methode auf der Klasse nichts zu suchen.
`self.empty_street` ist nicht definiert.
Wenn man Variablen durchnummeriert, will man eigentlich Listen benutzen. Dann sind die Tests mit `in` auch viel einfacher.
Wenn Du schon Namen für die Symbole vergeben hast, dann verwende die auch.
Statt eine Liste mit Dummy-Werten zu initialisieren und dann zu überschreiben, erstellt man die Listen direkt mit den richtigen Werten.
Die Elemente sind schon Strings, so dass es nicht nötig ist, die nochmal mit str umzuwandeln.
Eine Funktion, die ein Attribut füllt, sollte das nicht auch noch zurückgeben.
Ausgabe sollte in eine eigene Methode.
Was soll denn das 1 bei `execute`?
Code: Alles auswählen
class Map:
GRAS = "\033[32m\U0001F7E9" #gestrichelt
WATER = "\033[34m\U0001F7E6" #blue / getrichelt
EMPTY_STREET = "\033[37m\U00002B1C" #white/grey
HOUSE = "\033[30m\U00002B1B" #black
SYMBOLS = [EMPTY_STREET, WATER, HOUSE, GRAS]
def __init__(self):
self.grid = None
def print_grid(self):
for row in self.grid:
print(''.join(row))
def make_random_grid(self, n=30):
positions = [random.randint(1, n) for _ in range(5)]
self.grid = []
for i in range(n):
row = []
for j in range(n):
if i in positions or j in positions:
symbol = self.EMPTY_STREET
elif (i in [p+1 for p in positions] or j in [p+1 for p in positions]
or j in [p-1 for p in positions] or j in [p-1 for p in positions])
symbol = self.HOUSE
else:
symbol = self.GRAS
row.append(symbol)
self.grid.append(row)