Playlist ( ListiconGadget ) Randomize

Für allgemeine Fragen zur Programmierung mit PureBasic.
Benutzeravatar
125
Beiträge: 1322
Registriert: 19.09.2004 16:52
Wohnort: Neu Wulmstorf (Hamburg)
Kontaktdaten:

Playlist ( ListiconGadget ) Randomize

Beitrag von 125 »

Hi,
ich hab folgende Prozedur geschrieben um meine playlist zu mixen (ein listicongadget) das problem ist das wenn es mehr als 10 sind die Prozedur zur endlosschleife wird da Random nie die passende zahl zurückgibt. :(
Wie kann ich sie effizienter/nutzbar machen? (Darf keine Api verwenden da ich es nach Linux porten will)
Pls Help.
//Edit hat denn keiner Rat? kann man mit PB net mal nen listicongadget mischen :o ?

Code: Alles auswählen

----Veraltet siehe unten------
Schomal THX in voraus :)

mfg
125
Zuletzt geändert von 125 am 29.12.2004 01:05, insgesamt 1-mal geändert.
Benutzeravatar
125
Beiträge: 1322
Registriert: 19.09.2004 16:52
Wohnort: Neu Wulmstorf (Hamburg)
Kontaktdaten:

Beitrag von 125 »

so version 2 sie stürzt nun nicht mehr ab bei zu vielen items.
Aber das problem das es bei zuvielen items zu endless schleife wird bleibt immer noch. plzzzz help! :(

Code: Alles auswählen

Procedure Randomize()
  Gadgetitems=CountGadgetItems(#Plist)-1
  Dim gadgetitems2.s(Gadgetitems)
For xyzzzz=0 To Gadgetitems
  gadgetitems2(xyzzzz)=GetGadgetItemText(#Plist,xyzzzz,0)+Chr(10)+GetGadgetItemText(#Plist,xyzzzz,1)+Chr(10)+GetGadgetItemText(#Plist,xyzzzz,2)+Chr(10)+GetGadgetItemText(#Plist,xyzzzz,3)+Chr(10)+GetGadgetItemText(#Plist,xyzzzz,4)
Next
ClearGadgetItemList(#Plist)
Repeat

xzy=Random(Gadgetitems)
If FindString(ABC$,Str(xzy),0) = 0
  ABC$=ABC$+Str(xzy)+";"
EndIf
Until CountString(ABC$,";")=Gadgetitems+1
For kab=0 To Gadgetitems
AddGadgetItem(#Plist,-1,gadgetitems2(Val(StringField(ABC$,kab+1,";"))))
Next
EndProcedure
Benutzeravatar
Zaphod
Beiträge: 2875
Registriert: 29.08.2004 00:40

Beitrag von Zaphod »

nimm doch immer das element aus der liste, das du per random bestimmt hast und such das nächste mit random(n-1) aus der liste, bis du bei null bist.
Benutzeravatar
125
Beiträge: 1322
Registriert: 19.09.2004 16:52
Wohnort: Neu Wulmstorf (Hamburg)
Kontaktdaten:

Beitrag von 125 »

geht nicht weil n=maximum wenn er nun das erste mal die 1 bestimmt und ich minus 1 mach kann es immernoch sein das da 1 rauskomtm ......
:(
== ich hätte den Eintrag eins in der neuen Pplaylist 2 mal^^
Benutzeravatar
Zaphod
Beiträge: 2875
Registriert: 29.08.2004 00:40

Beitrag von Zaphod »

wenn du aus einer temporären liste die einträge immer gleich rauslöschst, kann es doch nicht passieren das einer 2 mal ausgewählt wird, oder verstehe ich dich falsch?
Christian
Beiträge: 73
Registriert: 31.08.2004 16:02

Beitrag von Christian »

Hi!

Warum so kompliziert? Diese Variante funktioniert sogar bei 1000 Einträgen noch relativ flott:

Code: Alles auswählen

#Plist = 0
#Button = 1

Procedure Randomize() 
Protected CurrenID.l, GadgetItems.l

  Gadgetitems = CountGadgetItems(#Plist) - 1 
  Dim GadgetItem.s(GadgetItems) 

  For i = 0 To Gadgetitems 
     GadgetItem(i) = GetGadgetItemText(#Plist, i, 0)+Chr(10)+GetGadgetItemText(#Plist, i, 1)+Chr(10)+GetGadgetItemText(#Plist, i, 2)+Chr(10)+GetGadgetItemText(#Plist, i, 3)+Chr(10)+GetGadgetItemText(#Plist, i, 4)
  Next 
  ClearGadgetItemList(#Plist)

  Repeat
    CurrentID = Random(GadgetItems)
    If GadgetItem(CurrentID) <> ""
        AddGadgetItem(#Plist, -1, GadgetItem(CurrentID))
        GadgetItem(CurrentID) = ""
    EndIf
  Until CountGadgetItems(#Plist) = GadgetItems
EndProcedure 

hwnd = OpenWindow(0, 0, 0, 500, 500, #PB_Window_SystemMenu | #PB_Window_ScreenCentered, "Random List")
If hwnd
    If CreateGadgetList(hwnd)
        ListIconGadget(#Plist, 0, 0, 500, 425, "Column 1", 125, #PB_ListIcon_FullRowSelect)
         AddGadgetColumn(#Plist, 1, "Column 2", 125)
         AddGadgetColumn(#Plist, 2, "Column 3", 125)
         AddGadgetColumn(#Plist, 3, "Column 4", 121)

        ButtonGadget(#Button, 200, 450, 100, 25, "Randomize")
    EndIf
    For a = 0 To 50
      AddGadgetItem(#Plist, -1, "Eintrag "+Str(a)+Chr(10)+"Spalte 2; "+"Eintrag "+Str(a)+Chr(10)+"Spalte 3; "+"Eintrag "+Str(a)+Chr(10)+"Spalte 4; "+"Eintrag "+Str(a))
    Next a

Repeat
 Select WaitWindowEvent()
  Case #PB_Event_Gadget
   Select EventGadgetID()
    Case #Button
     Randomize()

   EndSelect

  Case #PB_Event_CloseWindow
   Ende = 1

 EndSelect
Until Ende = 1
End
EndIf
Hoffe dir geholfen haben zu können.

Gruß
Christian
Benutzeravatar
125
Beiträge: 1322
Registriert: 19.09.2004 16:52
Wohnort: Neu Wulmstorf (Hamburg)
Kontaktdaten:

Beitrag von 125 »

ahh thx @ christian
funzt super :allright:

@Zaphod
der Parameter von Random ist das maximum das heist wenn ich 58 übergebe kommt eine Zahl zwischen 0 und 58 heraus. Nún bekomme ich z.B die 6 und sage Maximum-1 dann kann eine Zahl zwischen 0 und 57 herauskommen = 6 könnte doppelt ´reinkommen und die 58 würde nie erscheinen.....
Benutzeravatar
Zaphod
Beiträge: 2875
Registriert: 29.08.2004 00:40

Beitrag von Zaphod »

achso, wass ich meinte ist:
- du erzeugst eine temporäre liste (zb eine linked list)
- du erzeugst eine zielliste (wo die einträge so landen wie sie abgespielt werden sollen)

in der sortierten liste sind nun 10 einträge, du wählst also einen aus und tust ihn in die zweite liste und löscht ihn aus der erstem liste.

dann wählst du wieder einen aus der ersten liste, aber jetzt stehen da nurnoch 9 drinn, also suchst du einen eintrag über random(9) und kopierst ihn wieder in die zweite liste, löschst ihn aus der ersten liste, usw...

deine liste wird also bei jedem durchlauf um einen eintrag kürzer und du wendest random immer mit der anzahl der einträge an.

irgendwann hast du in der ersten liste nurnoch einen eintrag, da brauchst du dann garkein random mehr, denn das ist der letzte, den fügst du an die zweite liste an und voila, hast du alle einträge in zufälliger reihenfolge in der zweiten liste.

diese vorgehensweise sollte auch mit extrem vielen einträgen sauber funktionieren.
Benutzeravatar
125
Beiträge: 1322
Registriert: 19.09.2004 16:52
Wohnort: Neu Wulmstorf (Hamburg)
Kontaktdaten:

Beitrag von 125 »

achsooo, jetzt habbichs verstanden :)
Christian
Beiträge: 73
Registriert: 31.08.2004 16:02

Beitrag von Christian »

@125:
Kein Problem! :)

@Zaphod:
Das mit der Liste hatte ich auch ausprobiert. Habe also anstatt eines Arrays eine LinkedList benutzt, aber das war dann bei vielen Einträgen (hier 10000) um 3-4 Sekunden langsamer, als mit einem Array:

Code: Alles auswählen

#Plist = 0
#Button = 1

NewList GadgetItem.s()
Procedure Randomize() 
Protected CurrenID.l, GadgetItems.l
Start = ElapsedMilliseconds()

  Gadgetitems = CountGadgetItems(#Plist) - 1 

  For i = 0 To Gadgetitems 
     AddElement(GadgetItem())
      GadgetItem() = GetGadgetItemText(#Plist, i, 0)+Chr(10)+GetGadgetItemText(#Plist, i, 1)+Chr(10)+GetGadgetItemText(#Plist, i, 2)+Chr(10)+GetGadgetItemText(#Plist, i, 3)+Chr(10)+GetGadgetItemText(#Plist, i, 4)
  Next 
  ClearGadgetItemList(#Plist)

  Repeat
    CurrentID = Random(CountList(GadgetItem()))
    SelectElement(GadgetItem(), CurrentID)
      AddGadgetItem(#Plist, -1, GadgetItem())
      DeleteElement(GadgetItem())
  Until CountGadgetItems(#Plist) = GadgetItems

Debug Str(ElapsedMilliseconds() - Start)+" ms"
EndProcedure 

hwnd = OpenWindow(0, 0, 0, 500, 500, #PB_Window_SystemMenu | #PB_Window_ScreenCentered, "Random List")
If hwnd
    If CreateGadgetList(hwnd)
        ListIconGadget(#Plist, 0, 0, 500, 425, "Column 1", 125, #PB_ListIcon_FullRowSelect)
         AddGadgetColumn(#Plist, 1, "Column 2", 125)
         AddGadgetColumn(#Plist, 2, "Column 3", 125)
         AddGadgetColumn(#Plist, 3, "Column 4", 121)

        ButtonGadget(#Button, 200, 450, 100, 25, "Randomize")
    EndIf
    For a = 0 To 10000
      AddGadgetItem(#Plist, -1, "Eintrag "+Str(a)+Chr(10)+"Spalte 2; "+"Eintrag "+Str(a)+Chr(10)+"Spalte 3; "+"Eintrag "+Str(a)+Chr(10)+"Spalte 4; "+"Eintrag "+Str(a))
    Next a

Repeat
 Select WaitWindowEvent()
  Case #PB_Event_Gadget
   Select EventGadgetID()
    Case #Button
     Randomize()

   EndSelect

  Case #PB_Event_CloseWindow
   Ende = 1

 EndSelect
Until Ende = 1
End
EndIf
Gruß
Christian
Antworten