PDA

View Full Version : Randomize problem



Wizard
14-05-2008, 09:25 AM
Hi everyone, I have the following code to create objects on the form in random order. It works but not the way I expected, if my player bumps into one of the objects a question is generated. Problem is that even though the questions, which are linked to the objects, are generated randomly the same question (object) would sometimes appear 2 or 3 times. How can I make it truly random so that no question (object) appears more than once?

Thanks!

const
_RoundCount = 20;

fRoundImageIndex : array[0.._RoundCount-1] of integer;

var LoopLevelOne : integer;
begin
if (Level1Random) then
begin
for loopLevelOne := 1 to _RoundCount do
fRoundImageIndex[loopLevelOne-1]:=formGame.DXImageList.Items.IndexOf('Round'+intTo Str(loopLevelOne));
MyBlock.Add(TBlock.create(265,80,fRoundImageIndex[random(_RoundCount)],DXSpriteEngine.Engine,dxImageList));
MyBlock.Add(TBlock.create(265,200,fRoundImageIndex[random(_RoundCount)],DXSpriteEngine.Engine,dxImageList));
MyBlock.Add(TBlock.create(265,320,fRoundImageIndex[random(_RoundCount)],DXSpriteEngine.Engine,dxImageList));
MyBlock.Add(TBlock.create(7,10,fRoundImageIndex[random(_RoundCount)],DXSpriteEngine.Engine,dxImageList));
end;
end;

initialization
Randomize;
TimeBeginPeriod(1);
end.

User137
14-05-2008, 12:49 PM
You have to save current index somewhere and next time make a repeat-until loop for random that compares to last index until it differs. Here you must be sure there is more than 1 different index or you run in a infinite loop.

Wizard
16-05-2008, 10:29 AM
Thanks User137, I'll look into it when I have some free time :roll:

Wizard
19-05-2008, 12:06 PM
Hi, I'm realy not good with arrays and lists so please help :? I searched the web for examples and implimented the following into my code:

if (Level1Random) then
begin
j := 1;
m := 1;
while j < (21) do
begin
// randomize; //done at initialization
a := random(21);

// Checking array for duplicates.
for i := 1 to _RoundCount do
begin
if (fRoundImageIndex[i] = a) or (a=0) then
begin
included := true;
if included then exit;
end
else included := false {end if loop}
end; {for loop}

// Adding number to array.
if (not included) then
begin
fRoundImageIndex[m] := a;
m := m + 1;
j := j + 1;
end; {if loop}


for i := 1 to _RoundCount do
fRoundImageIndex[i-1] := formGame.DXImageList.Items.IndexOf('round'+intToSt r(i));
end; {while loop}
MyBlock.Add(TBlock.create(265,80,fRoundImageIndex[random(_RoundCount)],DXSpriteEngine.Engine,dxImageList));
MyBlock.Add(TBlock.create(265,200,fRoundImageIndex[random(_RoundCount)],DXSpriteEngine.Engine,dxImageList));
MyBlock.Add(TBlock.create(265,320,fRoundImageIndex[random(_RoundCount)],DXSpriteEngine.Engine,dxImageList));
MyBlock.Add(TBlock.create(7,10,fRoundImageIndex[random(_RoundCount)],DXSpriteEngine.Engine,dxImageList));
MyBlock.Add(TBlock.create(135,30,fRoundImageIndex[random(_RoundCount)],DXSpriteEngine.Engine,dxImageList));
MyBlock.Add(TBlock.create(135,400,fRoundImageIndex[random(_RoundCount)],DXSpriteEngine.Engine,dxImageList));
MyBlock.Add(TBlock.create(7,430,fRoundImageIndex[random(_RoundCount)],DXSpriteEngine.Engine,dxImageList));
MyBlock.Add(TBlock.create(395,30,fRoundImageIndex[random(_RoundCount)],DXSpriteEngine.Engine,dxImageList));
MyBlock.Add(TBlock.create(395,400,fRoundImageIndex[random(_RoundCount)],DXSpriteEngine.Engine,dxImageList));
MyBlock.Add(TBlock.create(525,430,fRoundImageIndex[random(_RoundCount)],DXSpriteEngine.Engine,dxImageList));
MyBlock.Add(TBlock.create(525,10,fRoundImageIndex[random(_RoundCount)],DXSpriteEngine.Engine,dxImageList));
MyBlock.Add(TBlock.create(32,290,fRoundImageIndex[random(_RoundCount)],DXSpriteEngine.Engine,dxImageList));
MyBlock.Add(TBlock.create(32,150,fRoundImageIndex[random(_RoundCount)],DXSpriteEngine.Engine,dxImageList));
MyBlock.Add(TBlock.create(160,153,fRoundImageIndex[random(_RoundCount)],DXSpriteEngine.Engine,dxImageList));
MyBlock.Add(TBlock.create(160,276,fRoundImageIndex[random(_RoundCount)],DXSpriteEngine.Engine,dxImageList));
MyBlock.Add(TBlock.create(420,276,fRoundImageIndex[random(_RoundCount)],DXSpriteEngine.Engine,dxImageList));
MyBlock.Add(TBlock.create(420,153,fRoundImageIndex[random(_RoundCount)],DXSpriteEngine.Engine,dxImageList));
MyBlock.Add(TBlock.create(550,290,fRoundImageIndex[random(_RoundCount)],DXSpriteEngine.Engine,dxImageList));
MyBlock.Add(TBlock.create(550,150,fRoundImageIndex[random(_RoundCount)],DXSpriteEngine.Engine,dxImageList));
MyBlock.Add(TBlock.create(265,432,fRoundImageIndex[random(_RoundCount)],DXSpriteEngine.Engine,dxImageList));
Solved := 0;
FormGame.DXWaveList.Items[0].Play(false);
fPlayingState:=_psPlaying;
end
else
if (Level2) then

it works but I still get duplicates, maybe I'm doing it wrong? Thanks for your help!

User137
19-05-2008, 01:23 PM
Here's something i noticed and would change when searhing previous inclusion (note that exit; quits the entire procedure, use break; instead):
included:=false; // reset only once at the beginning
for i := 1 to _RoundCount do
begin
if (fRoundImageIndex[i-1] = a) then // notice -1 , your array starts from 0
begin
included := true;
break; // exists innermost loop, which is for currently
end;{end if loop}
end; {for loop}

And...

If you call these 2 after another, there is chance that duplicates exists right?
MyBlock.Add(TBlock.create(265,80,fRoundImageIndex[random(_RoundCount)],DXSpriteEngine.Engine,dxImageList));
MyBlock.Add(TBlock.create(265,200,fRoundImageIndex[random(_RoundCount)],DXSpriteEngine.Engine,dxImageList));

Isn't random(_RoundCount) the part of code that you are meant to replace with duplicate finding? You can make a compare function for it so it won't be any longer as code to write.

Edit: After better look, there is alot of weird parts and real errors in your code. Take a really close look at it and think through what it is meant to do.