Recent

Author Topic: The necessity of using "delay" between "random" calling [SOLVED]  (Read 1380 times)

pascal111

  • Sr. Member
  • ****
  • Posts: 423
  • Un trabajo en equipo para programas serias.
This is a small program that generates two playing cards and making comparison between 'em, the problem is that I have to use "delay" between the generating of the two cards or I'll must get same two same cards in all tries.

Code: Pascal  [Select][+][-]
  1. procedure TForm1.Button1Click(Sender: TObject);
  2.  
  3.  
  4. var
  5.   s:string;
  6.   e:card_comparison;
  7.  
  8.  
  9. begin
  10.  
  11.   card_a^.card_generating;
  12.   delay(1000);
  13.   card_b^.card_generating;
  14.  
  15.   e:= cards_equal(card_a, card_b);
  16.   str(e,s);
  17.  
  18.   showmessage('Card A is ' + card_a^.name+#10#13+
  19.                'Card B is ' + card_b^.name+#10#13+
  20.                'Equality is ' + s);
  21.  
  22. end;
  23.  
  24.  

in

Code: Pascal  [Select][+][-]
  1. unit Unit1;
  2.  
  3. {$mode objfpc}{$H+}
  4. {$modeSwitch advancedRecords}
  5.  
  6. interface
  7.  
  8. uses
  9.   Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls,
  10.   Crt;
  11.  
  12. type
  13.  
  14.   { TForm1 }
  15.  
  16.   TForm1 = class(TForm)
  17.     Button1: TButton;
  18.     procedure Button1Click(Sender: TObject);
  19.     procedure FormClose(Sender: TObject; var CloseAction: TCloseAction);
  20.     procedure FormCreate(Sender: TObject);
  21.     procedure FormDestroy(Sender: TObject);
  22.   private
  23.  
  24.   public
  25.  
  26.   end;
  27.  
  28.   card_pattern = (Club, Diamond, Heart, Spade);
  29.  
  30.   playing_card = record
  31.     value:2..14;
  32.     name:string[20];
  33.     pattern:card_pattern;
  34.     procedure card_generating;
  35.   end;
  36.  
  37.   pcard = ^playing_card;
  38.  
  39.   card_comparison = (value, pattern, both, none);
  40.  
  41. function cards_equal(card_x, card_y:pcard):card_comparison;
  42.  
  43. var
  44.   Form1: TForm1;
  45.   card_a,
  46.   card_b:pcard;
  47.  
  48.  
  49.  
  50. implementation
  51.  
  52. {$R *.lfm}
  53.  
  54. { TForm1 }
  55.  
  56. procedure TForm1.FormClose(Sender: TObject; var CloseAction: TCloseAction);
  57. begin
  58.  
  59.  
  60.  
  61. end;
  62.  
  63. procedure TForm1.Button1Click(Sender: TObject);
  64.  
  65.  
  66. var
  67.   s:string;
  68.   e:card_comparison;
  69.  
  70.  
  71. begin
  72.  
  73.   card_a^.card_generating;
  74.   delay(1000);
  75.   card_b^.card_generating;
  76.  
  77.   e:= cards_equal(card_a, card_b);
  78.   str(e,s);
  79.  
  80.   showmessage('Card A is ' + card_a^.name+#10#13+
  81.                'Card B is ' + card_b^.name+#10#13+
  82.                'Equality is ' + s);
  83.  
  84. end;
  85.  
  86. procedure TForm1.FormCreate(Sender: TObject);
  87.  
  88. begin
  89.  
  90.   new(card_a);
  91.   new(card_b);
  92.  
  93. end;
  94.  
  95. procedure TForm1.FormDestroy(Sender: TObject);
  96. begin
  97.  
  98.   dispose(card_a);
  99.   dispose(card_b);
  100.  
  101. end;
  102.  
  103. procedure playing_card.card_generating;
  104.  
  105. var
  106.   x:2..14;
  107.   y:ord(low(card_pattern))..ord(high(card_pattern));
  108.   s1,s2:string[8];
  109.  
  110. begin
  111.  
  112.   randomize;
  113.   delay(10);
  114.  
  115.   x:=random(12+1)+2;
  116.   value:=x;
  117.  
  118.   case x of
  119.   11:s1:='JACK';
  120.   12:s1:='QUEEN';
  121.   13:s1:='KING';
  122.   14:s1:='ACE';
  123.   else
  124.     str(x,s1);
  125.   end;
  126.  
  127.   y:=random(ord(high(card_pattern))+1);
  128.   pattern:=card_pattern(y);
  129.  
  130.   str(pattern,s2);
  131.  
  132.   name:=s1+' '+s2;
  133.  
  134. end;
  135.  
  136. function cards_equal(card_x, card_y:pcard):card_comparison;
  137.  
  138. var
  139.   temp_e:card_comparison;
  140.  
  141. begin
  142.  
  143.   if (card_x^.value = card_y^.value) and
  144.   (card_x^.pattern <> card_y^.pattern) then
  145.    temp_e := value;
  146.  
  147.   if (card_x^.value <> card_y^.value) and
  148.   (card_x^.pattern = card_y^.pattern) then
  149.    temp_e := pattern;
  150.  
  151.   if (card_x^.value = card_y^.value) and
  152.   (card_x^.pattern = card_y^.pattern) then
  153.    temp_e := both;
  154.  
  155.   if (card_x^.value <> card_y^.value) and
  156.   (card_x^.pattern <> card_y^.pattern) then
  157.    temp_e := none;
  158.  
  159.   cards_equal:= temp_e;
  160.  
  161. end;
  162.  
  163. end.
  164.  
  165.  
« Last Edit: May 04, 2021, 06:17:52 pm by pascal111 »
La chose par la chose est rappelé.

dseligo

  • Hero Member
  • *****
  • Posts: 1220
Re: The necessity of using "delay" between "random" calling
« Reply #1 on: May 04, 2021, 05:54:38 pm »
I think you should call randomize only once, not every time. Put it somewhere in the beginning of program.

pascal111

  • Sr. Member
  • ****
  • Posts: 423
  • Un trabajo en equipo para programas serias.
Re: The necessity of using "delay" between "random" calling
« Reply #2 on: May 04, 2021, 05:59:41 pm »
I think you should call randomize only once, not every time. Put it somewhere in the beginning of program.

I called it once here in this next procedure, or you think its position isn't an appropriate one:

Code: Pascal  [Select][+][-]
  1.  
  2. procedure playing_card.card_generating;
  3.  
  4. var
  5.   x:2..14;
  6.   y:ord(low(card_pattern))..ord(high(card_pattern));
  7.   s1,s2:string[8];
  8.  
  9. begin
  10.  
  11.   randomize;
  12.   delay(10);
  13.  
  14.   x:=random(12+1)+2;
  15.   value:=x;
  16.  
  17.   case x of
  18.   11:s1:='JACK';
  19.   12:s1:='QUEEN';
  20.   13:s1:='KING';
  21.   14:s1:='ACE';
  22.   else
  23.     str(x,s1);
  24.   end;
  25.  
  26.   y:=random(ord(high(card_pattern))+1);
  27.   pattern:=card_pattern(y);
  28.  
  29.   str(pattern,s2);
  30.  
  31.   name:=s1+' '+s2;
  32.  
  33. end;
  34.  
La chose par la chose est rappelé.

dseligo

  • Hero Member
  • *****
  • Posts: 1220
Re: The necessity of using "delay" between "random" calling
« Reply #3 on: May 04, 2021, 06:04:12 pm »
Move randomize from card_generating to FormCreate.

dseligo

  • Hero Member
  • *****
  • Posts: 1220
Re: The necessity of using "delay" between "random" calling
« Reply #4 on: May 04, 2021, 06:05:15 pm »
And remove delays.

Bart

  • Hero Member
  • *****
  • Posts: 5289
    • Bart en Mariska's Webstek
Re: The necessity of using "delay" between "random" calling
« Reply #5 on: May 04, 2021, 06:13:38 pm »
Randomize initializes the global variable RandSeed.
It uses a.o. the current system time to calculate it.
If you call randomize twice with only nanoseconds between it, the system time will be the same in both calls.
Therefore RandSeed will be the same after both calls.
RandSeed then is used to calculate the result of Random().
So, both calls to Random() will have the same result.

With the delay, the system time is different after each call, so Random() will be different too.

As others explained: you should call Randomize only once (in the entire program).
The above tries to explain why this is the case.

Bart

pascal111

  • Sr. Member
  • ****
  • Posts: 423
  • Un trabajo en equipo para programas serias.
Re: The necessity of using "delay" between "random" calling
« Reply #6 on: May 04, 2021, 06:17:28 pm »
I moved "randomize" to "FormCreate", and removed "delays", as @dseligo and @Bart suggested and explained and the program works now appropriately. Thanks everyone!
La chose par la chose est rappelé.

 

TinyPortal © 2005-2018