Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Общие вопросы Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 25.05.2019, 18:38   #1
EverMan32
Новичок
Джуниор
 
Регистрация: 28.03.2019
Сообщений: 3
По умолчанию Рандомный вывод вопросов с исключением повторений

Здравствуйте, необходимо сделать рандомный вывод вопросов на форму, у меня в программе реализована последовательная загрузка одного за другим, при этом необходимо исключить повторения. Внизу идёт подсчёт правильных ответов.Пробовал делать в процедуре WriteVopros Num:=random(n); но при этом нарушается нумерация на форме Вопрос№1 и идёт не по порядку, а по номеру теста, который появился, а также сбивается подсчёт результатов.
Код:
unit Test;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, Buttons, ExtCtrls, Book_Test, Prepod, Student, jpeg;

type
  TForm5 = class(TForm)
    Label1: TLabel;
    Label2: TLabel;
    Image1: TImage;
    RadioGroup1: TRadioGroup;
    BitBtn1: TBitBtn;
    Label3: TLabel;
    BitBtn2: TBitBtn;
    procedure BitBtn2Click(Sender: TObject);
    procedure FormShow(Sender: TObject);
    procedure WriteVopros(k:integer);
    procedure BitBtn1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form5: TForm5;
  Tst:array[1..50] of Vopros;
  n,Sum,Num:integer;
  res:string;

implementation

{$R *.dfm}

procedure TForm5.WriteVopros(k:integer);
var i:integer;
begin
  //Вывод вопроса № k на форму:
  //Номер вопроса:
  Label1.Caption:='Вопрос №'+IntToStr(k)+':';
  //Текст вопроса:
  Label2.Caption:=Tst[k].Text;
  //Рисунок к вопросу:
try
  if Tst[k].FileRis<>'' then
    Image1.Picture.LoadFromFile('Test/'+Tst[k].FileRis)
  else
    Image1.Visible:=false;
except
  //Image1.Picture.LoadFromFile('Test/AN00790_.WMF');
  showmessage('Не найден файл указанного рисунка к вопросу!');
end;
  //Варианты ответов:
  RadioGroup1.Items.Clear;
  for i:=1 to 4 do
    RadioGroup1.Items.Add(Tst[k].Variant[i]);
  for i:=0 to 3 do
    RadioGroup1.Buttons[i].WordWrap:=true;
  RadioGroup1.ItemIndex:=-1;
  //Текуший результат:
  res:='Результат. Правильных ответов: '+IntToStr(Sum)+' из '+IntToStr(k-1);
  if k>1 then
    res:=res+' ('+IntToStr(Sum*100 div (k-1))+'%).';
  Label3.Caption:=res;
end;

procedure TForm5.FormShow(Sender: TObject);
begin
  //Открытие формы
  //Открыть файл теста, прочитать вопросы теста из файла в массив:
  //s - имя файла с выбранным тестом
 Caption:=Caption+' '+SpisStud[NumStud].FIO;
 try
  AssignFile(ftest,s);
  Reset(ftest);
  n:=0;
  while not eof(ftest) do begin
    inc(n);
    read(ftest,Tst[n]);
  end;
  CloseFile(ftest);
  BitBtn2.Enabled:=False;
  BitBtn1.Enabled:=True;
  //Вывод 1-го вопроса:
  Num:=1;
  Sum:=0;
  WriteVopros(Num);
 except
   showmessage('Не найден файл теста!');
   close;
 end;
end;

procedure TForm5.BitBtn1Click(Sender: TObject);
var rec:boolean;
begin
  //Нажатие на кнопку "Далее"
  //Проверка правильности ответа на текущий вопрос:
  if RadioGroup1.ItemIndex+1=Tst[Num].NumVern then inc(Sum)
  else showmessage(Tst[Num].Help);
  //Вывод следуещего вопроса:
  inc(Num);
  if Num<=n then WriteVopros(Num)
  else begin //Тест закончен
     BitBtn2.Enabled:=True;
     BitBtn1.Enabled:=False;
     res:='Результат. Правильных ответов: '+IntToStr(Sum)+' из '+IntToStr(n);
     res:=res+' ('+IntToStr(Sum*100 div n)+'%). ';
     //Запись результата тестирования в файл:
     Repeat
     rec:=True;
     try
       AssignFile(frestest,'Data/ResTest.dat');
       Reset(frestest);
       Seek(frestest,FileSize(frestest));
       restest.Group:=SpisStud[NumStud].Group;
       restest.FIO:=SpisStud[NumStud].FIO;
       restest.DateTest:=Date;
       restest.NumTest:=Form4.ListBox1.ItemIndex+1;
       restest.ResProcent:=Sum*100 div n;
       write(frestest,restest);
       CloseFile(frestest);
     except
       Rewrite(frestest);
       rec:=False;
     end;
     Until rec;
     res:=res+'Тестирование закончено.';
     Label3.Caption:=res;
  end;
end;

procedure TForm5.BitBtn2Click(Sender: TObject);
begin
  //Выход. Закрыть форму "Тестирование":
  Close;
end;

end.
EverMan32 вне форума Ответить с цитированием
Старый 25.05.2019, 21:56   #2
Serge_Bliznykov
Старожил
 
Регистрация: 09.01.2008
Сообщений: 26,238
По умолчанию

Вы предоставили неполную информацию.
Нет описания структуры вопроса (Vopros). Неизвестно где описан ftest и т.д.

но, если я правильно Вас понял, вашу проблему можно решить и достаточно просто.
Нужно просто перемешать вопросы в массиве после их чтения:
Код:
procedure TForm5.FormShow(Sender: TObject);
var 
  i,k:integer;
  buf : Vopros;
begin
  //Открытие формы
  //Открыть файл теста, прочитать вопросы теста из файла в массив:
  //s - имя файла с выбранным тестом
 Caption:=Caption+' '+SpisStud[NumStud].FIO;
 try

  AssignFile(ftest,s);
  Reset(ftest);
  n:=0;
  while not eof(ftest) do begin
    inc(n);
    read(ftest,Tst[n]);
  end;
  CloseFile(ftest);

  Randomize;

  //----------перемешать-------------
  for i:=1 to n-1 do
  begin
   k:= Random(n-i+1)+i;
   if k<>i then begin
     buf:=Tst[i];
     Tst[i]:=Tst[k];
     Tst[k]:=buf;
   end;
  end;

  BitBtn2.Enabled:=False;
  BitBtn1.Enabled:=True;
  //Вывод 1-го вопроса:
  Num:=1;
  Sum:=0;
  WriteVopros(Num);
 except
   showmessage('Не найден файл теста!');
   close;
 end;
end;
Serge_Bliznykov вне форума Ответить с цитированием
Старый 25.05.2019, 22:10   #3
EverMan32
Новичок
Джуниор
 
Регистрация: 28.03.2019
Сообщений: 3
По умолчанию

Цитата:
Сообщение от Serge_Bliznykov Посмотреть сообщение
Вы предоставили неполную информацию.
Нет описания структуры вопроса (Vopros). Неизвестно где описан ftest и т.д.

но, если я правильно Вас понял, вашу проблему можно решить и достаточно просто.
Нужно просто перемешать вопросы в массиве после их чтения:
Код:
procedure TForm5.FormShow(Sender: TObject);
var 
  i,k:integer;
  buf : Vopros;
begin
  //Открытие формы
  //Открыть файл теста, прочитать вопросы теста из файла в массив:
  //s - имя файла с выбранным тестом
 Caption:=Caption+' '+SpisStud[NumStud].FIO;
 try

  AssignFile(ftest,s);
  Reset(ftest);
  n:=0;
  while not eof(ftest) do begin
    inc(n);
    read(ftest,Tst[n]);
  end;
  CloseFile(ftest);

  Randomize;

  //----------перемешать-------------
  for i:=1 to n-1 do
  begin
   k:= Random(n-i+1)+i;
   if k<>i then begin
     buf:=Tst[i];
     Tst[i]:=Tst[k];
     Tst[k]:=buf;
   end;
  end;

  BitBtn2.Enabled:=False;
  BitBtn1.Enabled:=True;
  //Вывод 1-го вопроса:
  Num:=1;
  Sum:=0;
  WriteVopros(Num);
 except
   showmessage('Не найден файл теста!');
   close;
 end;
end;
Спасибо, работает, а я начинал всё усложнять, присваивая Num:=random(n), при этом вопросы иногда повторялись, да и плохо считались результаты, а вы так грамотно сделали.
EverMan32 вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
VBS как написать цикл Do While... Loop с исключением повторений Alex_Dom Microsoft Office Excel 5 15.02.2019 10:59
Рандомный вывод GRFed PHP 5 19.07.2017 09:15
Рандомный вывод вопросов в тесте Алексей_2012 Общие вопросы Delphi 12 25.05.2016 19:28
Создать рандомный массив без повторений элементов KYZ Помощь студентам 8 09.10.2014 11:54
Рандомный вывод Forrest Gamp Общие вопросы C/C++ 6 10.02.2008 15:03