Extended am Sonntag #11
Karten und Würfel
Heute geht es um eine häufig vorkommende Frage: Wie kann man Würfel oder das Ziehen von Karten aus einem Kartenstapel modellieren?
Man ahnt es vielleicht schon, es wird um Zufallswerte gehen.
Würfel erzeugen unabhängige Zufallsereignisse. Wenn ich mehrmals würfle, hat das Ergebnis nichts mit den vorherigen Würfen zu tun. Selbst bei einem gezinkten Würfel ist das so, auch wenn dort nicht alle Ergebnisse gleich wahrscheinlich sind. Münzwürfe fallen auch in diese Kategorie.
Im Gegensatz dazu entstehen beim Kartenziehen abhängige Ergebnisse. Wenn ich in einem normalen 32-Karten-Blatt einmal das Pik As ziehe, kann die nächste Karte sicher kein Pik As mehr sein. Beim Lotto ist es ähnlich.
Überlege also zuerst, in welche Kategorie deine zufälligen Ereignisse passen könnten.
Einmal Würfeln, gleiche Chancen
Wenn man „nur“ würfeln möchte, hat Extended das passende Werkzeug: Inventar > Würfeln.
Hier kannst du einstellen, wie gewürfelt werden soll. 1d6
steht z.B. für den klassischen, sechsseitigen Würfel, 1d100
entspricht dem /würfeln
-Makro. Das Würfelergebnis wird auf dem Bildschirm ausgegeben. Optional kannst du das Ergebnis in eine Variable speichern.
Wenn das Ergebnis keine Zahl, sondern eine zufällige Begrüßung, ein zufälliger Soundeffekt, o.ä. sein soll, benutzt man einen Trick: Jedes mögliche Ergebnis bekommt eine Nummer. Dann würfelt man die Nummer aus und voilà.
Hierzu sollte man Experte > Dynamischer Wert > Zufallswert einsetzen, denn wir sind nicht am Ergebnis selbst interessiert (der Zahl), sondern dem zugewiesenen Ereignis.
Eine ausführliche Beschreibung zum Erstellen einer Wurfmünze findet ihr hier: [Guide][Wiki-Beitrag] How-To Total RP 3 Extended ❔ - #4 von Enestress-die-aldor .
Das folgende Beispielitem gibt die Worte „EINSicht“, „AbZWEIgung“ oder „RunDREIse“ aus, jenachdem wie man gewürfelt hat. Das Grundprinzip ist immer das selbe: Erzeuge im ersten Effekt einen zufälligen Wert und frage ihn danach in den Effektbedingungen der Reihe nach ab.
Wörterwürfel
!9ozuVTjmqC8prRfCGULi1hiatcPoNUCjG2EWjuIxckeycijD7H8XApT36xS()m0TQLSxRWY(8DNV7hN9PSvZusBmSgyPKcfzjSCX4g3HzwXwFujhapOijMBv0SVazSN8zTvLZB0SanJN5yr6UacP8vk6qA9IQVRRtlXM061nDwPv5z6PvffMuEKtcX(uTtjDEHi2gm02)ryuK3G5sfjyfoNNVw9JWqwfsxV6EBDOKTrNTDboFAphhna8hA48WkU92()7d)LGxJ)09LbtdJWppZO9)siwh8MWM4cS59WxtcJwVVC9LHJlFoScXBcI2xaXWijLNTP9)d4RU2xPBtZlA6E)9PaoS(b4DQ71wIRfItlfwJCVzK7qOFmEkQl0h0nVB2M6uGefBECrxWYDt4GJyIvjlhJNWx5CLdqjUVJGOZs1WrqpqXFcJYKi1diejkjCoyUzbnhOctuKICFKfMcb(in6S915T)4oWrHHRXECqUNq6Sh(b0BHJMxEyXU8MSfCDDHLTjvijspfL80VQB11hF631FdHGB8GLp7zk737XBMl55ypdk(t5nbC8f2VhEgACHuJn1eiNyoKVjojH8HAno01K33ItEq8N73DAzsxMlpTSwJBWMTf5zB1LDx9oVuaBvQN)d
Würfeln mit ungleichen Chancen
Wenn ein gezinkter Würfel oder allgemein unterschiedlich wahrscheinliche Ereignisse benötigt werden, kann man sehr ähnlich wie im ersten Teil vorgehen, nur, dass man diesmal den Ergebnisbereich abfragt.
Als Beispiel habe ich eine Schatulle gebaut, die mit 15%-iger Wahrscheinlichkeit ein seltenes Item enthält. Ich habe das Item so konstruiert, dass es nach der Benutzung nicht verschwindet oder „leer“ ist. So könnt ihr den Effekt leichter ausprobieren.
Schatulle
!nx12UTnpm4NO1AlNGGvSnG0KITa060f5KIDJSvSzs0IpuiRCO7c)ySNMDxFXgPSttNtXF)3agWsmKLejf)iP(OfUIaHVl(445i8zcUdZPlZ1L50zAqxZEHVhQbFKpnA0YYv0KPCAKpqWlYNwccJGFzFARB54r5(wxRkZf8bJPr)(c(h1p(J8Y7L5ODKlDWFc(N7BDk)ssT76tJZWTqjdMqlgsNhZ1d18kA9i0LQ8THFf2bPXA5cJkFzypNWLqMdlCPga0b3ApOP(weeyp6ROd1yXCWbuhyHsaUn9NWkUZ4rK(3CNfedNAFrbAh81ibV7EAYeCczInTGVVziz6nJXqDmTo4lOmReTudVEgJXEHmwaOsRI2wKxfnotwf9jvAcuwfnujtGStsJEVAA0Pt70ySUyxEOJ7)sPSJZFrpZPBSCO(AlotLi4BL6WI7bTmhxi1llRLYtuXWKI0u7DSD2uePtrMWVZH79Kmkn2esO3XNuvjoI3Ky0gEN6rLbYcLj4S4c0PnIAKxdO4vq86q8mKnOzNfgpHjYx0gFOHITfvQ7bm8SGOfHSkQMfsM6sMoNcgQAc5Mc9dTJcdfe)nX)7E)VBay5e)FXpvf8owCkH4nAL5HRHTqQTI2MzX7Jt)2MSQOh)(If5asF0q8kt56uv8AS9WF292293oqHMxSpKiwh5T84vsZM0uWEJD(tn5Eof7)Sjhgrx(RK5wmYAUZ1i3H62nGugsXes5BcwPLyTHpt43ZEeNiHpeRiDp3HDoJvfXCVWT3fyR)dmrEYmSUCwNZWqYmR57c8bNye7cmOrOKagPkTSPLavjRn2ie)m
Obwohl es in diesem Beispiel nur zwei mögliche Items gibt, würfle ich von 1 bis 100. Wenn ich eine Zahl zwischen 1 und 15 erwürfelt habe (beachte die Effektbedingung), bekommt der Spieler das besondere Item, ansonsten Schrott. 15 von 100 Würfelergebnissen sind also „gut“, das entspricht den 15%, die ich vorher festgelegt habe. Ich hätte auch 86 bis 100 als „gut“ definieren können, nur die Größe des Bereichs ist hier wichtig.
Karten ziehen
Sobald wir mehr als eine Karte aus einem Deck ziehen, müssen wir etwas tiefer in die Trickkiste greifen. Extended muss sich nämlich irgendwie merken, welche Karten bereits gezogen wurden, oder alternativ, welche noch gezogen werden können.
Bevor ich mich darum kümmere, erstelle ich ein Kartendeck-Item für ein Skatdeck, d.h. ich werde 32 innere Items benötigen. Jetzt könnte ich die 32 Items von Hand erstellen… oder ich baue mir fix ein paar Makros.
Kleiner Exkurs in die TRP3-API
Der folgende Teil ist optional. Ihr könnt die inneren Items auch wie gewohnt erstellen.
/run _A = function(id, name) TRP3_ToolFrame.specificDraft.IN[id] = {TY = TRP3_DB.types.ITEM, MD = {MO = TRP3_DB.modes.NORMAL}, BA = {NA = name}} end
Makro Nummer 1 erzeugt eine Funktion, die ein inneres Item mit vorgegebener Id und vorgegebenem Namen erstellt. Das Item muss dabei in der Datenbank geöffnet sein.
/run _V = {"Sieben", "Acht", "Neun", "Zehn", "Bube", "Dame", "König", "As"} _C = {"Herz", "Pik", "Kreuz", "Karo"}
Das zweite Makro enthält die zukünftigen Namen der Karten.
/run local i = 1 for _, v in pairs(_V) do for _, c in pairs(_C) do _A(("card%02d"):format(i), c .. " " .. v) i = i + 1 end end
Das dritte Makro führt letztendlich meine Einfügefunktion 32 Mal aus. Damit man die Items auch sieht, muss man gegebenenfalls einmal ins Übersichtstab und zurück wechseln.
Zurück zum Deck
Wir haben es also irgendwie geschafft, die inneren Items card01
bis card32
zu erstellen.
Bei einem echten Kartenspiel würde man das Deck zuerst mischen, und dann so viele Karten von oben abnehmen, wie benötigt.
Es gibt aber noch eine andere Methode, die zumindest mathematisch gleichwertig ist: Man beginnt mit einem sortierten Deck. Dann würfelt man von 1 bis 32 und entnimmt die Karte an der entsprechenden Position. Für die zweite Karte würfelt man von 1 bis 31 usw.
Diese Methode werde ich vorstellen. In meinem Beispiel soll folgendes passieren:
- „mische“ den Stapel, d.h. sortiere alle Karten
- entnehme bis zu 5 Karten
- nachdem 5 Karten entnommen wurden, entferne alle gezogenen Karten aus dem Spielerinventar und mische neu
Kartendeck
!DEv4YnQnq43f3PZKmtQpHSVCjE69dsSN5CsoSRfoPT)qgmOeRAmCJqKEx6uES6lqFX6kjigi1tL7yhzqR(0(PD3Vfc1H6t9CGVObiQhMsqy05ieC7qIJxro1BaScYup1yuOigRqq(8y94mkXBgvsj()cSgyMRCvZ75sjFIjEPmyC4ogyxwHfBh258TDHcSZEOU57b6yjFVvWkac7XksB41JdCt)IFVDqnXPB)7)kL)udwBj6kh)RSnnyn(C7aRJvVXZwMJUnuK1nCHV0oSMZCRS0XKEB7uNHhb02bQbh1zTfF)GDinN0Rkw3OugDHDyR8A0gzdSw636cYwGDSm9ubUnRDSSOYW6ofKdSeRXXTv(iTgCjrnsUMsYsxMRmxH7ExQhcS4txtj)KRQzgzUR6MLEQX5eykNloNsEqp71l02iQXXkBy0aa4eTTzQrYvQX9zpcNTMLcw1U4Hjk)j1CXVMn(Ac4tRc2W(aZmBQA9F(bn)gV0qt4ame(zkL8(VQUybCHcIUbR8GbP6yHLjbtxWwjF8Xv50TTa64sHvXS9vpwwZRjE7cpSLTgmfEDKAw2gTQHuB1ILNyd22f8il7jz4C3GfYY2s6GvxWylJ0gx3nnJpkI3rOAz7fta71M4VQKnk1lXA15v1QXkVjzPXSOTnf64APQryx1iWOVRu2xwRSNc6UWOnC2ZSDSu5QNk4jXFHj2Ukjm(BjfQDUzxdl06eDFj19E6R4XusEKG)fy9HINYngijzrHjLbx7Uy8Q5U((tw4vg8XYGEDErRYavm87r44EL3OW3pB9VXIK9FouKRr82jZeLb)XFwEd)XYG0m5BxsFvmZSUV7a2(ryNXFOmqUHLwEtzWb3KpA8LAfpQ2qUEkNZgGldIZmguFyp(iG8KECjB3kbBx2ZSENz21ZAhhgb7ZUq5j8tbdoie6097ImCDcRppnNjKN8VYiadVcauBuDrLVLSVkB40EJ5mOwxxfvg87fIy1VPSIYGNy745GUVVA5oW(XsYzMnRkZj0NtGNB6lctJZ2DIZzhkCEAlKQeQgS5WyIfh8WioT9zqh)cJJ)pcEkNOJFWFyf)tJRLvW3eEUKw)HeZKH8KCDj8KRxTyIlzM3kqYmDUFv5A3x)xJ7UPkiZw24HVgzozmG483HWVddvbooJqdhHvIqq(syjGAl)h83ictsa9jOyVam1cccnYbnAa8KW7GogQNYkVV6Fgr3dzYpRf5VzZIVh0F9h2FOIl)pEC7NuDCA0DQ7RxqCHlfmOWiFBcpAllfcVf7GSdpTUuQm4fOa6foBJU)ljNfvi4YVDhW0evWus9gUNM0)5
Das ganze funktioniert mit einem Lua-Skripteffekt. Ich habe das Skript kopiert und Zeilennummern hinzugefügt, damit ich jede Zeile einzeln erklären kann. Wenn ihr den Code weiterverwenden wollt, müsst ihr die Zeilennummern löschen.
01 local CARD_PATTERN = "0206001034S1Nus card%02d"
02 args.object.vars = args.object.vars or {}
03 if not args.object.vars.deck or #args.object.vars.deck <= 27 then
04 args.object.vars.deck = {}
05 for i = 1,32 do
06 effect("item_remove", args, CARD_PATTERN:format(i), 1000)
07 table.insert(args.object.vars.deck, i)
08 end
09 effect("text", args, "Die Karten wurden neu gemischt.", 1)
10 else
11 local r = math.random(1, #args.object.vars.deck)
12 local card = table.remove(args.object.vars.deck, r)
13 effect("item_add", args, CARD_PATTERN:format(card), 1, 2)
14 end
Zeile 1
Hier speichere ich die Id einer Spielkarte ab %02d
steht als Platzhalter für die Kartennummer. Der erste Teil ist die Id des Kartendecks. Wenn ihr ein eigenes Item baut, müsst ihr diese entsprechend ändern.
Zeile 2
Mit args.object.vars
habe ich direkten Zugriff auf die Objektvariablen. Ich muss getVar
nicht verwenden und in diesem Fall könnte ich es auch gar nicht, denn meine Variable deck
wird eine Tabelle enthalten. Dieser Fall wird von getVar
nicht richtig behandelt.
Diese Zeile übernimmt den Fall, dass es noch keine Variablen im Objekt gibt (also Initialisierung).
Zeile 3
Hier prüfe ich, ob mein Deck gespeichert wurde, und wenn ja, wieviele Karten noch darin sind. Es muss gemischt werden, wenn die Variable deck
nicht existiert oder 27 oder weniger Karten im Deck sind.
Zeile 4
Bevor ich mische, lege ich einen leeren Kartenstapel an.
Zeile 5
Ich betrete eine Schleife über alle meine 32 möglichen Karten.
Zeile 6
Innerhalb der Schleife entferne ich jede Karte aus dem Inventar. Sollte die Karte gar nicht im Inventar liegen, passiert nichts. Als Vorsichtsmaßnahme werden bis zu 1000 Exemplare einer Karte entfernt. Es könnte nämlich sein, dass der Spieler mehrere Decks im Inventar hat und simultan zieht.
Zeile 7
Hier wird die Tabelle mit verfügbaren Karten gefüllt. nachdem das passiert ist, stehen dort einfach nur die Zahlen 1 bis 32 der Reihe nach.
Zeile 9
Ich gebe dem Spieler den Hinweis, wenn gemischt wird, damit sich niemand wundert, warum die ausgegebenen Karten verschwinden.
Zeile 10
Ab hier wird der Fall behandelt, dass eine Karte gezogen werden soll anstatt gemischt.
Zeile 11
Zuerst würfle ich aus (math.random
), welche Karte vom Stapel genommen werden soll. Diese Zahl ist die Kartenposition, nicht die Kartennummer.
Zeile 12
Mit table.remove
entnehme ich die Karte an der zuvor ausgewürfelten Position. In der Variable card
steht jetzt eine Kartennummer.
Zeile 13
Schließlich muss ich noch die Karte ins Spielerinventar legen. Mit CARD_PATTERN:format(card)
erzeuge ich aus der Kartennummer eine Karten-Id.
Uff, so ein Kartendeck zu bauen war dann doch ein ganzes Stück schwieriger als ein paar Würfel. Das liegt daran, dass sich Extended die verfügbaren Karten merken muss. In diesem Fall ist der Lua-Effekt kaum zu vermeiden, denn das ist momentan die einzige Möglichkeit, in Extended Tabellen bzw. Listen zu verarbeiten.
Viel Spaß beim Experimentieren und
bis zum nächsten Sonntag…