# Board index » delphi » problem passing array values.

## problem passing array values.

newbie question:
this program puts random values in an array, checking each value recursively
(in function "checkduplicates" to ensure that each value is unique, and then
is supposed to return the values
in the array to "main".  Otherwise it appears to work.
However, the values in the array after being passed back to the "main" are
always 0.  Any thoughts?
Much obliged.
A Newb
----------------------------------------------------------------------------
---------------------
program drawcard;
uses CRT;

type
HAND = array [1..8] of integer;

var
PLAYERS, DEALER, Y : integer;
Array1 : HAND;

function CheckDuplicates(var Xarray : HAND;
Target, N : integer) : Boolean;
{boolean, recursive funtion to search array}
begin {CheckDuplicates}

CheckDuplicates := False;
If N = 1 then
begin
CheckDuplicates := (Xarray[1] = TARGET);
end
Else If (Xarray[N] = TARGET) then
begin
CheckDuplicates := True;    {terminates function?}
writeln ('CheckDuplicates := ',CheckDuplicates)
end

Else                           {else if false, checks next N}
begin
CheckDuplicates := CheckDuplicates (Xarray, TARGET, N-1)
end
end;  {CheckDuplicates}

function dealit (var
X1 : Integer;
ARRAY1A : HAND) : HAND;
var count, N, X2, X3 : Integer;
Arr0, Arr1 : HAND;
begin {dealit}
X1 := (X1 + 1);
X1 := (2 * X1);
{while this is true, keep selecting random #'s}
X1 := 2;
For count := 1 to X1 do
begin {FOR}
writeln ('COUNT = ', count);
if count = 1  then
Arr0[1] := Random(52) + 1 {get 8 non-matching #'s}

else
begin {else}
repeat
{
while (CheckDuplicates (Arr0, X2, X1) =
true)
do
}
X2 := Random(52) + 1;
CheckDuplicates(Arr0, X2, X1);
until (CheckDuplicates(Arr0, X2, X1) = False);
writeln ('end of until');
If (CheckDuplicates(Arr0, X2, X1) = False)
then
begin {if}
Arr0[count] := X2;
ARRAY1A[count] := Arr0[count];
end  {if}
end {else}
end {FOR}
end;  {dealit}

begin
Y:=0;
Randomize; {calls proc. to initialize rnd. # generator}
write ('Enter the # of players (1 to 3) > ');
{add loop to control PLAYERS <= 4}

DEALIT(PLAYERS, ARRAY1);
{write out array}
{ note: this was causing a runtime error!
need to pass an array to dealit, }

for Y := 1 to PLAYERS do
begin
write (Array1[Y], 'elements of array ')
end;
writeln

end.

## Re:problem passing array values.

##### Quote
"eerieguy" <eerie...@noone.com> wrote:
>function dealit (var
>                        X1 : Integer;
>                        ARRAY1A : HAND) : HAND;

1) You are trying to return a HAND-type from this function, but never
assign a value (I wonder, if this compiles at all).

BTW, your naming is a mess. X1 or Array1A says nothing. I'd suggest
Num_Players and Cards or something more readable...

##### Quote
>      DEALIT(PLAYERS, ARRAY1);

2) You call the function without reading the result (that it does not
return anyway...)

You should better use a VAR parameter for Array1A in the "function"[0]
DealIt, so it can actually return something.

Vinzent.

[0] It should mutate to a procedure then...

## Re:problem passing array values.

JRS:  In article <AUbB9.44300\$hR3.30...@news2.central.cox.net>, seen in
news:comp.lang.pascal.borland, eerieguy <eerie...@noone.com> posted at
Fri, 15 Nov 2002 19:27:28 :-

##### Quote
>this program puts random values in an array, checking each value recursively
>(in function "checkduplicates" to ensure that each value is unique,

If you actually need an array of non-duplicate randoms, there may be
better ways, depending on the sizes of population and sample; it is
substantially a dealing problem - see via below.

--
? John Stockton, Surrey, UK.  j...@merlyn.demon.co.uk   Turnpike v4.00   MIME. ?
<URL:http://www.merlyn.demon.co.uk/> TP/BP/Delphi/&c., FAQqy topics & links;
<URL:http://www.merlyn.demon.co.uk/clpb-faq.txt> Pedt Scragg: c.l.p.b. mFAQ;
<URL:ftp://garbo.uwasa.fi/pc/link/tsfaqp.zip> Timo Salmi's Turbo Pascal FAQ.

## Re:problem passing array values.

Thanks for the feedback.

##### Quote
"Vinzent Hoefler" <JeLlyFish.softw...@gmx.net> wrote in message

news:3dd54e76_3@news.bluewin.ch...

##### Quote
> You should better use a VAR parameter for Array1A in the "function"[0]
> DealIt, so it can actually return something.

Whoops.

JRS:  In article <AUbB9.44300\$hR3.30...@news2.central.cox.net>, seen in
news:comp.lang.pascal.borland, eerieguy <eerie...@noone.com> posted at
Fri, 15 Nov 2002 19:27:28 :-

##### Quote
>If you actually need an array of non-duplicate randoms, there may be
>better ways, depending on the sizes of population and sample; it is
>substantially a dealing problem - see via below.

Good idea, but the examples seem to advanced for my course, or for me.
In one example, I don't understand why

for I := 1 to max_value
x := random (I + 1)

would yield non-duplicate randoms.
Perhaps I missed something.

## Re:problem passing array values.

##### Quote
"eerieguy" <eerie...@noone.com> wrote:
>Good idea, but the examples seem to advanced for my course, or for me.
>In one example, I don't understand why

>for I := 1 to max_value
>x := random (I + 1)
>would yield non-duplicate randoms.

It does not. You missed the point, or worse: you missed the rest of
the loop.

You are not choosing random *values* as a newly to-be-inserted card,
you are chosing a random *position* where you insert the next card
into the array to be built up. The dealing of the unique card comes
from the loop. The random *insertion* is from the random () function.
And this one does the shuffling of only the cards that are already
present in the array. It does not change the contents of the array, it
just changes the order of the contents up to the current index.

Mmh. As I read the above, it seems, I wouldn't understand it at the
forst glance. ;-)

Well, so I'll try to explain it a little bit more first by getting the
loop into single instructions:

|for J := 1 to 52 do begin
1|   K := Random(J)+1 ;
2|   A[J] := A[K] ;
3|   A[K] := J
|end ;

Line one creates a random number in range 1 to the current loop
counter. You never won't get above. That's your index where you should
insert your next card starting at one.

Line two moves the card that already is on this position to the
current end of the array to make space for the insertion at the chosen
position.

Now line three adds the new card (value J) to the randomly chosen
position in the array to fill it up.

Ok, more clear now? If not, let's try to make it a little bit more
visually imaginable:

Put your (sorted) card staple to the right side.

Get the first card to the left side. (Now you shuffle the card with
itself what does nothing).

Now take your next card from the right side and insert in at a random
position (either before or after the first card here). You have to
pick up the card eventually (move to end of array).

Take the next card (=incrementing the loop counter) from the right
staple and insert it at a randomly chosen position (line 1) of your
left staple by first taking the card at that position and putting it
on the top (line 2, yeah?) and then insert the card from the left
staple where the moved card was (line 3)...

Go on until all cards are on the left side.

Now the cards are "dealed" and you're done.

##### Quote
>Perhaps I missed something.

I think you get it now.

Vinzent.

## Re:problem passing array values.

JRS:  In article <oX8C9.76678\$hR3.24...@news2.central.cox.net>, seen in
news:comp.lang.pascal.borland, eerieguy <eerie...@noone.com> posted at
Mon, 18 Nov 2002 16:54:44 :-

##### Quote
>Good idea, but the examples seem to advanced for my course, or for me.
>In one example, I don't understand why

>for I := 1 to max_value
>x := random (I + 1)

>would yield non-duplicate randoms.
>Perhaps I missed something.

You missed telling us who wrote that, and where.  I have not got
"max_value" on my site; and I don't think it's in the others I cited.

In your own code, it should be simpler to iterate the array when
checking, rather than recurse it.

for J:= 1 to N do begin
repeat R := Choose until not ChosenBefore(R) ;
Save(R) ;
end ;

It would be best to put the choices in a set of 1..52, since you then
only need to implement  ChosenBefore as := R in ChosenSet ;

You should (almost?) never write   X = true   or   X = false  - use   X

--
? John Stockton, Surrey, UK.  j...@merlyn.demon.co.uk   Turnpike v4.00   MIME. ?
<URL:http://www.merlyn.demon.co.uk/> TP/BP/Delphi/&c., FAQqy topics & links;
<URL:http://www.merlyn.demon.co.uk/clpb-faq.txt> Pedt Scragg: c.l.p.b. mFAQ;
<URL:ftp://garbo.uwasa.fi/pc/link/tsfaqp.zip> Timo Salmi's Turbo Pascal FAQ.

## Re:problem passing array values.

Dr John Stockton <s...@merlyn.demon.co.uk> wrote:

##### Quote
>You should (almost?) never write   X = true   or   X = false  - use   X

Remove the part in the parentheses. :-) Pascal *knows* booleans and
handles them correctly, so there's no reason to use them incorrectly.

Vinzent.

## Re:problem passing array values.

JRS:  In article <3dd97c9c\$...@news.bluewin.ch>, seen in
news:comp.lang.pascal.borland, Vinzent Hoefler
<JeLlyFish.softw...@gmx.net> posted at Tue, 19 Nov 2002 00:49:18 :-

##### Quote
>Dr John Stockton <s...@merlyn.demon.co.uk> wrote:

>>You should (almost?) never write   X = true   or   X = false  - use   X

>Remove the part in the parentheses. :-) Pascal *knows* booleans and
>handles them correctly, so there's no reason to use them incorrectly.

Now that I have time to think of examples, consider the cases of :

Using for example the procedure FillChar with an error in its Count, it
is possible for an innocent nearby boolean to have its value
accidentally set to the value of FillChar's 3rd parameter. Tests for
exactly false & true, or one for <=true, could help.

Sometimes, in development of a program, there may be what should end up
as   if X=Y then ...   If the code giving Y were unreliable, then to
test the conditional code for a case where Y *ought* to be false, one
could change X=Y to X=false - that's less likely to confuse later than
just using X, specifically because it looks funny.

An allegedly boolean function supplied in a DLL written in another
language, which may give a malformed boolean - to test for that fault,
one could do
X := function(Y) ;
if (X=true) or (X=false) then Write('OK') else Write('ERROR') ;

A boolean set by typecasting an enumerated type, type X = (red, green),
for supply to a routine expecting a boolean.  If the type can be changed
to (red, amber, green), then a test against a boolean literal could be
useful.

A routine intended to be a severe test for debugging staff; it is
embedded in a unit which has in its interface
const true : boolean = 0=1 ; false : boolean = 0=0 ;
Since true is an identifier and not a reserved word, its value is not
necessarily boolean(1).  Another test would be to sneak in
type boolean = (true, false)
since boolean is not reserved either.

H'mm - in   case boovar of true:; false:; else filemode := 0 end;
I wonder whether code to set filemode is generated?  I cannot test at
present.

Anyway, the easiest way of explaining in writing that one should not
write "X = true" involves writing 'X = true'.  We do that quite often
here.

--
? John Stockton, Surrey, UK.  j...@merlyn.demon.co.uk   Turnpike v4.00   MIME. ?
Web  <URL:http://www.merlyn.demon.co.uk/> - FAQish topics, acronyms, & links.
Proper <= 4-line sig. separator as above, a line exactly "-- " (SonOfRFC1036)
Do not Mail News to me. Before a reply, quote with ">" or "> " (SonOfRFC1036)

## Re:problem passing array values.

Dr John Stockton <s...@merlyn.demon.co.uk> wrote:

##### Quote
>>Remove the part in the parentheses. :-) Pascal *knows* booleans and
>>handles them correctly, so there's no reason to use them incorrectly.

>Now that I have time to think of examples, consider the cases of :

>Using for example the procedure FillChar with an error in its Count, it
>is possible for an innocent nearby boolean to have its value
>accidentally set to the value of FillChar's 3rd parameter. Tests for
>exactly false & true, or one for <=true, could help.

Mmh. The problem is, Turbo Pascal explicitely states in the manual,
booleans are either internally 0 (= False) or they are considered as
True. So I guess, changing a statement from

|if Bool then

to

|if Bool = True then

will change absolutely nothing in the compiler's output (and honestly
spoken: It shall not.). Treating both statements differently would
change the semantics of the program.
Overflowing a buffer is always an error, so I do not see any other way
than to fix the bug instead of relying on questionable statements that
might or might not be implemented in the intended way, depending on
the compiler.

Ok, zero points until now. ;)

##### Quote
>Sometimes, in development of a program, there may be what should end up
>as   if X=Y then ...   If the code giving Y were unreliable,

Then it is wrong. Booleans say True or not True. If you are doing
anything else you should introduce a matching type like:

|type
|  fuzzy_bool = (absolutelytrue,
|                probablytrue,
|                maybetrue,
|                perhapstrue,
|                perhapsfalse,
|                maybefalse,
|                probablyfalse,
|                absolutelyfalse,
|                totallywrong,
|                completely{*word*30}edup);

and return an appropriate default value. :-)

##### Quote
>then to
>test the conditional code for a case where Y *ought* to be false, one
>could change X=Y to X=false - that's less likely to confuse later than
>just using X, specifically because it looks funny.

I consider this misuse of booleans and its useability might still
depend on the compiler you are using.

So still: zero points. ;)

##### Quote
>An allegedly boolean function supplied in a DLL written in another
>language, which may give a malformed boolean - to test for that fault,
>one could do
>        X := function(Y) ;
>        if (X=true) or (X=false) then Write('OK') else Write('ERROR') ;

Well, as I explained above, this may or may not work, here it might
depend eventually on an used optimization level. More modern compilers
than (and eventually even) TP will optimize the statement

|if (X = true) or (X = false)

down to a simple True without even considering the real value at all
and always implementing a simple

|Write ('OK');

instead of the above statement. Zero points.

##### Quote
>A boolean set by typecasting an enumerated type, type X = (red, green),
>for supply to a routine expecting a boolean.  If the type can be changed
>to (red, amber, green), then a test against a boolean literal could be
>useful.

The same as above applies here. It seems you are missing the point
that booleans are considered as they-can-have-only-two-values
variables, regardless of their internal representation.

So a typecast isn't just a bad idea, it also will probably lead to an
interpretation of Red = False, any other = True.

Still zero points.

##### Quote
>A routine intended to be a severe test for debugging staff; it is
>embedded in a unit which has in its interface
>        const true : boolean = 0=1 ; false : boolean = 0=0 ;
>Since true is an identifier and not a reserved word, its value is not
>necessarily boolean(1).  Another test would be to sneak in
>        type boolean = (true, false)
>since boolean is not reserved either.

Mmh. Quite {*word*193}, because in that case you'd invert all statements of
the type "if bool = ..." to its negation and every "if bool"[0]
probably keeps the intended semantics, because the compiler will use
its built-in bool type then. This ain't look like debugging. This
looks like "guess what I does."

Ok, because sometimes this is what a programmer intends, this one
gains a half point. ;)

[0] "var x : system.boolean;" should work for this in local scope or
it even already might be a "real" boolean, because it was imported
from another unit.

##### Quote
>H'mm - in   case boovar of true:; false:; else filemode := 0 end;
>I wonder whether code to set filemode is generated?

Well, here it looks like you get the point. The compiler can decide to
not implement the "else ..." at all. And it would be damn right. The
same holds true for every statement whose execution-flow tries to
depend on some "intermediate" values.

##### Quote
>I cannot test at present.

Well, you do not have to test. Even if it would work (on one
compiler), it can be considered as a very bad idea.

This is in ABSOLUTELY no way portable. It might work on TP3.0/4.0/5.5
whatever and might stop to work on TP6.0/7.0 (no, I won't test if
there are really differences).

##### Quote
>Anyway, the easiest way of explaining in writing that one should not
>write "X = true" involves writing 'X = true'.  We do that quite often
>here.

100 Points. Programmers are lazy. That's the right approach. :-)

Vinzent.

## Re:problem passing array values.

My favorite example doesn't explicitly use "true" or "false", but does do it
implicitly.  When I need to code a "do forever" loop, I have been known to write
---

CONST
hellfreezesover = false;  { much too hot }

...

REPEAT
{ some random code}
UNTIL hellfreezesover;

Bob Schor
Pascal Enthusiast

##### Quote
Dr John Stockton wrote:
> JRS:  In article <3dd97c9c\$...@news.bluewin.ch>, seen in
> news:comp.lang.pascal.borland, Vinzent Hoefler
> <JeLlyFish.softw...@gmx.net> posted at Tue, 19 Nov 2002 00:49:18 :-
> >Dr John Stockton <s...@merlyn.demon.co.uk> wrote:

> >>You should (almost?) never write   X = true   or   X = false  - use   X

> >Remove the part in the parentheses. :-) Pascal *knows* booleans and
> >handles them correctly, so there's no reason to use them incorrectly.

> Now that I have time to think of examples, consider the cases of :

> Using for example the procedure FillChar with an error in its Count, it
> is possible for an innocent nearby boolean to have its value
> accidentally set to the value of FillChar's 3rd parameter. Tests for
> exactly false & true, or one for <=true, could help.

> Sometimes, in development of a program, there may be what should end up
> as   if X=Y then ...   If the code giving Y were unreliable, then to
> test the conditional code for a case where Y *ought* to be false, one
> could change X=Y to X=false - that's less likely to confuse later than
> just using X, specifically because it looks funny.

> An allegedly boolean function supplied in a DLL written in another
> language, which may give a malformed boolean - to test for that fault,
> one could do
>         X := function(Y) ;
>         if (X=true) or (X=false) then Write('OK') else Write('ERROR') ;

> A boolean set by typecasting an enumerated type, type X = (red, green),
> for supply to a routine expecting a boolean.  If the type can be changed
> to (red, amber, green), then a test against a boolean literal could be
> useful.

> A routine intended to be a severe test for debugging staff; it is
> embedded in a unit which has in its interface
>         const true : boolean = 0=1 ; false : boolean = 0=0 ;
> Since true is an identifier and not a reserved word, its value is not
> necessarily boolean(1).  Another test would be to sneak in
>         type boolean = (true, false)
> since boolean is not reserved either.

> H'mm - in   case boovar of true:; false:; else filemode := 0 end;
> I wonder whether code to set filemode is generated?  I cannot test at
> present.

> Anyway, the easiest way of explaining in writing that one should not
> write "X = true" involves writing 'X = true'.  We do that quite often
> here.

> --
> ? John Stockton, Surrey, UK.  j...@merlyn.demon.co.uk   Turnpike v4.00   MIME. ?
>  Web  <URL:http://www.merlyn.demon.co.uk/> - FAQish topics, acronyms, & links.
>  Proper <= 4-line sig. separator as above, a line exactly "-- " (SonOfRFC1036)
>  Do not Mail News to me. Before a reply, quote with ">" or "> " (SonOfRFC1036)

## Re:problem passing array values.

##### Quote
Bob Schor <bsc...@pitt.edu> wrote:
>CONST
>   hellfreezesover = false;  { much too hot }

>...

>  REPEAT
>    { some random code}
>  UNTIL hellfreezesover;

Yeah. Self documenting, readable code. Very nice thing.

I like that. :-)

Vinzent.

## Re:problem passing array values.

JRS:  In article <3DDBF1F1.C307B...@pitt.edu>, seen in
news:comp.lang.pascal.borland, Bob Schor <bsc...@pitt.edu> posted at
Wed, 20 Nov 2002 15:34:58 :-

##### Quote
>Organization: University of Pittsburgh
>Lines: 75
>My favorite example doesn't explicitly use "true" or "false", but does do it
>implicitly.  When I need to code a "do forever" loop, I have been known to write
>---

>CONST
>   hellfreezesover = false;  { much too hot }

>...

>  REPEAT
>    { some random code}
>  UNTIL hellfreezesover;

WHILE true DO BEGIN
END ;

is better, since one can tell at the beginning that the loop is formally
infinite.

##### Quote
>Bob Schor
>Dr John Stockton wrote:

>> JRS:  In article <3dd97c9c\$...@news.bluewin.ch>, seen in
>> news:comp.lang.pascal.borland, Vinzent Hoefler
>> ...
>> ...

Your persistent, perverse, and inconsiderate habit of inverted full-
quoting shows you and the University of Pittsburgh in a rather bad
light.  If you cannot learn from the FAQ, why not learn from the
University of Vaasa?

--
? John Stockton, Surrey, UK.  j...@merlyn.demon.co.uk   Turnpike v4.00   MIME ?
Web <URL:http://www.uwasa.fi/~ts/http/tsfaq.html> -> Timo Salmi: Usenet Q&A.
Web <URL:http://www.merlyn.demon.co.uk/news-use.htm> :  about usage of News.
No Encoding. Quotes before replies. Snip well. Write clearly. Don't Mail News.

## Re:problem passing array values.

Dr John Stockton <s...@merlyn.demon.co.uk> wrote:

##### Quote
>JRS:  In article <3DDBF1F1.C307B...@pitt.edu>, seen in
>news:comp.lang.pascal.borland, Bob Schor <bsc...@pitt.edu> posted at
>Wed, 20 Nov 2002 15:34:58 :-

>>My favorite example doesn't explicitly use "true" or "false",
[...]
>>  REPEAT
>>    { some random code}
>>  UNTIL hellfreezesover;

>   WHILE true DO BEGIN
>     END ;

>is better, since one can tell at the beginning that the loop is formally
>infinite.

But this does avoid easy testing what would happen when hell freezes
over. ;-)

Vinzent.

Go to page: [1] [2]