Achtung, veraltet! Nur noch teilweise gültig.
Siehe:
https://belletristica.com/de/books/17583-the-bell-oktober/chapter/67593-die-neuen-edelschweinchen
September 19, 2019
Hallo und willkommen!
Bei einigen Usern ist seit Einführung der Edelschweinchen etwas Unmut entstanden. Es wurde vermutet, dass User bevorzugt behandelt werden oder das System nicht wirklich zufällig agiert. Deshalb erzähle ich euch heute ein wenig über den Programmcode der die Edelschweinchen triggert.
Um die Antwort gleich vorweg zu nehmen: Nein, kein User wird bevorzugt.
Aber da man keiner Aussage einfach glauben sollte, hier der Beweis.
Lizzy hat vor kurzem den Code zu den Edelschweinchen veröffentlicht, den ich jetzt Zeile für Zeile mit euch durchgehen werde. Das Originalbild kann man von mir (Lyndis) bekommen.
Zu meinen Referenzen: Ich studiere Informatik im Master und habe bereits beruflich eine Webseite betreut. Ist jetzt nicht so die größte Erfahrung, aber es ist mehr als ausreichend, um den Code zu verstehen.
Also, here we go!
> def perform
Eine Funktion wird definiert. Diese kann man dann im restlichen Code wieder aufrufen und dort dann ausführen lassen. Man unterteilt Code in Funktionen um die Übersicht besser behalten zu können und um sich lästige Schreibarbeit zu sparen, wenn man die Funktion an mehreren Stellen braucht. ‘perform’ ist der Name der Funktion, mit dem man sie aufrufen kann.
> conversation = Conversation.find(1)
Merkt euch das kleingeschriebene ‘conversation’. Das großgeschriebene ‘Conversation’ repräsentiert in diesem Fall so etwas wie die Liste aller öffentlicher Channel. Die Nummer 1 ist die Taverne. Diese ‘Auswahl’ wird in ‘conversation’ gespeichert, damit es später verwendet werden kann.
> winner = conversation.messages.where.not(user_id: User.team_ids).first&.user
Hier taucht ‘conversation’ wieder auf. Der Punkt zwischen ‘conversation’ und ‘messages’ bedeutet, dass ‘messages’ sich auf ‘conversation’ bezieht. Ergo: Wähle alle Nachrichten aus der Taverne. Von diesen Nachrichten werden dann nur die ausgewählt, die nicht vom Team kommen (jede Nachricht hat eine ID die eindeutig einem User zugeordnet werden kann. teams_id beinhaltet alle IDs des Teams). Danach wird die letzte geschriebene Nachricht ausgewählt. Ich nehme an, diese heißt ‘first’, weil irgendwie gemanaged werden muss, dass nur 30 Nachrichten angezeigt werden. Jede neue Nachricht wird deshalb auf den ersten Platz der gesammelten Nachrichten gesetzt und alle anderen rücken einen Platz weiter nach hinten. Alles was hinter dem 30. Platz liegt, wird dann nicht mehr angezeigt.
Von dieser Nachricht wird jetzt der Username gewählt und das wird in ‘winner’ gespeichert. Dieser User bekommt also das Schweinchen.
> cooldown = rand(6.hours) + rand(6.hours) + 1.minute
Das ist der Codeschnipsel der neben dem vorigen am wichtigsten ist. Hier wird angegeben, wann das nächste Schweinchen auftaucht.
Der Code generiert eine zufällige Zahl zwischen einer Minute und 12 Stunden. Die eine Minute die aufaddiert wird, sorgt dafür, dass keine 0 am Ende herauskommen kann und somit zwei Schweinchen gleichzeitig auftauchen.
Dass zweimal eine Zahl zwischen einer Minute und sechs Stunden addiert wird, statt einmal ein rand(12.hours), liegt an der gewollten Verteilung der Zeiten.
Wirft man einen 12-seitigen Würfel, ist die Wahrscheinlichkeit eine bestimmte Zahl zu bekommen, immer ein zwölftel.
Wirft man zwei 6-seitige Würfel, ist es wesentlich wahrscheinlicher, eine 7 zu würfeln, als alles andere. Die eine Minute und die 12 Stunden sind dann am unwahrscheinlichsten.
Lizzy hat angekündigt, dass das Team an dieser Formel vielleicht noch ein wenig herumschreiben werden, weil sie mit der Häufigkeit der Schweinchen noch nicht 100% zufrieden sind.
> PigletJob.set(wait: cooldown).perform_later
Hier wird dem Erscheinen des nächsten Schweinchens der vorher berechnete ‘cooldown’ zugewiesen. Die Funktion wird dann erst nach Ablauf der Zeit das nächste Mal ausgeführt.
> return if winner.blank? || winner.deleted? || winner.banned?
Sollte kein Gewinner ermittelt werden können, weil er nicht existiert oder die letzte geschriebene Nachricht von einem gelöschten oder gebannten Nutzer stammt, wird die Funktion hier abgebrochen. ‘return’ kann mehrere Funktionen annehmen, hier wird es nur genutzt, um die Funktion abzubrechen, ohne, dass sie mehr gemacht hat, als das nächste Schweinchen zu berechnen.
> piglet_type = Gemstone::TYPES.sample
Hier wird ausgewählt, welches Schweinchen erscheint, indem ein Edelsteintyp per Zufall gewählt wird.
> winner.or_orthonym.gemstones.create(type: piglet:type, level: 1)
Dem Gewinner (und wenn es ein Pseudonym ist, dann dem Originalaccount) wird der gewonnene Edelstein in die Schatzkammer gelegt.
> message = conversation.messages.create(
user_id: User::TEAM[“fairies”][“takaro”],
type: “piglet”,
dice: piglet_type,
plain_content: winner.username
)
Das sieht komplizierter aus, als es ist.
In der Taverne wird eine neue Nachricht erstellt. Da jede Nachricht einen Absender braucht, dem die Nachricht zugeschrieben wird, wird dafür Takaro eingesetzt.
Der Typ der Nachricht ist ‘piglet’. Normalerweise würde da wahrscheinlich ‘user’ oder ‘normal’ stehen, wenn ich raten müsste.
‘dice’ übernimmt den Schweinchentyp, der vorher berechnet wurde. Ich nehme an, dass diese Option normalerweise für die Würfel, Münzen und Pfeile benutzt wird um darüber den ausgewählten Würfel/Münze/Pfeil anzuzeigen.
‘plain_content’ ist dann das, was normalerweise das Ergebnis für einen Würfel/Münz/Pfeilwurf darstellt. Hier ist es der Username, der vorher ermittelt wurde.
> message.notify!
Die Nachricht wird versendet.
> end
Die Funktion ist hier beendet.
Also, wie ihr seht: Alles Zufall, niemand wird bevorzugt. Nicht einmal die Feen wissen, wann das nächste Schweinchen auftaucht.
Ich hoffe, ich konnte ein wenig Klarheit schaffen. Fröhliche Schweinchenjagd!
Autor: Lyndis