"Zufälliges", reproduzierbares Füllen eines Arrays

Für allgemeine Fragen zur Programmierung mit PureBasic.
Benutzeravatar
freedimension
Admin
Beiträge: 1987
Registriert: 08.09.2004 13:19
Wohnort: Ludwigsburg
Kontaktdaten:

"Zufälliges", reproduzierbares Füllen eines Arrays

Beitrag von freedimension »

Ich brauche eine schnelle Funktion welche mir zufällig Werte zwischen 0 und n für eine X/Y-Koordinate zurückgibt. Dabei soll der Wert allerdings reproduzierbar sein und nicht von der Größe des Arrays abhängig sein.

Ich habe schon folgendes, aber da sind teilweise immer noch zu viele Gruppen gleicher Zahlen drinnen, je nachdem was für einen Modulo-Wert ich einsetze :(

Code: Alles auswählen

Dim a.l(20)

a(0) = 5
a(1) = 8
a(2) = 117
a(3) = 142
a(4) = 17
a(5) = 204
a(6) = 31
a(7) = 62
a(8) = 8978
a(9) = 108
a(10) = 8
a(11) = 723
a(12) = 1
a(13) = 1563
a(14) = 174
a(15) = 29
a(16) = 845
a(17) = 215
a(18) = 725
a(19) = 234

OpenConsole()

For y = 0 To 20
  For x = 0 To 40
    d = x + y * 10997
    d = a(d%20)
    d % 2
    Print(Str(d))
  Next
  PrintN("")
Next


Input()
CloseConsole()
Wie gesagt, sollte für Echtzeit (Spiel) geeignet sein. Sinn und Zweck ist es zufällige Bodentiles ein und desselben Typs in einer Tileengine darzustellen. Dadurch lässt sich dann evtl. eine störende Musterbildung durch Wiederholung vermeiden.

Wenn jemand was besseres zustande bringt wäre ich echt happy.
Bitte mindestens mit % 2 und % 3 testen.
Beginne jeden Tag als ob es Absicht wäre!
Bild
BILDblog
Benutzeravatar
Zaphod
Beiträge: 2875
Registriert: 29.08.2004 00:40

Beitrag von Zaphod »

da random abhängig vom seedwert immer die selben zahlen liefert, kannst du das sogar mit random machen:

Code: Alles auswählen

RandomSeed(42)


For i=0 To 20
  Debug Random(255)
Next

Debug "-------"

RandomSeed(42)

For i=0 To 20
  Debug Random(255)
Next
Benutzeravatar
freedimension
Admin
Beiträge: 1987
Registriert: 08.09.2004 13:19
Wohnort: Ludwigsburg
Kontaktdaten:

Beitrag von freedimension »

Zaphod hat geschrieben:da random abhängig vom seedwert immer die selben zahlen liefert, kannst du das sogar mit random machen:

Code: Alles auswählen

RandomSeed(42)


For i=0 To 20
  Debug Random(255)
Next

Debug "-------"

RandomSeed(42)

For i=0 To 20
  Debug Random(255)
Next
OK, weiteres Kriterium: Random Access, d.h. freier Zugriff auf jedes einzelne Element. Desweiteren wäre es so auch nicht unabhängig von der Breite des Spielfeldes.
Beginne jeden Tag als ob es Absicht wäre!
Bild
BILDblog
Kaeru Gaman
Beiträge: 17389
Registriert: 10.11.2004 03:22

Beitrag von Kaeru Gaman »

noch eine andere möglichkeit:

deine tiles haben ja koordinaten (logischerweise)

nehmen wir mal an, du hast 16 verschiedene grastiles, in den sprites 0-15

dann berechnest du das anzuzeigende mit:

Code: Alles auswählen

SprNr = (TileX * TileY) & 15
für jedes tile in der map liegt also fest, welches aus der gruppe angezeigt wird,
durch die multiplikation sollte es doch relativ unregelmäßig sein.

kann man zur laufzeit ausführen, und muß kein extra-array mit sich rumschleppen.

wenn das noch zu regelmäßig ist, die formel ein bißchen aufpeppen:

Code: Alles auswählen

SprNr = (TileX * TileY / (TileX + TileY)  ) & 15
...nur als beispiel, laß dir was einfallen.
hoffe, das prinzip ist verständlich erklärt.
Der Narr denkt er sei ein weiser Mann.
Der Weise weiß, dass er ein Narr ist.
Benutzeravatar
Zaphod
Beiträge: 2875
Registriert: 29.08.2004 00:40

Beitrag von Zaphod »

das ist doch kein problem, dann füllst du dein 2d array mit random werten.

Code: Alles auswählen

RandomSeed(42)


Dim Map.l(20,20)

For x=0 To 20
  For Y=0 To 20
    Map.l(x,y)=Random(255)
  Next
Next

Debug "-------"

RandomSeed(42)


Map.l(20,20)

For x=0 To 20
  For Y=0 To 20
    Map.l(x,y)=Random(255)
  Next
Next
führt zu zwei identischen zufälligen karten.
Benutzeravatar
Zaphod
Beiträge: 2875
Registriert: 29.08.2004 00:40

Beitrag von Zaphod »

wenn du nur musterbildung verhindern willst, dann google mal nach "Wang Tiles"
Benutzeravatar
freedimension
Admin
Beiträge: 1987
Registriert: 08.09.2004 13:19
Wohnort: Ludwigsburg
Kontaktdaten:

Beitrag von freedimension »

Kaeru Gaman hat geschrieben:

Code: Alles auswählen

SprNr = (TileX * TileY) & 15
Öhm, dann hätte also die nullte Zeile (bzw. Spalte) immer komplett denselben Wert.

Code: Alles auswählen

SprNr = (TileX * TileY / (TileX + TileY)  ) & 15
Division durch Null? Böse, böse ;)
...nur als beispiel, laß dir was einfallen.
Hab ich ja schon. Wenn du meinen Code von oben gelesen hättest wüsstest du auch, dass wir im Prinzip denselben Ansatz haben, nur bei mir sind die Formeln schon etwas besser ;) Ich will aber eine noch bessere Formel.

@Zaphod: Die Wang Tiles sind interessant :allright: aber nicht ganz das was ich brauche. Mir geht es weniger um den Übergang der Tiles (diese sollen durchaus als einzelne Tiles erkannt werden) sondern um das Gesamtmuster das entsteht wenn alle Tiles denselben Aufbau (Helligkeit(-sverteilung)) haben.
Beginne jeden Tag als ob es Absicht wäre!
Bild
BILDblog
Kaeru Gaman
Beiträge: 17389
Registriert: 10.11.2004 03:22

Beitrag von Kaeru Gaman »

ok, hascht ja recht...

war arg beschäftigt, hab nur mal schnell meine 2ct. dazugegeben....
Der Narr denkt er sei ein weiser Mann.
Der Weise weiß, dass er ein Narr ist.
Benutzeravatar
freedimension
Admin
Beiträge: 1987
Registriert: 08.09.2004 13:19
Wohnort: Ludwigsburg
Kontaktdaten:

Beitrag von freedimension »

Hab jetzt etwas programmiert was gut genug für mich erscheint:

Code: Alles auswählen

Dim a.l(10, 10)
Restore PseudoRandomPattern
For y = 0 To 9
  For x = 0 To 9
    Read a(x, y)
  Next
Next

OpenConsole()

For y = 0 To 19
  For x = 0 To 19
    d = a(x%10, y%10) % 7 ; Anstatt der 7 kann hier auch ein anderer Modulo stehen
    Print(Str(d))
  Next
  PrintN("")
Next


Input()
CloseConsole()

DataSection
PseudoRandomPattern:
Data.l 14, 5,22,23,24,25,26,27,28,16
Data.l 16,13,21,20,23,22,25,26,30,17
Data.l 17,26,17,19,20,21,24,27,13,14
Data.l  3, 4, 5,18,26,13,25,26,17,15
Data.l  6, 7,32,13, 9, 7, 8,23,18,16
Data.l 32, 8, 9,10,11,30, 9,24,19,20
Data.l 15,43,42,13,12,11,10,23, 7,21
Data.l 31,44,41,15, 9, 7,21,20, 8,22
Data.l 21,43,19,16, 5,53,22,12, 9,23
Data.l 45,42,18,17,18,20,21,11,10,21

EndDataSection
Beginne jeden Tag als ob es Absicht wäre!
Bild
BILDblog
Antworten