Jump to content
Unity Insider Forum

Random zahl nur einmal verwenden


erixx

Recommended Posts

Hi, ich würde gerne folgendes umsetzen:

Es gibt verschiedene Händler, die sich aus einer Liste random ints (Item IDs) herauspicken.

Danach muss die ID aus der Liste gestrichen werden, damit ein anderer Händler nicht das gleiche Item ver/kauft.

 

Nun soll sich nach einer Weile die ID wieder random ändern, also muss eine neue ID herausgepickt werden. Müsste ich die alte ID dann wieder in die Liste einfügen, damit sie für die anderen Händler wieder zur verfügung steht?

 

Jeder Händler (es gibt 3-10) zieht sich 1-10 ids aus dieser Liste. Und die IDs sollen sich alle paar Minuten ändern.

 

 

Macht das mit der Liste Sinn?

LG

Link zu diesem Kommentar
Auf anderen Seiten teilen

Hi, also die Liste ist nicht die Item ID selber, nur eine Auflistung, noch freier IDs, die dann den Item IDs entsprechen.

 

Jeder Händler soll sich noch freie IDs aussuchen, die dann aus der Liste gestrichen werden.

Der nächste Händler kann sich dann welche aus den noch verbleibenden IDs aussuchen usw.

Nach einer Weile sollen sich die Sortimente der Händler ändern, dh, sie sollen andere Waren verkaufen/kaufen.

 

So würden sie sich dann neue IDs raussuchen, und gegebenfalls ihre alten IDs wieder in die Liste mischen, damit sie für andere Händler wieder zur Verfügung stehen würden.

Möchte damit ein wenig das Handelsgeschick/lust des Spielers erwecken, so haben verschiedene Händler zum Teil gleiche/andere Waren, doch zu unterschiedlichen Preisen, je nach Ruf usw.

Auch sterben die Händler ab einem gewissen Alter, und werden von neuen ersetzt, so müssten die IDs wieder frei werden. So sucht sich der Spieler lieber junge Händler aus, da er bei denen seinen Ruf mehr erhöhen kann. Doch alte Händler haben meist bessere Preise.

Auch werden von den Händlern Quests vergeben usw.

Stirbt der Händer, wird die Quest abgebrochen.

Aber das tut hier nichts mehr zur Sache ;)

Und das Sortiment ändert sich auch, so muss der Spieler hin und wieder den Markt nach verschiedenen Händlern durchforsten, wenn er etwas spezielles vk/kaufen möchte.

 

LG

Link zu diesem Kommentar
Auf anderen Seiten teilen

Ich finde die ganze beschreibung auch eher verwirrend. Ich vermute aber mal das mit "ID ändern" nicht gemeint ist das sich die ID selber ändern sollte, sondern das damit gemeint war das jeder Händler alle x minuten einfach über zufällig neue IDs verfügen soll. Wenn doch damit gemeint war das sich die IDs selber ändern sollten. Äh nein, finger weg von so einem Blödsinn.

 

Zu der Frage ob es Sinn macht, dafür müsstest du überhaupt erstmal beschreiben "was du tun willst". Derzeit beschreibst du eher "wie du etwas tun willst". Klar kannst du hingehen und eine liste von ids haben, jeder händler kann sich zahlen daraus nehmen, die kannst du wieder zurück geben. Ob das Sinn macht. Das hängt davon ab "was" du tun willst. Und wenn der unterschied nicht klar ist.

 

Wie/Imperativ: for-loop. Setzte i auf 0, wähle array element, prüfe ob ein condition zustimmt, wenn ja, pack es in ein anderes array, erhöhe i um eins. Wiederhole alles bist du alle elemente von array durchlaufen bist.

 

Was/Declarativ: LINQ-Where. Filtere alle elemente anhand einer Condition.

 

Wie/Imperative beschreibungen sind müll! Und du hast genau solche eine beschreibung. Du hast eine Liste mit IDs? Schön! Und warum hast du die nun genau? Weil du IDs aus der Liste holen willst ist keine brauchbare beschreibung. Machen kannst du das so wie du es beschreibst, vielleicht ist das auch der beste weg, aber ohne eine genauere beschreibung eines "Was" du tun willst kann man eine Frage ob es "Sinn ergibt" nicht wirklich beantworten.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Erstell dir eine Liste, welche so viele Einträge hat wie die Anzahl deiner Items. Die Einträge vom Typ int haben dann den Wert der jeweiligen IDs deiner Items. So bald du deine Liste initialisiert hast mischst du diese. Dann kannst du einfach durch deine Liste iterieren und einfach nach der Reihenfolge die IDs an die Händler verteilen. Beim erneuten Verteilen wird die Liste natürlich wieder gemischt.

 

Hier gibt es ein paar Lösungsvorschläge zum Implementieren einer Mischfunktion.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Genau, die ID an sich soll sich nicht ändern.

Jeder Händler soll zufällige Zahlen von den IDs auswählen, und kein anderer Händler soll zu diesem Zeitpunkt die gleichen IDs haben.

Darum dachte ich, ich setze eine Liste auf, die der Länge der IDs entspricht. Bei jedem Auswählen einer ID würde die ID aus dieser Liste gestrichen werden, damit der nächste Händler nicht die gleiche ID zieht.

Und yep, nach ein paar Minuten sollen sich die ausgewählten IDs ändern, wieder so, dass kein Händler die gleichen IDs hat.

Und die IDs sollen wieder in die Liste gepackt werden, sobald ein Händler sie nicht mehr "braucht".

Die Händler ziehen zu unterschiedlichen Zeitpunkten IDs aus der :Liste, so weiss ich nicht, ob ich die Liste an sich mischen sollte, oder nur die bereits vergebenen IDs daraus entferne und per random aus dieser verbleinbenden Liste auswählen lasse.

 

Das beschreibt wohl ein wenig was und wie ich es tun möchte.

Mal ein kleines Beispiel:

 

Liste (1,2,3,4,5,6,7,8,9);

 

Händler 1 zieht 3, 4

Liste (1,2,5,6,7,8,9);

 

Händler 2 zieht 1,5,8

Liste ( 2,6,7,8)

 

Händler 3 zieht 8,2

Liste (6,7)

 

Mit ganz einfachem Random.Range würde jeder Händler evtl mehrmals die gleiche ID ziehen, und verschiedene Händler hätten auch gleiche IDs. Das möchte ich vermeiden.

Doch vielleicht gibt es aber auch eine andere Möglichkeit, zufällige Zahlen nur einmal vorkommen zu lassen.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Ich würde das anders machen. Was vielleicht auch einfacher ist.

Steck alle handelbaren Idems in eine Liste (GameObject, oder GameObject mit Script "Item")-> List<Gameobject> oder List<Items>.

 

Jeder Händler hat eine Liste oder auch nur ein Feld mit dem gleichen Typ.

 

Szenariobeschreibung:

 

Ich kaufe bei Händler 1 eine Limo-> die anderen Händler(beliebig viele) dürfen das Item dann quasi nicht verkaufen.

Codeabfolge beschrieben:->

1. Gebe Spieler Limo

2. Schreibe bei allen anderen Händlern in die Liste oder überschreibe nur das Feld das die das Item(Limo) nicht verkaufen dürfen.

 

Ich komme zu Händler 42

Codeabfolge beschrieben:

1. Liste den Spieler alle Items außer das aus dem Feld oder die Items die sich in der Liste befinden. ->fertig

 

So würde ich das machen. Kein ID geändere oder sonst was für Code-Fasching. Falls deine Items eine ID brauchen, nehme ein Skript und vergebe da via int ID's nach einem Konzept oder nach einer Reihenfolge oder was auch immer.

 

// Edit: der Text steht eigentlich noch über deinem. Du hast nur schneller geschrieben

Link zu diesem Kommentar
Auf anderen Seiten teilen

Okay soweit ich das richtig verstanden habe, würde es folgende Möglichkeiten geben:

1. Möglichkeit:

 

Liste = 1,2,3,4,5,6,7,8,9

Händer 1 zieht daraus random, zB

5,3,7

 

Liste = 1,2,4,6,8,9

 

Händler 2 Zieht daraus wieder random, zB

9,1,6,

Liste = 2,4,8

 

Händler 3 Zieht daraus dann

4,2,8

Liste = leer;

 

2. Möglichkeit:

 

Liste = Random ( 7,5,4,3,6,8,1,9,2)

 

Händler 1 Zieht fest daraus die ersten 3.

 

Händler1 : 7,5,4

 

Händler 2 Zieht daraus die nächsten 3

 

Händler 2 : 3,6,8

 

Händler3 Zieht daraus die letzten 3

 

Händler 3: 1,9,2

 

Liste wird Random gemischt usw.

 

Das Problem an dieser Möglichkeit ist, wenn Händler 1 zB stirbt, wird er ersetzt, dann kommt ein neuer Händler, die Liste wurde schon gemischt, und nun zieht dieser neue Händler da wieder die ersten 3, die könnten aber die gleichen IDs sein, wie die alten IDs, die Händler 2 und 3 noch besitzen, da sie noch keine neu gemischten IDs gezogen haben.

Ich hoffe, ich schreibe nicht zu verwirrend :D

LG

Link zu diesem Kommentar
Auf anderen Seiten teilen

Ist eigentlich gar nicht so schwer zu verstehen mit den IDs, wenn man versteht dass man repräsentativ mit den IDs arbeiten will und nicht direkt mit den Items.

 

Zu deinem Problem:

Du kannst dir eine Int Liste erstellen, die all deine freien und verfügbaren IDs beeinhaltet

(List<Int> freeIDs = new List<Int>() ; <- benötigt "using System.Collections.Generic")

 

Mit freeIDs.Add oder freeIDs.Remove kannst du nun die IDs hinzufügen oder entfernen.

Auf die i-te Position kannst du dann mit freeIDs zugreifen (wie bei einem Array)

 

Um zufällig nun IDs auszuwählen benutzt du nun wie du schon anfangs dachtest Range.Random, allerdings benutzt für die möglichen Werte (0, freeIDs.Count - 1)

Damit erhältst du eine zufällige Position in der Liste. Diese ID liest du nun aus und entfernst die ID an dieser Position, so verhinderst du dass diese ID wieder verwendet wird, da diese nicht mehr in der Liste ist.

 

Wenn IDs wieder hinzugefügt werden sollen, dann benutzt einfach wieder Add()

 

Ich hoffe du kannst der Beschreibung folgen und es selbst ausprobieren ;)

Link zu diesem Kommentar
Auf anderen Seiten teilen

Okay, also jedes Item hat eine ID (0-140).

Die Items mit ihren IDs und all ihren Stats werden in einer ItemDatabase Klasse festgehalten.

Die Liste hier hat die gleiche Länge wie die ItemDatabase, also geht von 0-140.

Nun verkauft Händler 1 zB item 35, dann wird item[35] aus der itemDatabase Klasse abgerufen ( die Stats, Name, Beschreibung, usw) angezeigt, der Itempreis wird vom Spieler abgezogen, und item[35] wird dem Spieler in das Inventar gelegt,/aus dem HändlerInventar entfernt.D ann muss item 35 aus der Liste gestrichen werden, damit Händler 2 alle items ausser item 35 verkaufen darf.

Die Liste an sich sagt nur, welche int (id) noch frei sind.

 

Also die int in der Liste beziehen sich auf die ID in der itemDatabase

Und wenn ein neues Item zur itemDatabase hinzugefügt wird, geht die von 0-141, die Liste wird dann auch auf 0-141 erweitert.

Dann kann Händler aus der erweiterten Liste auswählen.

Sprich, die ID / int sagt, welches Item verwendet wird.

Link zu diesem Kommentar
Auf anderen Seiten teilen

So richtig ein "was" ist es immer noch. Um mal ein "was" zu generieren was ich mir gerade vorstelle was du machen möchtest, basierend aus deinen anderen Threads und Fragen die du gestellt hattest so denke ich mir derzeit folgendes.

 

Du möchtest einen haufen von zufälligen gegenständen im spiel haben. Jeder gegenstand soll eine eindeutige ID besitzen. Um sicherzustellen das jeder Gegenstand eine eindeutige ID hat, hast du einen zentralen Manager der alle Items generiert. Du möchtest

nun das jeder Händler in deinem Spiel zufällig items anzeigen. Natürlich soll dasselbe item aber nicht bei mehreren händlern angezeigt werden.

 

Das was du eigentlich nur benötigst ist also eine "Unique ID". Es gibt dafür auch spezielle algorithmen wie eben UUID (Unique Universal ID) damit kannst du einmalige IDs generieren lassen die dann Weltweit einmalig sind. So kannst du z.B: sicherstellen das jeder Händler einfach selber jede x minuten ein paar items generieren kann, und jedes item trotzdem eine einmalige ID verpasst bekommt, auch ohne das du überhaupt einen Manager brauchst.

 

Alternativ kannst du auch einfach einen Manager schreiben der nichts anderes tut als einen immer aufsteigenden long wert zurück zu geben. Deine Händler können dann ebenfalls wieder beliebig items jederzeit generieren und wenn sie z.B. 30 items generieren, dann fragen sie einfach den Manager um die 30 nächste zahlen. Sowas kann schon durch ein simples

 

private static long current;
public static long GetId() {
   return current++;
}

 

auf irgendeiner Klasse implementiert werden. Du kannst aber natürlich auch gleich eine Methode wie "GetRandomItem()" haben, das du einfach aufrufst und dir ein ganzes item inklusive Unique ID generiert und zurück liefert. Sollen deine Hädnler dann sagen wir 30 neue Gegenstände anzeigen, dann rufst du diese Methode eben 30 mal auf. deine bisherigen items die deine händler haben kannst du dann weg werfen.

 

Ehrlich gesagt sehe ich keinerlei grund warum du es so kompliziert machst und über irgendwelche listen ids gehst wo sich dann jeder irgendwelche ids heraus pickt. Kann natürlich sein das du sowas brauchst. Aber du beschreibst viel zu wenig was deine intention genau ist.

Link zu diesem Kommentar
Auf anderen Seiten teilen

....

Ehrlich gesagt sehe ich keinerlei grund warum du es so kompliziert machst und über irgendwelche listen ids gehst wo sich dann jeder irgendwelche ids heraus pickt. Kann natürlich sein das du sowas brauchst. Aber du beschreibst viel zu wenig was deine intention genau ist.

 

Sid beschreibt mein Fragezeichen im Kopf. Falls Du wirklich nur Sicherstellen willst das Händler nicht die gleichen Items haben, brauchst Du keine ID's.

 

Du brauchst:

- Liste aller Items oder schon generierter Items

- Items aller Händler

 

Und dann nach dem einfachen Konzept: Was der eine hat, darf der andere nicht haben.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Hi Sid, die Idee, dass der Händler selber die Items generiert,ist an sich nicht schlecht. Doch er soll auch aus einem vorhandenen Itempool die IDs abfragen (die schon von einem Generator erzeugt wurden bzw ich vorher manuell erzeugt habe).

ZB Händler kauft Materalien mit der ID 344. Das ist in diesem Beispiel Stein.

Nun schaut der Spieler ob er Item ID 344 besitzt, wenn ja, kann er es verkaufen ( da Händler item id 344 kauft),

Würde der Händler selbst Material mit ID 345 erzeugen (und kaufen), gäbe es dieses Material noch nicht.

Eine Steinressource hätte nicht die id 345, so müsste ich die Ressourcen Materialien mit zufälligen IDs abbauen lassen. Aber im Moment haben Ressourcen feste IDs. Sprich ein Steinhaufen fügt Item mit ID 344 in das Inventar hinzu, da Material 344 Stein ist ( von mir vorher festgelegt).

Es gibt in meiner Database zufällig erzeugte Items, die einfach hinzugefügt werden, aber es gibt auch feste Items, die ich voher konfiguriere.

 

Wenn zB ein item erzeugt wird, sagen wir ein Schwert mit einer neuen ID, dann wird diese ID zum Itempool hinzugefügt. Dh, Item.length+1 wäre der neue index, somit auch die neue ID.

Der Händler hätte direkten Zugriff auf diese neu erzeugte ID, in dem er aus der Liste(1,Item.length) per Random zufällig auswählt. Und das eben im An- und Verkauf.

Dann aber gibt es auch Materalien, die feste IDs haben, so könnte der Händler anhand dieser Liste auch diese Materalien wählen, da sie auch in der Liste + Database vorkommen.

So in etwa das Prinzip:

Händler[index];

index=Random.Range(1-10);

Händler [index] verkauft (1-10) Gegenstände;

 

Händler[index].Gegenstand .art = random.range(useable,equip,material)

 

Händler[index].Gegenstand.id=random.range (1,usable[id].length//1,equip[id].length//1,material[id].length); <= und da kommt die Liste ins Spiel,damit die ausgewählte ID nicht bei Gegenstand[i++] vorkommt.

 

Und das selbe auch beim Ankauf.

 

Gillt für jeden Händler.

 

Dh, jeder dieser (1-10) Gegenstände soll beim Händer selber im An-Verkauf nicht doppelt vorkommen und auch nicht bei den Händlern untereinander.

Darum dachte ich mir, ich erstelle eine Liste, von der alle ausgewählten IDs entfernt werden.

 

Doch im Sellmodus vom Händler könnte ich natürlich neue Items (Equipment) erzeugen lassen, das ist eine gute IDee ;)

Liebe Grüße und ein schönes Wochenende!

 

 

Edit: Das mit den Listen funktioniert auch wunderbar, ich dachte nur, ich versuche zu erklären, warum ich die Methode mit den Listen ausgewählt habe.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Der Sinn darin liegt, dass oft Daten, die nicht häufig verwendet werden auf der Platte liegen, damit diese nicht den RAM vollhauen mit Daten die man nicht braucht was die Leistung verringern kann.

 

In diesem Fall ist es sinnvoll sich eine Liste der IDs zu machen (als eine Art Referenz) und gegebenenfalls das Item zu laden und besser als durchgängig alle Items im Arbeitspeicher zu haben (Diese Items haben dann zB verschiedene Werte wie preis , Effekt , Typ, usw ; die Liste nur die id)

Link zu diesem Kommentar
Auf anderen Seiten teilen

....

In diesem Fall ist es sinnvoll sich eine Liste der IDs zu machen (als eine Art Referenz) und gegebenenfalls das Item zu laden und besser als durchgängig alle Items im Arbeitspeicher zu haben (Diese Items haben dann zB verschiedene Werte wie preis , Effekt , Typ, usw ; die Liste nur die id)

 

Was? Um RAM zu sparen? Die Variante ist nicht sparsamer. Hier erzeugst Du zusätzlich noch ID's (integer) um ein Objekt zu erkennen. Bei der von mir beschriebenen Variante speicherst Du die Referenz auf das Objekt und nicht nochmal zusätzlich das Objekt.

 

!!! Wenn Du ein Objekt in eine oder mehrere Listen packst, dann speicherst Du eine "Art" Referenz !!! ->Es ist die Referenz!

 

Ich will jetzt nicht wie ein Erbsenzähler klingen, aber ich glaub für das Game müsste er eine Kombinatorik an Items erfinden, wofür er mindestens 10 Jahre braucht, um den RAM mit 500 MB zu belegten(soll nur Ironisch klingen)

 

Wie gesagt, wenn er die ID's brauch, okay. Das es anders geht wurde erwähnt. Was er daraus macht muss er selber wissen.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Hi Bemmi, also ich persönlich finde das mit den IDs übersichtlicher, ich habe für alles IDs, für Skills, Feinde, Händler, Quests, Ressourcen usw. So kann ich per script schnell auf eine ID zugreifen, und das entsprechende Item/whatever verändern/aufrufen/erstellen/löschen usw..

Aber es ist auch gut, dass es mehrere Möglichkeiten gibt. :)

LG

Link zu diesem Kommentar
Auf anderen Seiten teilen

Hi,

jo wie gesagt, kann ja jeder machen wie er will. Von meiner Seite her nutze ich lieber erst die Vorteile die mir Programmiersprache bietet.

 

Nur noch so als Info:

Wenn Du Items, Skills, Händler usw in jeweilige Listen speicherst, wo sich die Reihenfolge nicht ändern soll, aber die Listen wie Du es brauchst erweiterbar sein sollen, kann wäre der Index der Liste eine sinnvolle ID.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Ganau so hab ich es gemacht. :) Und wenn eine ID wieder frei werden soll, wird sie auf 0 gesetzt, so kann eine neue ID an dieser Stelle erzeugt werden. So würde sich die Reihenfolge nicht ändern, aber die Liste würde immer größer werden, falls keine 0 darin vorkommen. LG

Link zu diesem Kommentar
Auf anderen Seiten teilen

Archiviert

Dieses Thema ist jetzt archiviert und für weitere Antworten gesperrt.

×
×
  • Neu erstellen...