Seite 1 von 1

Playlist ( ListiconGadget ) Randomize

Verfasst: 28.12.2004 21:13
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

Verfasst: 29.12.2004 00:59
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

Verfasst: 29.12.2004 02:10
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.

Verfasst: 29.12.2004 10:04
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^^

Verfasst: 29.12.2004 12:32
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?

Verfasst: 29.12.2004 13:08
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

Verfasst: 29.12.2004 17:16
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.....

Verfasst: 29.12.2004 18:40
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.

Verfasst: 29.12.2004 18:48
von 125
achsooo, jetzt habbichs verstanden :)

Verfasst: 30.12.2004 12:54
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