3

I need a delphi solution for this solution in java JAVA CODE

type
 TColors = (red, green, blue, white, purple, orange, yellow, black);
type
 TForm1 = class(TForm)
 Button1: TButton;
 Memo1: TMemo;
 procedure Button1Click(Sender: TObject);
 private
 { Private-Deklarationen }
 public
 { Public-Deklarationen }
 end;

 var Form1: TForm1;

 implementation

 {$R *.fmx}

 function RandomColor: TColors;
 begin
  result := blue;  //   make this random value from enum ????
end;

procedure TForm1.Button1Click(Sender: TObject);
var
s: string;
begin
  s := GetEnumName(TypeInfo(TColors), integer(RandomColor));
 Memo1.Lines.Add(s);   ///  print random color to memo 
end;
Community
  • 1
  • 1
Franz
  • 1,883
  • 26
  • 47

2 Answers2

5
function RandomColor: TColors;
begin
  Result := TColors(Random(Succ(Ord(High(TColors)))));
end;

var
  MyColor: TColors;
begin
  Randomize; //call this once at startup
  MyColor := RandomColor;
Chris Rolliston
  • 4,788
  • 1
  • 16
  • 20
  • 4
    I would add a +1 to the Ord(), otherwise you will never see the highest possible enum value. The upper limit is exclusive. – JensG Oct 12 '13 at 02:04
  • There seems to be a mistake. `Random(A)` returns range of 0..A-1, so if you want to have last element included you need to use `Random(A+1)`. – Kromster Oct 12 '13 at 06:15
  • @JensG and Krom - completely right, thanks - I've now added a Succ call. – Chris Rolliston Oct 12 '13 at 08:54
  • 2
    With the Succ() and RANGECHECKS ON my Delphi XE doesn't even compile this. Nice solution, indeed. BTW, why do you earn all the points while we do the work correcting your stuff? – JensG Oct 12 '13 at 10:04
  • 1
    @JensG - the Succ call is against an integer, so works fine with range checking enabled - I have no idea why your Delphi XE 'doesn't even compile this'. Perhaps you haven't copied and pasted correctly? – Chris Rolliston Oct 12 '13 at 11:34
  • Ok, your'e right. I added the succ() around high(), not ord(). This way it works indeed, and I have to apologize for the rant, I guess. – JensG Oct 12 '13 at 11:40
  • Doesn't that line read more like LISP though than Delphi? In practice readability should be valued above conciseness. – alcalde Feb 26 '14 at 05:25
  • @alcalde - if you're truly bothered just use one or two temporary variables. – Chris Rolliston Feb 26 '14 at 13:54
  • Although this answer works correctly based on what was originally asked, I would add a warning note about enums defined with arbitrary values. If the enum is defined as `TColors = (red = 5, green = 10, blue =15 etc)`, this code may return a value out of bound. – Christiano Kiss Apr 30 '19 at 04:08
0

Here's a complete test program, including a check against Low(TColors) not being zero, which must otherwise taken into account within the RandomColor function, if that later changes for some reason.

program Project7;

{$APPTYPE CONSOLE}
{$RANGECHECKS ON}

uses
  SysUtils;

type
  TColors = (red, green, blue);

const NAMES : array[TColors] of string = ('red','green','blue');

function RandomColor: TColors;
begin
  ASSERT( Ord(Low(TColors)) = 0);
  Result := TColors(Random(1+Ord(High(TColors))));
end;

var i : integer;
begin
  Randomize; 
  while true do begin
    for i := 0 to 7 do write('"', NAMES[RandomColor], '" ');
    writeln;
    writeln('press Ctrl+C to break, ENTER to continue ');
    readln;
  end;
end.
JensG
  • 13,148
  • 4
  • 45
  • 55