Board index » delphi » Random file access for a quiz program

Random file access for a quiz program

Hi, I hope someone can help with this.
I'm writing a little shareware quiz program, and I want to make the
questions appear in random order. I've got that working OK, but what I also
want is for each question to only appear once, and I can't seem to get that
to happen. I've used both WHILE and REPEAT loops to try and get it working,
neither of which is doing the trick. Here's the code (it's a bit lengthy,
plus OE messed up the formatting a bit):

PROGRAM random_quz_file_test; {EvilBill, May 28th 2001}

USES crt,dos;

TYPE
 quesans=1..3;
 scores=0..25;

 questions=RECORD
  question,ans1,ans2,ans3:STRING[80];
  answer:quesans;
 END;

VAR
 quesinfo:questions;
 quesfile:FILE OF questions;
 score:scores;
 questions_used:ARRAY [1..25] OF Integer;
 used:boolean;

PROCEDURE set_vars;
VAR
 i:Integer;
BEGIN
 score:=0;
 FOR i:=1 TO 25 DO
  questions_used[i]:=-1;
 used:=true;
END;

VAR
 i,x,error,fpos:Integer;
 youranswer:quesans;

BEGIN
 randomize;
 clrscr;
 writeln('    Random Question Asking - Test program');
 writeln;
 writeln('(C) EvilBill 2001-05-28. Do not distribute!');
 writeln;
 assign(quesfile,'test.quz');
 {$I-}
 reset(quesfile);
 {$I+}
 error:=ioresult;
 IF error<>0 THEN
 BEGIN
  writeln('Error, there is no test question file to read from');
  halt(1);
 END;
 FOR i:=1 TO 25 DO
 BEGIN
  REPEAT
   {$I-}
   seek(quesfile,random(25));
   read(quesfile,quesinfo);
   {$I+}
   error:=ioresult;
   IF error<>0 THEN
   BEGIN
    writeln('Error, this is not a complete question file');
    halt(1);
   END;
   fpos:=filepos(quesfile);
   x:=1;
   WHILE used=true DO
   BEGIN
    IF fpos=questions_used[x] THEN
     used:=true
    ELSE
     used:=false;
    x:=x+1;
   END;
  UNTIL used=false;
  questions_used[i]:=fpos;
  writeln;
  writeln('Question ',i,':');
  writeln(quesinfo.question);
  writeln;
  writeln(' 1: ',quesinfo.ans1);
  writeln(' 2: ',quesinfo.ans2);
  writeln(' 3: ',quesinfo.ans3);
  writeln;
  write('Your answer (1-3): ');
  readln(youranswer);
  IF youranswer=quesinfo.answer THEN
   inc(score);
 END;
 writeln;
 writeln('You scored ',score,'.');
 writeln;
 writeln('Question numbers displayed were:');
 FOR i:=1 TO 25 DO
  write(questions_used[i],' ');
 writeln;
END.

Hopefully someone can see the problem and help me fix it? Thanks in advane.

(PS, the test file was created by another little program, all that does is
create the questions and answers and write them to the file.)

--
-- EvilBill[AGQx]
All your .sig file are belong to us.
ICQ: 37464244

 

Re:Random file access for a quiz program


Quote
"EvilBill[AGQx]" <evil_lord_b...@q3arena.com> wrote:
>I'm writing a little shareware quiz program, and I want to make the
>questions appear in random order. I've got that working OK, but what I also
>want is for each question to only appear once,

The best way is to read in the array, then shuffle it, and then
use it in order.  Here is how to shuffle:

n is the number of items in the array, first array element has
index 1.

{ randomize should be called only once if repeatedly shuffling a
small array! }
{ randomize; }

var i, j, n : integer;
    temp : QuestionType;

begin

for i := n downto 2 do
begin
  j := random( i) + 1; { 1 <= j <= i }
  temp := question[ i];
  question[ i] := question[ j];
  question[ j] := temp;
end {** for i := **}

Re:Random file access for a quiz program


Quote
"Jud McCranie" <jud.mccra...@mindspring.com> wrote in message
> "EvilBill[AGQx]" <evil_lord_b...@q3arena.com> wrote:

> >I'm writing a little shareware quiz program, and I want to make the
> >questions appear in random order. I've got that working OK, but what I
also
> >want is for each question to only appear once,

> The best way is to read in the array, then shuffle it, and then
> use it in order.  Here is how to shuffle:

> n is the number of items in the array, first array element has
> index 1.

> { randomize should be called only once if repeatedly shuffling a
> small array! }
> { randomize; }

> var i, j, n : integer;
>     temp : QuestionType;

> begin

> for i := n downto 2 do
> begin
>   j := random( i) + 1; { 1 <= j <= i }
>   temp := question[ i];
>   question[ i] := question[ j];
>   question[ j] := temp;
> end {** for i := **}

Thanks, although if I understand this correctly it means reading the
questions into an array? My final version will be choosing 25 questions from
a file of 100 or so, so I'll have memory considerations to think about.

--
-- EvilBill[AGQx]
All your .sig file are belong to us.
ICQ: 37464244

Re:Random file access for a quiz program


Quote
"EvilBill[AGQx]" <evil_lord_b...@q3arena.com> wrote:
>Thanks, although if I understand this correctly it means reading the
>questions into an array? My final version will be choosing 25 questions from
>a file of 100 or so, so I'll have memory considerations to think about.

The way you have it, 100 questions will use up about 33KB.  If
that's too much, then an alternative would be to set up an array

for i := 1 to 100 do x[ i] := i;

then shuffle that array as I showed, then each time you are
ready for a question, open the file and read to you get the x[i]
question.

Re:Random file access for a quiz program


Quote
Jud McCranie <jud.mccra...@mindspring.com> wrote:
>then shuffle that array as I showed, then each time you are
>ready for a question, open the file and read to you get the x[i]
>question.

Instead, you should leave the file open and then seek the x[i]
record in the ith time through the loop, x is shuffled.

Re:Random file access for a quiz program


"EvilBill[AGQx]" <evil_lord_b...@q3arena.com> said the following:
Quote
>"Jud McCranie" <jud.mccra...@mindspring.com> wrote in message
>> "EvilBill[AGQx]" <evil_lord_b...@q3arena.com> wrote:

>> >I'm writing a little shareware quiz program, and I want to make the
>> >questions appear in random order. I've got that working OK, but what I
>also
>> >want is for each question to only appear once,

>> The best way is to read in the array, then shuffle it, and then
>> use it in order.  Here is how to shuffle:

[..]

>Thanks, although if I understand this correctly it means reading the
>questions into an array? My final version will be choosing 25 questions from
>a file of 100 or so, so I'll have memory considerations to think about.

Just use an array of word with contents 1..100, shuffle as Jud's
suggestion then use the value in the array as an index into the
file - for 25 questions then just read value in array location 1..25

--
Pedt

Most mushrooms are umbrella shaped as they grow in damp places

Re:Random file access for a quiz program


Thanks, I'll give it a try :)

--
-- EvilBill[AGQx]
All your .sig file are belong to us.
ICQ: 37464244

Re:Random file access for a quiz program


JRS:  In article <9eu1s1$pp...@news6.svr.pol.co.uk>, seen in
news:comp.lang.pascal.borland, EvilBill[AGQx]
<evil_lord_b...@q3arena.com> wrote at Mon, 28 May 2001 18:33:01 :-

Quote
>Hi, I hope someone can help with this.
>I'm writing a little shareware quiz program, and I want to make the
>questions appear in random order. I've got that working OK, but what I also
>want is for each question to only appear once, and I can't seem to get that
>to happen. I've used both WHILE and REPEAT loops to try and get it working,
>neither of which is doing the trick. Here's the code (it's a bit lengthy,
>plus OE messed up the formatting a bit):

You have 25 questions.  Deal the numbers 1..25 into an array [1..25],
and use the array sequentially to index into the file.  For efficient
dealing, see <URL: http://www.merlyn.demon.co.uk/pas-rand.htm#Deal> and
TSFAQP #140.

--
? 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:Random file access for a quiz program


JRS:  In article <rp55htgehlpkmmhdltt070s2f8ecnp4...@4ax.com>, seen in
news:comp.lang.pascal.borland, Jud McCranie
<jud.mccra...@mindspring.com> wrote at Mon, 28 May 2001 14:25:39 :-

Quote

>for i := n downto 2 do
>begin
>  j := random( i) + 1; { 1 <= j <= i }
>  temp := question[ i];
>  question[ i] := question[ j];
>  question[ j] := temp;
>end {** for i := **}

[Almost] never move more than once any item larger than a single
instruction will handle on the course of sorting, shuffling, or dealing;
one can adjust indexes or pointers instead, and, if really necessary,
re-order accordingly later.

Never load an array with sequential numbers for shuffling, as one can
deal them faster with the method given by Horst Kraemer and quoted in
TSFAQP #140.

In this case, only one question need be accessed at a time, and it can
be accessed direct from disc without significant delay on a modern PC+OS
- either by simple read through a text file (which will get cached), or
by using a file of string, and Seek.

The originator has given extra information; only a fraction of the
questions will get asked.

If the fraction is small, just select the number at random, and use an
array of booleans, or a set, to track which are already asked; repeating
the choice until a new number is obtained.

If the fraction is large, deal an array representing all questions, and
use as many as are needed starting from the beginning (or end).

The dividing line between small & large will depend on the detailed
effectiveness of the routines used; one might guess 50%.

On a modern PC, for the sort of numbers involved, any reasonable correct
method will be fast enough.

--
? 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:Random file access for a quiz program


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

Quote
>[Almost] never move more than once any item larger than a single
>instruction will handle on the course of sorting, shuffling, or dealing;
>one can adjust indexes or pointers instead, and, if really necessary,
>re-order accordingly later.

There are 100 questions, it will take a very small anount of
time.

Quote
>Never load an array with sequential numbers for shuffling, as one can
>deal them faster with the method given by Horst Kraemer and quoted in
>TSFAQP #140.

There are 100 questions, it will take a very small anount of
time.

Quote
>In this case, only one question need be accessed at a time, and it can
>be accessed direct from disc without significant delay on a modern PC+OS
>- either by simple read through a text file (which will get cached), or
>by using a file of string, and Seek.

Seeking will probably take a lot more time than the other
methods.

Re:Random file access for a quiz program


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

Quote
>Never load an array with sequential numbers for shuffling, as one can
>deal them faster with the method given by Horst Kraemer and quoted in
>TSFAQP #140.

You're right, it is faster - with TP7 on a 400 MHz Celeron, it
saves you 0.0000013 seconds when shuffling 52 integers!!  Do it
a million times and it will save you over 1 whole second!!!
(unless you have a 533 or faster CPU).

Anyhow, the point of setting the array sequentially was to avoid
having the strings in memory and moving them.

Re:Random file access for a quiz program


Quote
In article <i4c8ht0398voo4j9n21e7ju2gh2obgm...@4ax.com>, Jud McCranie wrote:
> Dr John Stockton <s...@merlyn.demon.co.uk> wrote:

>>Never load an array with sequential numbers for shuffling, as one can
>>deal them faster with the method given by Horst Kraemer and quoted in
>>TSFAQP #140.

> You're right, it is faster - with TP7 on a 400 MHz Celeron, it
> saves you 0.0000013 seconds when shuffling 52 integers!!  Do it
> a million times and it will save you over 1 whole second!!!
> (unless you have a 533 or faster CPU).

Read slashdot from a few days ago. A lot of people consider 200 ms already
as lag.

Re:Random file access for a quiz program


mar...@toad.stack.nl (Marco van de Voort) wrote:

Quote
>Read slashdot from a few days ago. A lot of people consider 200 ms already
>as lag.

The user can sometimes notice that - 2/10 of a second.  I
recently got a screen update down from 0.39 sec to 0.1 sec, and
it makes a noticeable difference.

The method discussed here saves 10 clock cycles per item
shuffled on a P-II, maybe fewer on a P-III.  Shuffling 100 items
on a GHz machine means that the first question gets up there
0.000001 second faster.

Re:Random file access for a quiz program


"Marco van de Voort" <mar...@toad.stack.nl> wrote in message

Quote

> Read slashdot from a few days ago. A lot of people consider 200 ms already
> as lag.

200ms makes a hell of a lot of difference where online games are concerned,
but in a simple DOS-based program, it'd be hardly noticeable.

--
-- EvilBill[AGQx]
All your .sig file are belong to us.
ICQ: 37464244

Re:Random file access for a quiz program


JRS:  In article <i4c8ht0398voo4j9n21e7ju2gh2obgm...@4ax.com>, seen in
news:comp.lang.pascal.borland, Jud McCranie
<jud.mccra...@mindspring.com> wrote at Tue, 29 May 2001 19:33:22 :-

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

>>Never load an array with sequential numbers for shuffling, as one can
>>deal them faster with the method given by Horst Kraemer and quoted in
>>TSFAQP #140.

>You're right, it is faster - with TP7 on a 400 MHz Celeron, it
>saves you 0.0000013 seconds when shuffling 52 integers!!  Do it
>a million times and it will save you over 1 whole second!!!
>(unless you have a 533 or faster CPU).

From time to time, I still use a machine which I believe to have either
a low-power 8 MHz 8086-2 or an equivalent NEC V30 - it is my most
reliable machine, having served for 13 years without failure.  A memory
cycle is 0.5 us.  Most of my programming is on a 33 MHz 486 - it is
*absolutely impossible* for a program on that machine to harm this
machine, and vice versa.

Quote
>Anyhow, the point of setting the array sequentially was to avoid
>having the strings in memory and moving them.

Which is the most important point; and was made in a post of yours
subsequent to that to which I was responding.  Nevertheless, why
recommend filling and shuffling when dealing is in TS's FAQ, is less
code, and is quicker?

--
? 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.

Go to page: [1] [2]

Other Threads