losowanie - dziwna sprawa

0

mam taki oto kod

procedure TForm1.r2Click(Sender: TObject);
var i,j,IloscLiczb,WylosButNr:byte;
    ktorekliknieto: Array[1..9] of Boolean;
    DoLosowania: Array[1..9] of byte;

begin

 for i :=1 to 9 do begin
 ktorekliknieto[i] := false;
 DoLosowania[i] := 0;
 end;


 memo1.Clear;
 IloscLiczb := 0;
 j := 0;
 WylosButNr := 0;

if s1.Checked = true then
 begin
  sleep(800);

   if (bitbtn5.Glyph.Empty = true) or (bitbtn5.Tag = 2) then
    begin
     bitbtn5.Click;
     r1.Checked := true;
     exit;
    end else
     for i := 1 to 9 do
      with TBitbtn(findcomponent('bitbtn'+inttostr(i))) do
       begin
        if (((glyph.Empty = false) and (tag = 0)) or ((glyph.Empty = false) and (tag = 1))) then
        ktorekliknieto[i] := False  else ktorekliknieto[i] := True;
        if ktorekliknieto[i] = False then memo1.Lines.Add('false '+ inttostr(i));
        if ktorekliknieto[i] = True then memo1.Lines.Add('true  '+ inttostr(i));
       end;

     for i := low(ktorekliknieto) to high(ktorekliknieto) do
      if ktorekliknieto[i] = False then next else
       begin
        DoLosowania[i] := i;
        memo1.Lines.Add('do losowania ' +inttostr(DoLosowania[i]));
        inc(IloscLiczb);
       end;

       memo1.Lines.Add('ilosc liczb ' +inttostr(IloscLiczb));
<b>
       randomize;
       j := randomRANGE(1,IloscLiczb+1);
       WylosButNr := DoLosowania[(j)];
</b>


       memo1.Lines.Add('wylosowano ' +inttostr(WylosButNr));
       if  (WylosButNr >= 1) then
        with TBitbtn(findcomponent('bitbtn'+inttostr(WylosButNr))) do
              begin
               click;
               r1.Checked := true;
              end;
         //odblokujbuttony;
end;
end;

od momentu randomize co jakis czas dzieja sie dziwne rzeczy. majac do losowania liczby z przedzialu od 1 do IloscLiczb czasem (dosyc czesto) zostaje wylosowane zero. nie wiem o co chodzi. moze ktos pomoze
dzieki

0

może to coś pomoże, bo jak mi się wydaje to wykluczy "0".

j := randomRANGE(1,IloscLiczb)+1;

0

niestety, w jakis dziwny sopsob ponownie wylosowano 0 z zakresu od 1 do iloscliczb, nie to szlag :-[

0

Random(x) + 1 - to powinno działać ;)

0

tez wylosowano 0. zdaje sobie sprawe ze powinno dzialac tak i tak. dlaczego jednak losuje zero ?

0

wlasnie odkrylem ze dolosowania[i] dodawane sa rowniez zera. czyzby w momencie napotkania false, tablicy dolosowania[i] przypisane zostalo zero. chyba NEXT za bardzo tu nie dziala ? co o tym myslicie ???

for i := low(ktorekliknieto) to high(ktorekliknieto) do
     <b> if ktorekliknieto[i] = False then next else</b>
       begin
        DoLosowania[i] := i;
        memo1.Lines.Add('do losowania ' +inttostr(DoLosowania[i]));
        inc(IloscLiczb);
       end;

</b>
0

Nie wiem czy to o to chodzi, bo jestem dziś jakiś zagubiony, ale po pierwsze to cyba pisząc "next" miałeś na myśli "Continue" (przechodzi do następnego obrotu pętli. Po drugie to pamiętaj że nawet jak Ci pętla przeskoczy to "i" i tak się zwiększy więc nie możesz tak zapisać. wiem że zamotałem więc wyjaśnię na rysunku:

i:=1 : ktorekliknieto[i] = False : przeskocz : do tablicy nic nie wpisuje czyli masz tam "0"
i:=2 : ktorekliknieto[i] = true : wpisz do tablicy o indeksie i (czyli "2" a nie "1")

powodzenia.

0

Randomize() stosuje się tylko raz w programie.

0

thenkles chyba nie bardzo przemyslales swoj post.
Randomize ustala punkt startowy dla generatora losowania. Po jego ustaleniu mozna go odczytac by potem z tego samego punktu wystartowac a nastepnie znow losowac z innego "losowego". Na przykald:

seed:integer;
randomize; seed:=randseed;
// {} tu jakies rzeczy z wykorzystaniem random
randseed:=seed;
//{**} powtorzenie na przyklad czesci testow z {
}
//i w tym miejscu mamy randseed taki jak po wykonaniu czesci {**} w {*} . Jesli chcemy uzyskiwac dalej inne wartosci w generatorze musimy ponownie uzyc randomize

0

Randomize initializes the built-in random number generator with a random value (obtained from the system clock). The random number generator should be initialized by making a call to Randomize, or by assigning a value to RandSeed.

Do not combine the call to Randomize in a loop with calls to the Random function. Typically, Randomize is called only once, before all calls to Random.

Natomiast żadnego zapamiętywanie ziarna generatora w kodzie nie widzę, więc nie wiem, co to ma do rzeczy.

0

A to tak thenkles, masz rację, że na ogół w prostych zastosowaniach wystarczy raz (typically= typowo , zazwyczaj). Zareagowałem poprzednim postem bo napisałeś ogólne zdanie

Randomize() stosuje się tylko raz w programie.

jakby zawsze jedno wywyłanie randomize było wystarczające:)

0

Jedno wywołanie Randomize JEST wystarczające, lecz trzeba wiedzieć, gdzie je wywołać, tzn. trzeba je wywołać na początku programu, jeśli chodzi o Delphi to najlepiej w OnCreate pierwszej formy.

1 użytkowników online, w tym zalogowanych: 0, gości: 1