mmmmm sve je to fino,ali mislim da nije bila svrha da se napravi cijeli program(ili jest?),već algoritam koji će napravit random poredak n elemenata neke liste(pley liste u ovom slučaju)...Dakle,trebalo bi napraviti procedure i/ili funkcije,a ne pisati cijeli program..kad bude trebalo napravit neke izmjene u daljnjem razvoju,onda će to biti teško
da ne petljam dalje,evo kako bi se moglo:
imamo listu od n članova(filename u ovom slučaju),neka je ona
PlayLista:array[1..n]of string;
netko je već rekao,napravimo listu slučajnih brojeva od 1 do n tako da se svaki ponavlja samo jednom,lista neka je
Redosljed:array[1..n]of integer;
pjesma koja se pušta je ona čiji se file name nalazi u listi na poziciji redosljed[I],gdje je I brojač koji povećavamo prilikom završetka pjesme ili klika na gumb za prelazak na sljedeću.
npr.imamo PlayLista:('pjesma1.mp3','pjesma2.mp3','pjesma3.mp3','pjesma4.mp3','pjesma5.mp3',) i
Redosljed:(1,5,3,4,2)
dakle,kako I krene od 1 pa do 5,puštat će se 'pjesma1.mp3','pjesma5.mp3','pjesma3.mp3','pjesma4.mp3','pjesma2.mp3'. kad je i recimo I:=2,onda
se pušta pjesma5.mp3,jer je Redosljed[2]=5,a PlayLista[Redosljed[2]]=PlayLista[5]='pjesma5.mp3'
ovu ideja je već predložena,samo da ju malo pojasnim.
e sad, viking13 je između ostalog napisao i ovo:
Result := 0;
I := 0;
Randomize;
// pravljenje playliste koja ide redom
PlayList := TStringList.Create;
// setovanje foldera sa mp3 fajlovima
// obrati paznju da moras da imas '\' na kraju stringa
Folder := 'D:\mp3\';
try
ChDir(Folder);
except
on EInOutError do
begin
Exit; // ukoliko folder ne postoji ostak nema smisla
end;
end;
// pronadji prvi folder
FindFirst(Folder+'*.mp3', faAnyFile, SearchRec);
// pronadji ostale i dodaj ih u listu
while Result = 0 do
begin
PlayList.Add(SearchRec.Name);
Result := FindNext(SearchRec);
Application.ProcessMessages;
end;
// pomoćna lista da bi mogli da izmešamo originalnu
TmpPlayList := TStringList.Create;
try
repeat
// slučajan broj
RndInt := Random(PlayList.Count);
// dodaj novi element ukoliko već ne postoji
if TmpPlayList.IndexOf(PlayList[RndInt]) = -1 then
begin
TmpPlayList.Add(PlayList[RndInt]);
inc(I);
end;
until I = PlayList.Count-1; // svi elementi prebačeni u novu listu
// prabaci elemente izmešane liste u originalnu listu
PlayList.Assign(TmpPlayList);
finally
TmpPlayList.Free;
end;
Memo1.Lines.Clear;
prvo što mi se nesviđa je što je ovaj kod,umjesto da je u zasebnoj proceduri,on stoji u form.create,što znači da je moguće samo jednom napravit random listu,prilikom pokretanja programa,a novu pravi ponovnim pokretanjem programa.
drugo,što ćeš vidit ako ovo testiraš na većim playlistama,je to da će se program jaaako usporit tražeći posljednje elemente,jer je recimo vjerojatnost da će od 100 brojeva bit izvučen jedan, 1/100, pa kad na kraju ostane recimo da se treba naći broj 89 da bi se izašlo iz petlje, program u svakom koraku imati vjerojatnost od 0,01 da taj broj i dobije..100 je možda i mala brojka,ali kod većih listi,ma kolko jak bio procesor,usporit će se program..osim ako nemaš neki procesor sretne ruke ;)
u tu svrhu postoji više algoritama kako to izbjeći,a najbolji je ovaj:
zamisli se jedan broj od 1 do n
element na toj poziciji zamjeni se sa zadnjim
u sljedećem koraku se zamisli broj od 1 do n-1 i zamjeni s predzadnjim,itd dok ne dođemo do jednog elementa
kod u delphiju bi bio
procedure Izmjesaj_niz(var niz:array of integer);
var
i,r,pom,n:integer;
begin
n:=high(niz);
for I:=0 to n do niz[I]:=I+1;
for I:=n downto 1 do
begin
randomize;
r:=random(I+1);
pom:=niz[I];
niz[I]:=niz[r];
niz[r]:=pom;
end;
end;
dakle,ova procedura u array niz zapisuje n nasumičnih brojeva
ovo je glavno,i odgovor na tvoje pitanje,a dalje možemo na razne načine.Možemo napravti niz slučajnih brojeva i po njemu svirati.možemo i ispremještati samu playlistu..kako smo ovo sve radili zbog brzine,najbolje je ovo prvo.Zbog toga možemo napraviti proeduru sviraj
procedure Sviraj(i:integer);
begin
MediaPlayer1.Close;
MediaPlayer1.FileName := PlayLista[Redosljed[I]];
MediaPlayer1.Open;
MediaPlayer1.Play;
end;
tako u proceduru FormCreate ide između ostalog
procedure FormCreate(Sender: TObject);
begin
.
.
.
brojac:=-1;
end;
gdje je brojac varijabla globalnog tipa definirana u private odjeljku unita,kao i nizovi PlayLista i Redosljed(slično kao u prethodnom rješenju, samo naši nazivi) dok u proceduru TForm1.Button1Click može ići
procedure TForm1.Button1Click(Sender: TObject);
begin
.
.
.
Postavi_brojac(brojac);
Sviraj(brojac);
end;
gdje nam procedura Postavi_brojac izgleda
procedure Postavi_brojac(var brojac:integer);
begin
if brojac>high(Redosljed) then brojac:=0 else brojac:=brojac+1;
end;
imamo i proceduru za stvaranje nove random liste,koju možemo upotrjebiti kad želimo novi razmještaj stare ili nove playliste
procedure Stvori_listu(velicina:integer);
begin
setlength(redosljed,velicina);
Izmjesaj_niz(Redosljed);
end;
na kraju priče,tvoj unit bi trebao izgledati otprilike:
Code:
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, MPlayer, ExtCtrls;
type
TForm1 = class(TForm)
.
.
.
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject)
.
.
.
private
{ Private declarations }
PlayLista: TStringList;
Redosljed:array of integer;
brojac:integer;
public
{ Public declarations }
end;
var
Form1: TForm1;
procedure Inicijalizacija;
procedure Izmjesaj_niz(var niz:array of integer);forward;
procedure Postavi_brojac(var brojac:integer);forward;
procedure Stvori_listu(velicina:integer);forward;
procedure Sviraj(i:integer);forward;
implementation
procedure Inicijalizacija;
begin
brojac:=-1;
end;
procedure Izmjesaj_niz(var niz:array of integer);
var
i,r,pom,n:integer;
begin
n:=high(niz);
for i:=0 to n do niz[I]:=I+1;
for i:=n downto 1 do
begin
randomize;
r:=random(i+1);
pom:=niz[I];
niz[I]:=niz[r];
niz[r]:=pom;
end;
end;
procedure Postavi_brojac(var brojac:integer);
begin
if brojac>high(Redosljed) then brojac:=0 else brojac:=brojac+1;
end;
procedure Stvori_listu(velicina:integer);
begin
setlength(redosljed,velicina);
Izmjesaj_niz(Redosljed);
end;
procedure Sviraj(i:integer);
begin
MediaPlayer1.Close;
MediaPlayer1.FileName := PlayLista[Redosljed[I]];
MediaPlayer1.Open;
MediaPlayer1.Play;
end;
.
.
.
procedure TForm1.Button1Click(Sender: TObject);
begin
.
.
.
Postavi_brojac(brojac);
Sviraj(brojac);
end;
procedure TForm1.Button2Click(Sender: TObject);//kojim možeš stvoriti novu listu i svirati odmah
var
...
velicina:integer;//nju dobiješ kad učitaš listu PlayListu,to možeš kako ti je viking13 objasnio.Primjeti da ova procedura mijenja FormCreate
begin
PlayLista := TStringList.Create;
// setovanje foldera sa mp3 fajlovima
// obrati paznju da moras da imas '\' na kraju stringa
Folder := 'D:\mp3\';
try
ChDir(Folder);
except
on EInOutError do
begin
Exit; // ukoliko folder ne postoji ostak nema smisla
end;
end;
// pronadji prvi folder
FindFirst(Folder+'*.mp3', faAnyFile, SearchRec);
// pronadji ostale i dodaj ih u listu
while Result = 0 do
begin
PlayList.Add(SearchRec.Name);
Result := FindNext(SearchRec);
Application.ProcessMessages;
end;
velicina:=PlayLista.Count;
Stvori_listu(velicina);
Inicijalizacija;
Postavi_brojac(brojac);
Sviraj;
end;
.
.
.
end.
da napomenem,nema ništa pogrešno u prethodnom postu,ovdje je glavno da je popravljen algoritam za stvaranje random liste,ali isto mislim da je apstrakcija u programiranju jako važna,i zbog toga sam malo i preuredio unit(točkice zamjenjuju sve ostalo što ćeš ti još nadograditi).Iako, ni ovo nije baš apstrahirano kako treba,najbolje bi bilo kad bi napravio novi unit,ili još bolje biblioteku procedura i funkcija,koje bi radile sa random listama,i ti ih onda samo pozivao iz svog unit-a..nebi bilo loše ni napraviti novu klasu koja radi s random listama..ali to su sve samo različiti pristupi rješavanju problema,zasad je važno da je pristup koji se odabere točan..pozz
[/code][code][code]