2 dimensionales array füllen aber keine gleichen inhalte?wie

Übersicht BlitzBasic Allgemein

Neue Antwort erstellen

 

X-tra

Betreff: 2 dimensionales array füllen aber keine gleichen inhalte?wie

BeitragSa, Jul 19, 2008 9:49
Antworten mit Zitat
Benutzer-Profile anzeigen
also ich möchte 1 zweidimensionales array füllen lassen, sagen wir mit 10 unterschiedlichen werten, mittels Zufallszahl.also array(x,y,zahl) = zufallszahl
wie bei einem schachbrett sozusagen.
ich möchte aber nicht, dass es in der horizontalen und vertikalen 3 gleiche inhalte gibt.
x000000000
x000000000
0000xx0000
0000000000
0000000000
0000000000
0000000000
0000000000
0000000000
0000000000

ist okay aber....

x000000000
x000000000
x000xxx000
0000000000
0000000000
0000000000
0000000000
0000000000
0000000000
0000000000

so soll es nicht sein.

wie könnte man so eine füllmethode hinbekommen.

ich habe vor monaten mal einen code in der art dazu gehabt, den hab ich zwar nun nicht mehr, aber
ich erinnere mich, dass dort dann irgendwie wie in einer endlosschleife ständig alles getauscht wurde, und es irgendwie zu keinem fest etabliertem spielfeld kam.

Xeres

Moderator

BeitragSa, Jul 19, 2008 11:49
Antworten mit Zitat
Benutzer-Profile anzeigen
Den Array erst per Zufall mit Zahlen befüllen und dann testen ob 3 Zahlen hintereinander vorkommen und wenn ja, eine davon ändern. Das wiederholt man so lange bis eben keine 3 Zahlen hintereinander mehr vorkommen.
Win10 Prof.(x64)/Ubuntu 16.04|CPU 4x3Ghz (Intel i5-4590S)|RAM 8 GB|GeForce GTX 960
Wie man Fragen richtig stellt || "Es geht nicht" || Video-Tutorial: Sinus & Cosinus
T
HERE IS NO FAIR. THERE IS NO JUSTICE. THERE IS JUST ME. (Death, Discworld)

Firstdeathmaker

BeitragSa, Jul 19, 2008 12:15
Antworten mit Zitat
Benutzer-Profile anzeigen
Wenn es eine Int-Zufallszahl aus einem festen Bereich sein soll:

(Dieser Algorithmus hat eine lineare Laufzeit, d.h. er terminiert wirklich, im Gegensatz zum stupiden rumprobieren)

Code: [AUSKLAPPEN]
Const Zufallszahlen = 10
Const Hoehe = 10
Const Breite = 10
Const maxNumbers = 3

Dim myArray(Breite,Hoehe) ;dieses Array soll die Bedingungen nachher erfüllen.

Dim array(1,Zufallszahlen)
Dim array2(Zufallszahlen)

fillArray()
printMyArray()




Function printMyArray()
   For y = 0 To Hoehe
      Local s$ = myArray(0,y)
      For x=1 To Breite
         s = s + ","+myArray(x,y)
      Next
      Print s
   Next
End Function

Function fillArray()
   For x = 0 To Breite
   For y = 0 To Hoehe
      setNumber(x,y,getRandNumber(x,y))
   Next
   Next
End Function

Function setNumber(posX%,posY%,number)
   myArray(posX,posY) = number
End Function

Function getRandNumber(posX%,posY%)
   ;Array zurücksetzen
   For i=0 To Zufallszahlen
      array(0,i) = 0
      array(1,i) = 0
   Next

   ;herausfinden welche noch gültig sind, und diese eintragen (zusammenzählen)
   For i = 0 To Breite
      array(0,myArray(i,posY)) = array(0,myArray(i,posY)) + 1
   Next
   
   For i = 0 To Hoehe
      array(1,myArray(posX,i)) = array(1,myArray(posX,i)) + 1
   Next
   
   ;jetzt steht in 'array', für jede Zufallszahl an der position posX,posY, wie viele Male sie
   ;in horizontaler und vertikaler Richtung vorkommt.
   
   counter = 0;wir brauchen einen Counter, weil die Arraynummer
   ;in array2 <> der Zahl die dort gespeichert wird. Dieser counter dient
   ;auch gleichzeitig dazu, nachher zu wissen wie viele Zufallszahlen im
   ;array sind.
   ;jetzt werden alle Zufallszahlen durchgegangen, und für jede Zahl das 'array'
   ;abgefragt, ob diese Zahl in horzontaler und vertikaler Richtung weniger als 'maxNumbers' mal vorkommt.
   ;ist dies der Fall, dann wird die Zahl in 'array2' eingetragen.
   For i=1 To Zufallszahlen
      If array(0,i)<maxNumbers And array(1,i)<maxNumbers ;checken ob in dieser Zeile und Spalte diese Zufallszahl(i) noch nicht dreimal vorkommt
         array2(counter) = i ;Zufallszahl in Hilfsarray eintragen.
         counter = counter + 1 ;counter um 1 erhöhen, da wir gerade eine weitere gültige Zufallszahl dem array hinzugefügt haben.
      EndIf
   Next
   
   Return (array2(Rand(1,counter-1))) ;Aus den gültigen Zufallszahlen eine Zufällige auswählen.
End Function



Achtung. Der Algorithmus ist nicht stabil. D.h. wenn er an eine Position kommt, an der er gar keine Möglichkeit mehr bekommt (weil schon alle Zahlen 2x in er Reihe und Spalte vorkommen), bricht er mit einem Fehler ab. Um das zu umgehen, könnte man vor dem letzten Aufruf in getRandNumber() eine Abfrage machen, ob counter=0, und vorher abbrechen. In diesem Fall müsste man per Backtracking vorgehen (einfach mal bei Wikipedia suchen).
www.illusion-games.de
Space War 3 | Space Race | Galaxy on Fire | Razoon
Gewinner des BCC #57 User posted image
 

X-tra

BeitragSa, Jul 19, 2008 12:29
Antworten mit Zitat
Benutzer-Profile anzeigen
@xerxes: könntest du das in einen code fassen, ich wüßte zwar auch wie, aber mir fällt da spontan nur die möglichkeit ein zu schauen ob eben in einer reihe jeweils 3 gleiche vorkommen, weiß nicht ob das dann durcheinander gerät mit den spalten.

@firstdeathmaker: schönes beispiel was ich nicht wirklich verstanden habe beim kurzen überfliegen, aber das ist glaube ich etwas viel aufwand, nur um ein feld zu spielbeginn zu füllen, oder?

hectic

Sieger des IS Talentwettbewerb 2006

BeitragSa, Jul 19, 2008 13:23
Antworten mit Zitat
Benutzer-Profile anzeigen
Der Code von Firstdeathmaker ist garnicht so aufwendig, er hat dir nur zu 70% auch Kommentare dazu geschrieben. Im Prinzip ist es aber ganz einfach. Solange du so viele (oder nicht mehr) Zahlen schreiben willst, als Spalten oder Zeilen vorhanden sind, dann kannst du es ganz einfach in eine Schleife packen.

Beispiel:

- Dim mit 10x10 Felder ''Dim myArray(9,9)''

- und jeweils eine Zahl pro Zeile haben willst, dann machst du:
Code: [AUSKLAPPEN]
For Y=0 to 9
   myArray(rnd(0,9),Y)
Next


- oder jeweils eine Zahl pro Spalte haben willst, dann machst du:
Code: [AUSKLAPPEN]
For X=0 to 9
   myArray(X,rnd(0,9))
Next


Das ganze geht so lange, bis die gewünschte Zahlenanzahl nicht die Anzahl verfügbaren Zeilen oder Spalten besitzt, da ja logischer Weise dann deine Bedingung nicht erfüllt ist. Soll wiederrum die Zahlenanzahl nicht gleich der X oder Y Dimgröße entsprechen, dann kann auch ganz einfach ein Multiplikator mit der X oder Y -Schleifenvariable gesetzt werden.

Ganz einfach also...
Download der Draw3D2 V.1.1 für schnelle Echtzeiteffekte über Blitz3D
 

X-tra

BeitragSa, Jul 19, 2008 13:30
Antworten mit Zitat
Benutzer-Profile anzeigen
häää nun bin ich total verwirrt.
wieso eine zahl pro spalte oder zeile?
ich möchte schlussendlich ein array mit 9 zeilen und 8 spalten haben.

dieses soll komplett mit zahlen zwischen 1-10 gefüllt werden.
dabei sollen niemals 3 gleiche zahlen in einer spalte, und niemals 3 gleiche zahlen in einer zeile vorkommen.
2 aufeinanderfolgende sind okay.
Nur 3 gleiche dürfen weder in einer zeile noch in einer spalte vorkommen.

hectic

Sieger des IS Talentwettbewerb 2006

BeitragSa, Jul 19, 2008 13:32
Antworten mit Zitat
Benutzer-Profile anzeigen
Sorry, ich hatte dein ersten Post irgendwie falsch verstanden. Mein Fehler. Embarassed
Download der Draw3D2 V.1.1 für schnelle Echtzeiteffekte über Blitz3D
 

X-tra

BeitragSa, Jul 19, 2008 13:45
Antworten mit Zitat
Benutzer-Profile anzeigen
hast du trotzdem eine lösung?

hectic

Sieger des IS Talentwettbewerb 2006

BeitragSa, Jul 19, 2008 13:55
Antworten mit Zitat
Benutzer-Profile anzeigen
Beim weiterem Überfliegen vom Firstdeathmaker's Code sehe ich keine Bedenken seiner Überlegungen. Firstdeathmaker ist ja auch ein hervorragender Programmierer, dem ich auch nichts weiteres hinzufügen muß. Du kannst - meiner Meinung - sein Code bedenkenlos als Grundlage benutzen. Man kan den Code allerdings vereinfachen, wenn man nicht ein ganzes Randomfeld braucht, sondern immer nur eine Zahl nicht mehr als n-fach haben will. Soweit solltest du dann aber versuchen den Code zu verstehen, denn sonst stellst du dir selbst ein Bein beim programmieren.
Download der Draw3D2 V.1.1 für schnelle Echtzeiteffekte über Blitz3D
 

X-tra

BeitragSa, Jul 19, 2008 13:59
Antworten mit Zitat
Benutzer-Profile anzeigen
nein was ich meine ist, das ich schonmal sowas da hatte, war eigentlich total simple, und nur ziemlich wenig code um zu überprüfen das nie mehr als 2 gleiche zahlen nebeneinander oder eben über-untereinander liegen.

das muss doch auch einfacher gehen als beim deathmaker

hectic

Sieger des IS Talentwettbewerb 2006

BeitragSa, Jul 19, 2008 14:17
Antworten mit Zitat
Benutzer-Profile anzeigen
Du brauchst doch nur diese eine Funktion, und wenn du die Kommentare weg machst bleibt folgendes übrig:

Hier unten auf AUSKLAPPEN klicken
Code: [AUSKLAPPEN]
Const Zufallszahlen = 10
Dim array(1,Zufallszahlen)
Dim array2(Zufallszahlen)


Function getRandNumber(posX%,posY%)
   
   For i=0 To Zufallszahlen
      array(0,i) = 0
      array(1,i) = 0
   Next
   
   For i = 0 To Breite
      array(0,myArray(i,posY)) = array(0,myArray(i,posY)) + 1
   Next
   
   For i = 0 To Hoehe
      array(1,myArray(posX,i)) = array(1,myArray(posX,i)) + 1
   Next
   
   counter = 0
   
   For i=1 To Zufallszahlen
      If array(0,i)<maxNumbers And array(1,i)<maxNumbers
         array2(counter) = i
         counter = counter + 1
      EndIf
   Next
   
   Return (array2(Rand(1,counter-1)))
End Function


Diese Funktion setzt nun nur noch die Zahlen, die zulässig sind an gewünschter Stelle. Man setzt also vom Anfang an keine sinnlosen Einträge die anschliessend wieder geändert und möglicher Weise ein anderen Konflikt erzwingen.

Wenn man unbedingt will, könnte man ggf. die beiden temporären Arrays: array und array2 auch in der Funktion durch eine Bank ersetzen, die onthefly in der Funktion selbst erstellt und wieder terminiert wird.

Wenn du meinst, man könnte es noch wesentlich kürzer machen, dann starte doch mal ein Minicontest. Das einzige was mir etwas misfällt sind die beiden temporären Arrays, die ich, wie bereits gesagt, per Banken gelöst hätte. Wink

Edit1: Mir fällt gerade ein, wenn du meinst nur nebeneinander oder übereinander, dann kannst du es mit einer einfacheren Funktion machen. mom...

Edit2: Hier eine Version wo nur jeweils das benachbarte Feld nicht identisch sein darf:

Code: [AUSKLAPPEN]
Graphics 220,220,0,2
SetBuffer FrontBuffer()

Const XARRAY%=9
Const YARRAY%=9

Dim myArray%(XARRAY,YARRAY)
Local X%,Y%




;myArray schreiben
For Y=0 To XARRAY
   For X=0 To YARRAY
      myArray(X,Y)=Setzen(X,Y,4)
   Next
Next


;myArray anzeigen
For Y=0 To XARRAY
   For X=0 To YARRAY
      Text X*20,Y*20,myArray(X,Y)
   Next
Next

WaitKey
End




Function Setzen(FX,FY,FZahl)
   Local AllesOK=1
   Local TempWert
   
   Repeat
      AllesOK=1
      TempWert=Rnd(0,FZahl)
      If FX>0 Then If myArray(FX-1,FY)=TempWert Then AllesOK=0
      If FY>0 Then If myArray(FX,FY-1)=TempWert Then AllesOK=0
      If FX<XARRAY Then If myArray(FX+1,FY)=TempWert Then AllesOK=0
      If FY<YARRAY Then If myArray(FX,FY+1)=TempWert Then AllesOK=0
   Until AllesOK=1
   
   Return TempWert
End Function
 

X-tra

BeitragSa, Jul 19, 2008 15:11
Antworten mit Zitat
Benutzer-Profile anzeigen
ich schau dann später selber mal, hoffe mir fällt das ganze wieder ein.
der untere code bei dir macht ja schon fast das, nur eben es dürfen 2 gleiche steine nebeneinander sein, nur eben nicht 3 gleiche.
und die gilt nur horizontal und vertikal in dem feld.
diagonal ists völlig wurscht.

Neue Antwort erstellen


Übersicht BlitzBasic Allgemein

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group