Der Händler
Jeden Tag fährt Hugo, der Händler, mit seinem Karren an Emmas Hof vorbei und kauft Pflanzen. Seine Preise ändern sich jeden Tag. Ist sein Karren leer, zahlt er für jede Pflanze 2 Münzen mehr als der Markt. Am nächsten Tag, wenn er halb voll ist, zahlt er 1 Münze mehr. Am dritten Tag ist er voll, und er zahlt nur, was der Markt zahlt. Dann bringt er alles in die Stadt, und es beginnt von vorn: 2, 1, 0, 2, 1, 0 …
Emmas Regel ist einfach: Wenn Hugo mehr zahlt als der Markt, verkauft sie ihm alles aus der Scheune. Sonst behält sie es, und am Ende der Saison geht es auf den Markt.
Hugos Tage sind ein Fall für eine Koroutine, wie in der Lektion über Koroutinen: eine Funktion, die jeden Tag ein Stück läuft und bei coroutine.yield pausiert. coroutine.wrap macht daraus eine Funktion, die sie fortsetzt: Jeder Aufruf führt sie bis zum nächsten yield aus und gibt den Wert zurück, den sie an yield übergeben hat. Zum Beispiel, was der Hund Rex den ganzen Tag macht:
local function rexSkript()
while true do
coroutine.yield("bewacht die Scheune")
coroutine.yield("schläft am Brunnen")
end
end
local rex = coroutine.wrap(rexSkript)
for tag = 1, 3 do
print("Tag " .. tag .. ": Rex " .. rex())
endDas gibt Folgendes aus:
Tag 1: Rex bewacht die Scheune
Tag 2: Rex schläft am Brunnen
Tag 3: Rex bewacht die ScheuneDie Schleife while true endet nie, aber das ist hier in Ordnung. Bei jedem yield pausiert die Koroutine, und das Programm läuft weiter. Sie läuft erst wieder, wenn sie aufgerufen wird, und macht dort weiter, wo sie aufgehört hat, hier mitten in ihrer Schleife. Hugos Skript wird genauso aussehen, nur mit einer for-Schleife darin, die von 2 abwärts bis 0 zählt. Vergiss ihre Schrittweite -1 nicht. Ohne sie läuft die for-Schleife nullmal, while true erreicht nie ein yield, und das Programm läuft, bis die Seite es nach 5 Sekunden abbricht.
Hugos Skript muss als Koroutine laufen, mit coroutine.wrap (oder coroutine.create und coroutine.resume). Rufst du hugoSkript() direkt auf, ist es keine Koroutine, und yield hat nichts, wohin es zurückkehren kann: attempt to yield from outside a coroutine (diesmal ohne Zeilennummer am Anfang). Und erstelle die Koroutine nur einmal, über der Schleife über die Tage. Würdest du sie innerhalb der Schleife erstellen, finge sie jeden Tag von vorn an, und Hugo würde immer 2 Münzen mehr zahlen.
Die Funktion verkaufe braucht zwei weitere Parameter: wer kauft (kaeufer) und wie viele Münzen mehr als der Markt er zahlt (aufschlag). Gib ihnen Standardwerte, wie in der Lektion über Funktionen: kaeufer = kaeufer or "Markt" und aufschlag = aufschlag or 0. Dann funktioniert der Aufruf verkaufe(scheune) am Ende der Saison wie zuvor.
verkaufe muss auch die Scheune leeren: scheune[name] = nil entfernt eine Pflanze, sobald sie verkauft ist. Ohne das würde Hugo an einem anderen Tag denselben Weizen noch einmal kaufen, der Markt am Ende noch einmal, und Emma beendete die Saison mit 390 Münzen. Das ist zu schön, um wahr zu sein. Die Schlüssel der Scheune innerhalb der Schleife zu entfernen ist in Ordnung, weil die Schleife die separate Liste aus sortierteNamen durchgeht.
Am ersten Tag zahlt Hugo 2 Münzen mehr, aber die Scheune ist noch leer, und verkaufe würde Hugo: = 0 ausgeben. Lass es seine Zeile also nur ausgeben, wenn die Summe größer als 0 ist.
So schreibst du es:
Anweisungen
- 1
Schreibe unter
verkaufeeine FunktionhugoSkript()mit einer Schleifewhile true, die nie endet. Darin zählt einefor-Schleife von2abwärts bis0(mit der Schrittweite-1) und gibt jede Zahl ancoroutine.yieldweiter. - 2
Ändere
verkaufe. Gib der Funktion die Parameterkaeuferundaufschlagmit den Standardwerten"Markt"und0, addiereaufschlagzum Preis jeder Pflanze, beginne die Zeile mitkaeuferstatt mitMarktund entferne jede verkaufte Pflanze aus der Scheune. Gib die Zeile nur aus, wenn die Summe größer als 0 ist. Die Ausgabe ändert sich noch nicht. - 3
Erstelle im Hauptprogramm Hugos Koroutine über der Schleife über die Tage:
local hugo = coroutine.wrap(hugoSkript). Hole dir an jedem Tag nach der Zeile des Tages Hugos Aufschlag aushugo(). Ist er größer als 0, verkaufe ihm mitverkaufe(scheune, "Hugo", aufschlag)alles aus der Scheune und addiere die Münzen. Die Saison sieht jetzt so aus:Münzen: 6 Tag 1 (sonnig): Karotte 1/3, Weizen 1/2, Kürbis 1/6 Tag 2 (sonnig): Karotte 2/3, Weizen 2/2, Kürbis 2/6 Hugo: Weizen 6 x 4 = 24 Tag 3 (regnerisch): Karotte 3/3, Weizen 2/2, Kürbis 4/6 Tag 4 (wolkig): Karotte 1/3, Weizen 1/2, Kürbis 5/6 Hugo: Karotte 4 x 7, Weizen 6 x 5 = 58 Tag 5 (sonnig): Karotte 2/3, Weizen 2/2, Kürbis 6/6 Hugo: Kürbis 2 x 21, Weizen 6 x 4 = 66 Tag 6 (wolkig): Karotte 3/3, Weizen 1/2, Kürbis 1/6 Markt: Karotte 4 x 5 = 20 Saisonende: 174 MünzenZahlt Hugo jeden Tag 2 Münzen mehr (
Weizen 6 x 5an Tag 2), erstellst du seine Koroutine innerhalb der Schleife.