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

?
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
@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