Zueinander abhängige Signale

7

Bare Frage:

Gibt es eine Möglichkeit, ein Paar Signale zu definieren, die in Elm voneinander abhängen?

Präambel:

Ich versuche, ein winziges Cookie-Clicker-ähnliches Browserspiel zu schreiben, in dem der Spieler Ressourcen sammelt und sie dann ausgibt, um autonome Ressourcen sammelnde Konstrukte zu kaufen, die beim Kauf teurer werden. Das beinhaltet drei relevante Signale: gathered (wie viel Ressourcen der Spieler gesammelt hat), spent (wie viel Ressource hat der Spieler bereits ausgegeben) und cost (wie viel kostet ein Upgrade).

Hier ist eine Implementierung:

%Vor%

Dies wird zwar gut übersetzt, aber wenn ich es in eine HTML-Datei einbetten will, in der die entsprechenden Tasten angeschlossen sind, um Nachrichten an die entsprechenden Ports oben zu senden, bekomme ich den Fehler

%Vor%

Das Problem scheint darin zu bestehen, dass cost von canAfford abhängt, was von balance abhängt, was von spent abhängt, was wiederum von cost abhängt.

Wenn ich die Kostenzeile so ändere, dass

%Vor%

es funktioniert wie erwartet (außer dass der Spieler in negative Ressourcen investieren darf, was ich gerne vermeiden würde).

Irgendwelche Ideen?

    
Inaimathi 07.03.2014, 21:49
quelle

1 Antwort

20

Beantworte deine nackte Frage

Nein , in Elm gibt es keinen allgemeinen Weg, gegenseitig rekursive Signale zu definieren.
Das Problem liegt in der Einschränkung, dass ein Signal in Elm immer einen Wert haben muss. Wenn die Definition von cost canAfford erfordert, aber canAfford in cost definiert ist, besteht das Problem darin, mit der Auflösung des Anfangswerts des Signals zu beginnen. Dies ist ein schwieriges Problem zu lösen, wenn Sie in Bezug auf gegenseitig rekursive Signale denken.

Gegenseitig rekursive Signale haben alles mit vergangenen Signalwerten zu tun. Mit dem Konstrukt foldp können Sie das Äquivalent von gegenseitig rekursiven Signalen bis zu einem bestimmten Punkt angeben. Die Lösung des Anfangswertproblems wird durch ein explizites Argument für foldp , das der Anfangswert ist, gelöst. Die Einschränkung ist jedoch, dass foldp nur reine Funktionen benötigt.

Dieses Problem lässt sich nur schwer so erklären, dass keine Vorkenntnisse erforderlich sind. Also hier ist eine andere Erklärung, basierend auf einem Diagramm, das ich von Ihrem Code gemacht habe.

Nehmen Sie sich Zeit, um die Verbindungen zwischen dem Code und dem Diagramm zu finden (beachten Sie, dass ich main weggelassen habe, um das Diagramm zu vereinfachen). A foldp ist ein Knoten mit einer Schleife zurück, sampleOn hat einen Blitz usw. (Ich habe sampleOn bei einem konstanten Signal in always umgeschrieben). Der problematische Teil ist die steigende rote Linie mit canAfford in der Definition von cost .
Wie Sie sehen können, hat eine grundlegende foldp eine einfache Schleife mit einem Basiswert. Dies zu implementieren ist einfacher als ein beliebiges Rückschleifen wie das Ihre.

Ich hoffe, Sie verstehen das Problem jetzt. Die Einschränkung ist in Elm, es ist nicht deine Schuld Ich löse diese Einschränkung in Elm auf, obwohl es einige Zeit dauern wird.

Lösung für Ihr Problem

Obwohl es schön sein kann, Signale zu benennen und mit diesen zu arbeiten, hilft es bei der Implementierung von Spielen in Elm normalerweise, ein anderes zu verwenden Programmierstil . Die Idee im verlinkten Artikel besteht darin, Ihren Code in folgende Teile aufzuteilen:

  1. Eingaben: Mouse , Time und Ports in Ihrem Fall.
  2. Modell: Der Status des Spiels, in Ihrem Fall cost , balance , canAfford , spent , gathered usw.
  3. Update: Die Update-Funktion des Spiels, die Sie aus kleineren Update-Funktionen zusammenstellen können. Diese sollten möglichst reine Funktionen sein.
  4. Ansicht: Code zum Anzeigen des Modells.

Verknüpfen Sie alles mit etwas wie main = view <~ foldp update modelStartValues inputs .

Insbesondere würde ich es so schreiben:

%Vor%     
Apanatshka 09.03.2014, 15:56
quelle

Tags und Links