save and load
This commit is contained in:
@ -1,10 +1,12 @@
|
|||||||
import inputHelper
|
import inputHelper
|
||||||
import turtle
|
import turtle
|
||||||
import time
|
import drawer
|
||||||
|
|
||||||
turtle.tracer(0, 0)
|
turtleObject = drawer.newTurtle()
|
||||||
turtleObject = turtle.Turtle()
|
screen = turtleObject.screen
|
||||||
turtleObject.hideturtle()
|
screen.colormode(255)
|
||||||
turtleObject.screen.colormode(255)
|
try:
|
||||||
inputHelper.takeInput(turtleObject)
|
inputHelper.takeInput(turtleObject)
|
||||||
turtleObject.screen.mainloop()
|
except EOFError:
|
||||||
|
quit()
|
||||||
|
screen.mainloop()
|
||||||
|
|||||||
@ -16,21 +16,26 @@ class DrawingInfo:
|
|||||||
scale: float
|
scale: float
|
||||||
recursionDepth: int
|
recursionDepth: int
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class Drawing:
|
||||||
|
info: DrawingInfo
|
||||||
|
turtle: turtle.Turtle
|
||||||
|
|
||||||
drawings = []
|
drawings = []
|
||||||
|
|
||||||
class Drawer():
|
class Drawer():
|
||||||
def __init__(self, drawingInfo, turtleObject):
|
def __init__(self, drawing):
|
||||||
self.startWord = drawingInfo.lSystem.startWord
|
self.startWord = drawing.info.lSystem.startWord
|
||||||
self.recursionDepth = drawingInfo.recursionDepth
|
self.recursionDepth = drawing.info.recursionDepth
|
||||||
self.productionRules = drawingInfo.lSystem.productionRules
|
self.productionRules = drawing.info.lSystem.productionRules
|
||||||
self.angel = drawingInfo.lSystem.angel
|
self.angel = drawing.info.lSystem.angel
|
||||||
self.forwardDistance = drawingInfo.scale
|
self.forwardDistance = drawing.info.scale
|
||||||
self.turtle = turtleObject
|
self.turtle = drawing.turtle
|
||||||
self.turtle.penup()
|
self.turtle.penup()
|
||||||
self.turtle.setposition(drawingInfo.position)
|
self.turtle.setposition(drawing.info.position)
|
||||||
self.turtle.setheading(drawingInfo.rotation)
|
self.turtle.setheading(drawing.info.rotation)
|
||||||
self.turtle.pendown()
|
self.pendown()
|
||||||
self.turtle.pencolor(drawingInfo.color)
|
self.turtle.pencolor(drawing.info.color)
|
||||||
|
|
||||||
def storeEdges(self):
|
def storeEdges(self):
|
||||||
pass
|
pass
|
||||||
@ -79,9 +84,8 @@ class Edges:
|
|||||||
return turtle.Vec2D(self.max[0], self.max[1])
|
return turtle.Vec2D(self.max[0], self.max[1])
|
||||||
|
|
||||||
class DrawerSimulation(Drawer):
|
class DrawerSimulation(Drawer):
|
||||||
def __init__(self, drawingInfo, turtleObject):
|
def __init__(self, drawing):
|
||||||
super(DrawerSimulation, self).__init__(drawingInfo, turtleObject)
|
super(DrawerSimulation, self).__init__(drawing)
|
||||||
self.turtle.penup()
|
|
||||||
self.edges = Edges()
|
self.edges = Edges()
|
||||||
|
|
||||||
def storeEdges(self):
|
def storeEdges(self):
|
||||||
@ -94,9 +98,11 @@ class DrawerSimulation(Drawer):
|
|||||||
def pendown(self):
|
def pendown(self):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def draw(turtleObject, lSystem, recursionDepth, middle, rotation, size, color):
|
def draw(lSystem, recursionDepth, middle, rotation, size, color):
|
||||||
drawingInfo = DrawingInfo(lSystem, turtle.Vec2D(0, 0), rotation, color, 1, recursionDepth)
|
drawingInfo = DrawingInfo(lSystem, turtle.Vec2D(0, 0), rotation, color, 1, recursionDepth)
|
||||||
simulatedDraw = DrawerSimulation(drawingInfo, turtleObject)
|
turtleObject = newTurtle()
|
||||||
|
drawing = Drawing(drawingInfo, turtleObject)
|
||||||
|
simulatedDraw = DrawerSimulation(drawing)
|
||||||
simulatedDraw.draw()
|
simulatedDraw.draw()
|
||||||
maxVec = simulatedDraw.edges.maxVec()
|
maxVec = simulatedDraw.edges.maxVec()
|
||||||
minVec = simulatedDraw.edges.minVec()
|
minVec = simulatedDraw.edges.minVec()
|
||||||
@ -105,14 +111,21 @@ def draw(turtleObject, lSystem, recursionDepth, middle, rotation, size, color):
|
|||||||
yScale = size[1] / distance[1]
|
yScale = size[1] / distance[1]
|
||||||
scale = yScale if xScale > yScale else xScale
|
scale = yScale if xScale > yScale else xScale
|
||||||
pos = middle + (-minVec - distance * (1/2)) * scale
|
pos = middle + (-minVec - distance * (1/2)) * scale
|
||||||
drawingInfo.position = pos
|
drawing.info.position = pos
|
||||||
drawingInfo.scale = scale
|
drawing.info.scale = scale
|
||||||
actualDrawer = Drawer(drawingInfo, turtleObject)
|
drawScaled(drawing)
|
||||||
actualDrawer.draw()
|
|
||||||
drawings.append(drawingInfo)
|
|
||||||
|
|
||||||
def redraw(turtleObject):
|
def newTurtle():
|
||||||
turtleObject.clear()
|
turtleObject = turtle.Turtle()
|
||||||
for drawing in drawings:
|
turtleObject.hideturtle()
|
||||||
drawer = Drawer(drawing, turtleObject)
|
turtleObject._tracer(0, 0)
|
||||||
drawer.draw()
|
return turtleObject
|
||||||
|
|
||||||
|
def delete(i):
|
||||||
|
drawings[i].turtle.clear()
|
||||||
|
del drawings[i]
|
||||||
|
|
||||||
|
def drawScaled(drawing):
|
||||||
|
actualDrawer = Drawer(drawing)
|
||||||
|
actualDrawer.draw()
|
||||||
|
drawings.append(drawing)
|
||||||
|
|||||||
@ -1,18 +1,35 @@
|
|||||||
import drawer
|
import drawer
|
||||||
import turtle
|
import turtle
|
||||||
import lSystems
|
import lSystems
|
||||||
|
import pickle
|
||||||
|
from dataclasses import dataclass
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class Save:
|
||||||
|
backgroundColor: any
|
||||||
|
drawingInfos: [drawer.DrawingInfo]
|
||||||
|
|
||||||
|
loadedFilepath = None
|
||||||
|
backgroundColor = "white"
|
||||||
|
|
||||||
|
def defaultValueMsg(defaultValue):
|
||||||
|
if defaultValue == None:
|
||||||
|
return ""
|
||||||
|
return f" (Standartwert: {defaultValue})"
|
||||||
|
|
||||||
|
def inputWithDefault(description, defaultValue):
|
||||||
|
return input(f"{description}{defaultValueMsg(defaultValue)}: ")
|
||||||
|
|
||||||
def inputNum(inputType, description, rangeErrorMsg, minRange, maxRange, defaultValue = None):
|
def inputNum(inputType, description, rangeErrorMsg, minRange, maxRange, defaultValue = None):
|
||||||
n: int
|
|
||||||
while True:
|
while True:
|
||||||
inputValue = input(description)
|
inputValue = inputWithDefault(description, defaultValue)
|
||||||
try:
|
try:
|
||||||
n = inputType(inputValue)
|
number = inputType(inputValue)
|
||||||
inputError = n < minRange or n > maxRange
|
inputError = number < minRange or number > maxRange
|
||||||
if inputError:
|
if inputError:
|
||||||
print(rangeErrorMsg)
|
print(rangeErrorMsg)
|
||||||
else:
|
else:
|
||||||
return n
|
return number
|
||||||
except ValueError:
|
except ValueError:
|
||||||
if inputValue == "" and defaultValue != None:
|
if inputValue == "" and defaultValue != None:
|
||||||
return defaultValue
|
return defaultValue
|
||||||
@ -23,28 +40,33 @@ def inputColorError():
|
|||||||
|
|
||||||
def inputColor(turtleObject, question, defaultValue = None):
|
def inputColor(turtleObject, question, defaultValue = None):
|
||||||
while True:
|
while True:
|
||||||
defaultValueMsg = f" (Standartwert: {defaultValue})" if defaultValue != None else ""
|
inputValue = input(f"{question} RGB-Wert eingeben, wobei die Farben mit Leerzeichen getrennt werden, oder einen Tk-Farbnamen eingeben [0 0 0 - 255 255 255 oder Farben auf https://www.tcl.tk/man/tcl8.4/TkCmd/colors.html]{defaultValueMsg(defaultValue)}: ")
|
||||||
inputValue = input(f"{question} RGB-Wert eingeben, wobei die Farben mit Leerzeichen getrennt werden, oder einen Tk-Farbnamen eingeben [0 0 0 - 255 255 255 oder Farben auf https://www.tcl.tk/man/tcl8.4/TkCmd/colors.html]{defaultValueMsg}: ")
|
|
||||||
if inputValue == "":
|
if inputValue == "":
|
||||||
if defaultValue != None:
|
if defaultValue != None:
|
||||||
return defaultValue
|
return defaultValue
|
||||||
inputColorError()
|
inputColorError()
|
||||||
else:
|
else:
|
||||||
oldPenColor = turtleObject.pencolor()
|
|
||||||
try:
|
try:
|
||||||
color = tuple([int(color) for color in inputValue.split()])
|
color = tuple([int(color) for color in inputValue.split()])
|
||||||
turtleObject.pencolor(color)
|
turtleObject.pencolor(color)
|
||||||
turtleObject.pencolor(oldPenColor)
|
|
||||||
return color
|
return color
|
||||||
except:
|
except:
|
||||||
try:
|
try:
|
||||||
turtleObject.pencolor(inputValue)
|
turtleObject.pencolor(inputValue)
|
||||||
turtleObject.pencolor(oldPenColor)
|
|
||||||
return inputValue
|
return inputValue
|
||||||
except:
|
except:
|
||||||
inputColorError()
|
inputColorError()
|
||||||
|
|
||||||
|
def inputString(question, defaultValue = None):
|
||||||
|
while True:
|
||||||
|
inputValue = inputWithDefault(question, defaultValue)
|
||||||
|
if inputValue != "":
|
||||||
|
return inputValue
|
||||||
|
if defaultValue != None:
|
||||||
|
return defaultValue
|
||||||
|
|
||||||
def takeInput(turtleObject):
|
def takeInput(turtleObject):
|
||||||
|
global backgroundColor
|
||||||
inputValue = input("Bitte einen Befehl eingeben. h für Hilfe: ")
|
inputValue = input("Bitte einen Befehl eingeben. h für Hilfe: ")
|
||||||
match inputValue:
|
match inputValue:
|
||||||
case "h":
|
case "h":
|
||||||
@ -52,21 +74,23 @@ def takeInput(turtleObject):
|
|||||||
d: ein neues Lindenmayer-System zeichnen
|
d: ein neues Lindenmayer-System zeichnen
|
||||||
l: ein Lindenmayer-System löschen
|
l: ein Lindenmayer-System löschen
|
||||||
b: Hintergrundfarbe ändern
|
b: Hintergrundfarbe ändern
|
||||||
q: Programm beenden""")
|
q: Programm beenden
|
||||||
|
s: Lindenmayer-Systeme speichern
|
||||||
|
r: zuvor gespeicherte Lindenmayer-Systeme wiederherstellen""")
|
||||||
case "d":
|
case "d":
|
||||||
for i, lSystem in enumerate(lSystems.LSystems):
|
for i, lSystem in enumerate(lSystems.LSystems):
|
||||||
print(f"{i}: {lSystem.name}")
|
print(f"{i}: {lSystem.name}")
|
||||||
lSystemIndex = inputNum(int, "Bitte ein Lindenmayer-System auswählen und die entsprechende Nummer eingeben: ", "Es gibt kein L-System mit dieser Nummer.", 0, len(lSystems.LSystems) - 1)
|
lSystemIndex = inputNum(int, "Bitte ein Lindenmayer-System auswählen und die entsprechende Nummer eingeben: ", "Es gibt kein L-System mit dieser Nummer.", 0, len(lSystems.LSystems) - 1)
|
||||||
lSystem = lSystems.LSystems[lSystemIndex]
|
lSystem = lSystems.LSystems[lSystemIndex]
|
||||||
recursionDepth = inputNum(int, "Rekursiontiefe des Lindenmayer-Systems eingeben [1-20] (Standartwert: 5): ", "Rekursionstiefe nicht im vorgegebenen Bereich.", 1, 20, 5)
|
recursionDepth = inputNum(int, "Rekursiontiefe des Lindenmayer-Systems eingeben [1-20]", "Rekursionstiefe nicht im vorgegebenen Bereich.", 1, 20, 5)
|
||||||
rotation = inputNum(float, "Bitte die Rotation in Grad gegen den Uhrzeigersinn angeben, wobei 0° rechts ist (Standartwert: 90°): ", "nur Gradzahlen von 0 bis 360 werden akzeptiert.", 0, 360, 90)
|
rotation = inputNum(float, "Bitte die Rotation in Grad gegen den Uhrzeigersinn angeben, wobei 0° rechts ist", "nur Gradzahlen von 0 bis 360 werden akzeptiert.", 0, 360, 90)
|
||||||
inputError = True
|
inputError = True
|
||||||
color = inputColor(turtleObject, "Welche Farbe soll das Lindenmayer-System haben?", "black")
|
color = inputColor(turtleObject, "Welche Farbe soll das Lindenmayer-System haben?", "black")
|
||||||
while inputError:
|
while inputError:
|
||||||
match input("Möchtest du das das Lindenmayer-System das ganze Fenster ausfüllt? [J/n]: ").lower():
|
match input("Möchtest du das das Lindenmayer-System das ganze Fenster ausfüllt? [J/n]: ").lower():
|
||||||
case "j"|"":
|
case "j"|"":
|
||||||
inputError = False
|
inputError = False
|
||||||
drawer.draw(turtleObject, lSystem, recursionDepth, turtle.Vec2D(0, 0), rotation, turtleObject.screen._window_size(), color)
|
drawer.draw(lSystem, recursionDepth, turtle.Vec2D(0, 0), rotation, turtleObject.screen._window_size(), color)
|
||||||
takeInput(turtleObject)
|
takeInput(turtleObject)
|
||||||
case "n":
|
case "n":
|
||||||
inputError = False
|
inputError = False
|
||||||
@ -78,14 +102,15 @@ q: Programm beenden""")
|
|||||||
size = pos[1] - pos[0]
|
size = pos[1] - pos[0]
|
||||||
middle = pos[0] + (1/2) * size
|
middle = pos[0] + (1/2) * size
|
||||||
size = turtle.Vec2D(abs(size[0]), abs(size[1]))
|
size = turtle.Vec2D(abs(size[0]), abs(size[1]))
|
||||||
drawer.draw(turtleObject, lSystem, recursionDepth, middle, rotation, size, color)
|
drawer.draw(lSystem, recursionDepth, middle, rotation, size, color)
|
||||||
takeInput(turtleObject)
|
takeInput(turtleObject)
|
||||||
|
|
||||||
turtleObject.screen.onclick(lambda x, y: afterClick(turtle.Vec2D(x, y)))
|
turtleObject.screen.onclick(lambda x, y: afterClick(turtle.Vec2D(x, y)))
|
||||||
case _:
|
case _:
|
||||||
print("Bitte j oder n eingeben")
|
print("Bitte j oder n eingeben")
|
||||||
case "b":
|
case "b":
|
||||||
turtleObject.screen.bgcolor(inputColor(turtleObject, "Hintergrundfarbe eingeben"))
|
backgroundColor = inputColor(turtleObject, "Hintergrundfarbe eingeben")
|
||||||
|
turtleObject.screen.bgcolor(backgroundColor)
|
||||||
case "q":
|
case "q":
|
||||||
quit()
|
quit()
|
||||||
case "l":
|
case "l":
|
||||||
@ -93,10 +118,37 @@ q: Programm beenden""")
|
|||||||
print("Es gibt nichts, was man löschen könnte.")
|
print("Es gibt nichts, was man löschen könnte.")
|
||||||
else:
|
else:
|
||||||
for i, drawing in enumerate(drawer.drawings):
|
for i, drawing in enumerate(drawer.drawings):
|
||||||
print(f"{i}: {drawing.lSystem.name} Position: {drawing.position}")
|
print(f"{i}: {drawing.info.lSystem.name} Position: {drawing.info.position}")
|
||||||
iDelete = inputNum(int, "Nummer des zu löschenden Zeichnung eingeben: ", "Es gibt keine Zeichnung mit dieser Nummer", 0, len(drawer.drawings) - 1)
|
iDelete = inputNum(int, "Nummer des zu löschenden Zeichnung eingeben: ", "Es gibt keine Zeichnung mit dieser Nummer", 0, len(drawer.drawings) - 1)
|
||||||
del drawer.drawings[iDelete]
|
drawer.delete(iDelete)
|
||||||
drawer.redraw(turtleObject)
|
case "s":
|
||||||
|
filepath = inputString("Dateipfad zum Speichern eingeben", loadedFilepath)
|
||||||
|
drawingInfo = [drawing.info for drawing in drawer.drawings]
|
||||||
|
save = Save(backgroundColor, drawingInfo)
|
||||||
|
try:
|
||||||
|
file = open(filepath, "wb")
|
||||||
|
pickle.dump(save, file)
|
||||||
|
print("erfolgreich gespeichert")
|
||||||
|
except Exception as err:
|
||||||
|
print(err)
|
||||||
|
finally:
|
||||||
|
file.close()
|
||||||
|
case "r":
|
||||||
|
filepath = inputString("Datei, die geladen werden soll eingeben")
|
||||||
|
save: Save
|
||||||
|
try:
|
||||||
|
file = open(filepath, "rb")
|
||||||
|
save = pickle.load(file)
|
||||||
|
except Exception as err:
|
||||||
|
print(err)
|
||||||
|
finally:
|
||||||
|
file.close()
|
||||||
|
turtleObject.screen.clear()
|
||||||
|
backgroundColor = save.backgroundColor
|
||||||
|
turtleObject.screen.bgcolor(save.backgroundColor)
|
||||||
|
for drawingInfo in save.drawingInfos:
|
||||||
|
drawing = drawer.Drawing(drawingInfo, drawer.newTurtle())
|
||||||
|
drawer.drawScaled(drawing)
|
||||||
case _:
|
case _:
|
||||||
print("unbekannter Befehl")
|
print("unbekannter Befehl")
|
||||||
if inputValue != "d":
|
if inputValue != "d":
|
||||||
|
|||||||
Reference in New Issue
Block a user