• Постановка задачи
  • Структура базы вопросов и ответов
  • Разработка формы
  • Разработка программного кода
  • Полный исходный код модуля
  • Глава 13

    Тест

    Постановка задачи

    Разработать программу для тестирования знаний в разных областях. Пользователь должен ответить на несколько вопросов, которые случайным образом выбираются из общей базы вопросов. После того как пользователь ответил на все вопросы, программа должна высчитать и выдать результат прохождения теста — процент правильных ответов. Также необходимо дать возможность пользователю подключать внешние файлы, содержащие вопросы и варианты ответов к ним. Для того чтобы пользователь не смог прочитать правильные ответы, следует зашифровать файл с вопросами и ответами.

    Структура базы вопросов и ответов

    Перед тем как разработать сам тест, разберем содержимое файла, в котором будут храниться вопросы и варианты ответов к ним. Это будет ini-файл следующей структуры:

    [num]

    num=количество вопросов в базе


    [Q]

    0=Первый вопрос

    1=Второй вопрос


    [А]

    0=0твет к первому вопросу

    1=0твет ко второму вопросу


    [W1]

    0=Неправильный вариант к первому вопросу

    1= Неправильный вариант ко второму вопросу


    [W2]

    0=Неправильный вариант к первому вопросу

    1= Неправильный вариант ко второму вопросу


    [W3]

    0=Неправильный вариант к первому вопросу

    1=Неправильный вариант ко второму вопросу

    В этом ini-файле шесть разделов: num, Q, A, W1, W2 и W3. Как вы понимаете, если кто-то заглянет в этот файл, то уже через несколько минут он будет знать правильные ответы на все вопросы. А если он этот файл подкорректирует, то и вовсе будет получать только правильные варианты ответов. Для того чтобы этого не случилось, мы будем шифровать нашу базу вопросов. Это можно сделать с помощью программы Блокнот-шифровальщик, рассмотренной в главе 7. Для шифрования выберем небольшое смещение, например, 101. После того как вы создали все вопросы и варианты ответов к ним, не забудьте указать количество вопросов в разделе num. После этого зашифруйте базу, используя смещение 101.

    ⊚ Пример зашифрованной базы вопросов/ответов можно найти на прилагаемом к книге компакт-диске в файле Chapter_13\comp.ini.

    Разработка формы

    Создайте новый проект Delphi. Присвойте свойству Caption формы значение Tester, а свойству BorderStyle — bsNone. У верхнего края формы разместите компонент Label категории Standard, присвоив его свойству Caption значение Первый вопрос:.

    Ниже разместите компонент Memo категории Standard, с помощью которого мы будем отображать текущий вопрос. Присвойте свойству Memo1.Readonly значение True, чтобы пользователь не мог изменить текст вопроса.

    Под вопросом будут расположены варианты ответов. Разместите под компонентом Memo1 компонент RadioGroup (группа переключателей) категории Standard и присвойте его свойству Caption значение Варианты ответов:. Разместите на компоненте RadioGroup1 четыре компонента RadioButton (переключатели) категории Standard. Очистите для каждого из них свойство Caption, а свойству Name присвойте значения an1, an2, an3 и an4 соответственно.

    В любом месте формы разместите компонент Label, который изначально будет невидимым. Он будет служить для отображения результатов и в последствии будет растянут на всю форму. Установите для него свойства согласно табл. 13.1.

    Таблица 13.1. Свойства компонента Label, отображающего результат теста

    Свойство Значение Пояснение
    Alignment taCenter Выравнивание текста — по центру
    Color clBlack Цвет фона — черный
    Font.Color clRed Цвет текста — красный
    Font.Name Arial Название шрифта
    Font.Size 26 Размер шрифта
    Font.Style [fsBold] Начертание шрифта — полужирное
    Visible False При запуске программы метка невидима

    Осуществлять переход к следующему вопросу мы будем с помощью панелей. Разместите под вариантами ответов пять компонентов Panel категории Standard. Для каждой из них присвойте свойству Caption значение Следующий вопрос>>>>>, свойству Color — значение clMaroon, а свойству Font.Color — значение clWhite. Присвойте им имена (свойство Name) p1, р2, p3, р4 и р5. Для того чтобы убрать выпуклость и привести панель к виду стильной кнопки, изменим значение свойства BevelInner на bvRaised, а свойства BevelOuter — на bvLowered. Для всех панелей, кроме p1, присвойте свойству Visible значение False (изначально будет видна только первая панель).

    Поскольку в программе будет предусмотрена возможность динамической загрузки базы вопросов/ответов, нам понадобится диалоговое окно открытия файла. Для этого разместим на форме компонент OpenDialog категории Dialogs и присвоим ему имя Open1 (свойство Name). Кроме того, определите в свойстве Filter следующий фильтр: ini-файлы|*.ini|Все файлы|*.*.

    Теперь разработаем меню программы. Для этого разместите на форме компонент MainMenu категории Standard и создайте меню в соответствии с рис. 13.1.

    ⇖ Разработка меню рассматривается в главе 6, "Программа просмотра рисунков".

    Рис. 13.1. Меню для программы-теста

    Полученная форма должна примерно соответствовать рис. 13.2.

    Рис. 13.2. Форма программы-теста

    Разработка программного кода

    Для начала, объявим все глобальные переменные:

    var

     Form1: TForm1;

     i, a, n, balls, vopr: integer; {различные счетчики и переменные для подсчета баллов}

     dir, dir2, ss, zz, yes: string; {путь к файлу с вопросами, к программе и расшифрованной базе}

     win: TIniFile; //переменная для работы с ini-файлами

     mass: array[1..100] of integer; {содержит номера уже заданных вопросы, чтобы они не повторялись}

     f1, f2: file of char; //переменные для работы с файлами

     сор: char; //для работы с каждым символом отдельно

    Добавим в раздел uses ссылку на модуль IniFiles, который потребуется для работы с классом TIniFile. Мы также разработаем четыре собственные процедуры. Объявим их как закрытые члены класса формы:

    type

    TForm1 = class(TForm)

     …

    private

     { Private declarations }

     procedure start; //начало теста

     procedure question_select; //выбор вопроса

     procedure vars(var variant: integer); {сортировка и определение правильного варианта ответа}

     procedureverno(); {проверка: правильно ли ответил пользователь}

    public

     { Public declarations }

    end;

    Теперь создадим сами процедуры в разделе implementation. Процедура Start:

    procedure TForm1.start();

    begin

     Randomize; //Включаем генератор случайных чисел

     for i:=1 to n do mass[i] := 0; //n – количеству вопросов

     {$I-} //отключаем контроль ошибок ввода/вывода.

     //делаем все элементы видимыми для пользователя

     Memo1.Visible:= True;

     RadioGroup1.Visible:= True;

     Label1.Visible:= True;

     an1.Visible:= True;

     an2.Visible:= True;

     an3.Visible:= True;

     an4.Visible:= True;

     p1.Visible:= True;

     p2.Visible:= False;

     p3.Visible:= False;

     p4.Visible:= False;

     p5.Visible:= False;

     balls:= 0;

     Label2.Visible:= False; //прячем результаты

     Label1.Caption:= 'Первый вопрос:';

     dir2:= 'C:\base.bsd'; //путь к расшифрованной базе

     //копируем зашифрованную базу на диск С:

     CopyFile(PChar(ss), PChar(dir2), True);

     //связываем переменную f1 с зашифрованным ini-файлом

     AssignFile(f1, ss);

     //связываем переменную f2 с файлом C:\base.bsd

     AssignFile(f2, dir2);

     Reset(f1); //открываем первый файл на чтение

     Rewrite(f2); //второй – на запись

     while not Eof(fl) do

     begin //пока не достигнут конец первого файла

      Read(f1, cop); //считываем один символ из файла

      сор:= Chr(Ord(cop) xor 101); //расшифровываем символ

      Write(f2, сор); //записываем расшифрованный символ в файл

     end;

     CloseFile(f1); //закрываем первый файл

     CloseFile(f2); //закрываем второй файл

     {$I+} //включаем контроль ошибок ввода/вывода

     Win:= TIniFile.Create(dir2); //работаем с ini-файлом

     //считываем количество вопросов в базе

     ss:= Win.ReadString('num', 'num', ss);

     //преобразовываем строку в число и записываем значение в n

     n:= StrToInt(ss);

     vopr:=Random(4) + 1;

    //случайное число от 1 до 4

     vars(vopr); {передаем число процедуре vars, которая сортирует варианты ответов}

    end;

    Эта процедура начинает игру. Сначала делаем все элементы видимыми и прячем метку, отображающую результат прохождения теста. Затем открываем файл, содержащий вопросы, и считываем из него по одному символу. Каждый байт расшифровывается особо и записывается в отдельный файл. Далее мы работаем с расшифрованным файлом как с обычным ini-файлом. Первое, что мы считываем, — это общее количество вопросов в базе.

    Теперь очередь процедуры question_select:

    procedure TForm1.question_seleсt();

    label ran; //метка ran для быстрого перехода

    begin

     Randomize;

    ran:

     a:=Random(n); //выбираем случайный вопрос из базы

     //проверяем: не задавали ли мы этот вопрос ранее

     for i:=1 to n do

      if mass[i] = a then goto ran;

     for i:=1 to n do

      if mass[i] = 0 then begin

       mass[i]:= а; {записываем номер вопроса, чтобы не задавать его больше }

       Break;

      end;

     //сбрасываем флажки со всех вариантов ответов

     an1.Checked:= False;

     an2.Checked:= False;

     an3.Checked:= False;

     an4.Checked:= False;

    end;

    Эта процедура случайным образом выбирает вопрос. Затем выполняется проверка: не задавался ли этот вопрос ранее. Если мы нашли вопрос, который еще не был задан, то задаем его и помечаем как уже заданный, чтобы не задавать его больше в текущей сессии.

    Процедура verno:

    procedure TForm1.verno();

    begin

     if an1.Checked then

      if yes = an1.Caption then balls:= balls + 1;

     if an2.Checked then

      if yes = an2.Caption then balls:= balls + 1;

     if an3.Checked then

      if yes = an3.Caption then balls:= balls + 1;

     if an4.Checked then

      if yes = an4.Caption then balls:= balls + 1;

    end;

    Здесь мы сравниваем правильный ответ с вариантом, который дал пользователь, и в случае правильного ответа пополняем счетчик правильных ответов.

    Процедура vars:

    procedure TForm1.vars(var variant: integer);

    begin

     //вызываем процедуру выбора случайного вопроса question_select();

     case variant of

     1:

      begin

       Win:= TIniFile.Create(dir2); //открываем ini-файл

       //считываем вопрос

       Memo1.Text:= Win.ReadString('Q', IntToStr(a), Memo1.Text);

       //считываем правильный вариант ответа

       an1.Caption:= Win.ReadString('A', IntToStr(a), an1.Caption);

       //считываем три неверных варианта к данному вопросу

       an2.Caption:= Win.ReadString('W1', IntToStr(a), an2.Caption);

       an3.Caption:= Win.ReadString('W2', IntToStr(a), an3.Caption);

       an4.Caption:= Win.ReadString('W3', IntToStr(a), an4.Caption);

       Win.Free; //освобождаем ini-файл

       //помечаем первый вариант как правильный

       yes:= an1.Caption;

      end;

     2:

      begin

       Win:= TIniFile.Create(dir2);

       Memo1.Text:= Win.ReadString('Q', IntToStr(a), Memo1.Text);

       an2.Caption:= Win.Readstring('A', IntToStr(a), an2.Caption);

       an1.Caption:= Win.Readstring('W1', IntToStr(a), an1.Caption);

       an3.Caption:= Win.ReadString('W2', IntToStr(a), an3.Caption);

       an4.Caption:= Win.ReadString('W3', IntToStr(a), an4.Caption);

       Win.Free;

       yes: = an2.Caption;

      end;

     3:

      begin

       Win:= TIniFile.Create(dir2);

       Memo1.Text:= Win.ReadString('Q', IntToStr(a), Memo1.Text);

       an3.Caption:= Win.ReadString('A', IntToStr(a), an3.Caption);

       an2.Caption:= Win.ReadString('W1', IntToStr(a), an2.Caption);

       an1.Caption:= Win.ReadString('W2', IntToStr(a), an1.Caption);

       an4.Caption:= Win.ReadString('W3', IntToStr(a), an4.Caption);

       Win.Free;

       yes:= an3.Caption;

      end;

     4:

      begin

       Win:= TIniFile.Create(dir2);

       Memo1.Text:= Win.ReadString('Q', IntToStr(a), Memo1.Text);

       an4.Caption:= Win.ReadString('A', IntToStr(a), an4.Caption);

       an2.Caption:= Win.ReadString('Wl', IntToStr(a), an2.Caption);

       an3.Caption:= Win.ReadString('W2', IntToStr(a), an3.Caption);

       an1.Caption:= Win.ReadString('W3', IntToStr(a), an1.Caption);

       Win.Free;

       yes:= an4.Caption;

      end;

     end;

    end;

    Здесь мы вначале запускаем процедуру выбора вопроса. Потом проверяем: какой вариант ответа является правильным. Затем считываем вопрос и варианты ответов к нему. Сортируем и отображаем все это на форме.

    Обработчик события создания главной формы будет выглядеть следующим образом:

    procedure TForm1.FormCreate(Sender: TObject);

    begin

     Randomize;

     //получаем каталог, в котором находится наша программа

     dir:= GetCurrentDir;

     ss:= dir + '\comp.ini'; //путь к базе вопросов

     zz:= ss;

     start(); //начинаем тест

    end;

    Теперь создадим обработчик события главной формы OnDestroy (возникает при выходе из программы):

    procedure TForm1.FormDestroy(Sender: TObject);

    begin

     DeleteFile('c:\base.bsd'); //удаляем расшифрованную базу

    end;

    Теперь обрабатываем команды меню. Обработчик события OnClick для пункта Игра→Заново:

    procedure TForm1.N1Click(Sender: TObject);

    begin

     Randomize;

     ss:= zz;

     start(); //начало теста

    end;

    Поскольку у нас весь основной код вынесен в процедуры, теперь достаточно только вызвать процедуру начала игры.

    Обработчик события OnClick для пункта меню Игра→Загрузить базу:

    procedure TForm1.N2Click(Sender: TObject);

    begin

     Randomize;

     //начинаем обзор с текущего каталога

     Open1.InitialDir:= GetCurrentDir;

     if not Open1.Execute then ShowMessage('Вы не выбрали файл!')

     else begin

      ss:= Open1.FileName; //открываем выбранный файл

      zz:= ss; //запоминаем путь к базе

      start(); //начинаем тест

     end;

    end;

    Здесь мы предлагаем пользователю выбрать через диалоговое окно обзора ini– или любой другой файл, в котором содержатся зашифрованные вопросы и варианты ответов. Когда пользователь выбрал файл, мы запускаем процедуру start и, тем самым, начинаем тест.

    Обработчик события OnClick для пункта меню Игра→Выход:

    procedure TForm1.N4Click(Sender: TObject);

    begin

     Halt; //выход из программы

    end;

    Теперь обработаем щелчок мышью на панели p1:

    procedure TForm1.p1Click(Sender: TObject);

    begin

     Label1.Caption:= 'Второй вопрос:';

     verno(); //принимаем вариант ответа

     p1.Visible:= False; //убираем первую панель

     р2.Visible:=True; //активизируем вторую панель

     vopr:= Random(4) +1; //выбираем случайный вариант ответа

     vars(vopr); //задаем вопрос

    end;

    Здесь мы вначале изменяем заголовок на "Второй вопрос:", после чего принимаем вариант ответа, выбранный пользователем, вызывая процедуру verno.

    Затем готовим форму ко второму вопросу: прячем первую панель и выводим вторую. Вызываем процедуру vars, которая выбирает вопрос и отображает его вместе с вариантами ответа.

    Обработаем щелчок мышью на второй панели:

    procedure TForm1.p2Click(Sender: TObject);

    begin

     Label1.Caption:= 'Третий вопрос:';

     verno();

     p2.Visible:= False;

     p3.Visible:= True;

     vopr:= Random(4) + 1;

     vars(vopr);

    end;

    Здесь происходит то же самое, что и для панели p1, только надпись метки принимает значение "Третий вопрос", мы прячем вторую "кнопку" и активизируем третью для следующего вопроса.

    Аналогичные обработчики события OnClick создаем для третьей и четвертой панелей:

    procedure TForm1.p3Click(Sender: TObject);

    begin

     Label1.Caption:= 'Четвертый вопрос:';

     verno();

     р3.Visible:= False;

     p4.Visible:= True;

     vopr:= Random(4) + 1;

     vars(vopr);

    end;


    procedure TForm1.p4Click(Sender: TObject);

    begin

     Label1.Caption:= 'Пятый вопрос:';

     verno();

     p4.Visible:= False;

     p5.Visible:= True;

     vopr:= Random(4) + 1;

     vars(vopr);

    end;

    Для пятой (последней) панели обработчик события OnClick будет выглядеть несколько иначе:

    procedure TForm1.p5Click(Sender: TObject);

    begin

     //проверяем правильность ответа на последний вопрос

     verno() ;

     //узнаем, сколько баллов набрал пользователь

     ss:= IntToStr(balls);

     //делаем почти все компоненты невидимыми

     Memo1.Visible:= False;

     р5.Visible:= False;

     RadioGroup1.Visible:= False;

     Label1.Visible:= False;

     an1.Visible:= False;

     an2.Visible:= False;

     an3.Visible:= False;

     an4.Visible:= False;

     Label2.Visible:=True;//показываем метку с результатом

     Label2.Align:= alClient;//растягиваем ее на всю форму

     //Отображаем процент правильных ответов

     Label2.Caption:= 'Правильных ответов' + IntToStr(balls*(100 div 5))+'%';

    end;

    После проверки правильности ответа на последний вопрос, мы прячем почти все компоненты на форме, оставляя видимой только метку Label2 для вывода результата и меню, чтобы можно было продолжить работу с программой. С помощью метки мы отображаем процент правильных ответов пользователя по формуле: "количество правильных ответов * (100 / количество заданных вопросов)". Пример отображения результата теста представлен на рис. 13.3.

    Рис. 13.3. Отображение результата теста

    Единственное, что осталось сделать, — реализовать имитацию нажатия кнопки при щелчке на панели мышью. Для того чтобы "оживить" панель, для нее следует создать обработчики двух событий: OnMouseDown и OnMouseUp. Первое событие возникает при щелчке мышью, а второе — при отпускании кнопки мыши. Для панели pi эти обработчики будут выглядеть следующим образом:

    procedure TForm1.p1MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);

    begin

     p1.BevelInner:= bvLowered;

     p1.BevelOuter:= bvRaised;

    end;


    procedure TForm1.p1MouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);

    begin

     p1.BevelInner:=bvRaised;

     p1.BevelOuter:=bvLowered;

    end;

    Для всех остальных панелей обработчики этих событий будут выглядеть аналогичным образом за исключением того, что имя p1 потребуется изменить на имя р2, p3, р4 или р5.

    Программа тестирования в действии показана на рис. 13.4.

    Рис. 13.4. Программа тестирования в действии

    Полный исходный код модуля

    Полный код модуля программы-теста представлен в листинге 13.1.

    Листинг 13.1. Модуль программы-теста

    unit Unit1;


    interface


    uses

     Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, ExtCtrls, StdCtrls, IniFiles, jpeg, Menus;


    type TForm1 = class(TForm)

     Memo1: TMemo;

     RadioGroup1: TRadioGroup;

     p1: TPanel;

     p2: TPanel;

     p3: TPanel;

     p4: TPanel;

     p5: TPanel;

     an1: TRadioButton;

     an2: TRadioButton;

     an3: TRadioButton;

     an4: TRadioButton;

     Label1: TLabel;

     Label2: TLabel;

     MainMenu1: TMainMenu;

     N1: TMenuItem;

     N2: TMenuItem;

     N3: TMenuItem;

     N4: TMenuItem;

     Open1: TOpenDialog;

     procedure FormCreate(Sender: TObject);

     procedure p1Click(Sender: TObject);

     procedure p2Click(Sender: TObject);

     procedure p3Click(Sender: TObject);

     procedure p4Click(Sender: TObject);

     procedure p5Click(Sender: TObject);

     procedure Image1Click(Sender: TObject);

     procedure p1MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);

     procedure p1MouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);

     procedure p2MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);

     procedure p2MouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);

     procedure p3MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);

     procedure p3MouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);

     procedure p4MouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);

     procedure p4MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);

     procedure p5MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);

     procedure p5MouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);

     procedure N1Click(Sender: TObject);

     procedure N2Click(Sender: TObject);

     procedure N4Click(Sender: TObject);

     procedure FormDestroy(Sender: TObject);

    private

     { Private declarations }

     procedure start; //начало теста

     procedure question_select; //выбор вопроса

     procedure vars(var variant: integer); {сортировка и определение правильного варианта ответа}

     procedureverno(); {проверка: правильно ли ответил пользователь}

    public

     { Public declarations }

    end;


    var

     Form1: TForm1;

     i, a, n, balls, vopr: integer; {различные счетчики и переменные для подсчета баллов}

     dir, dir2, ss, zz, yes: string; {путь к файлу с вопросами, к программе и расшифрованной базе}

     win: TIniFile; //переменная для работы с ini-файлами

     mass: array[1..100] of integer; {содержит номера уже заданных вопросы, чтобы они не повторялись}

     f1, f2: file of char; //переменные для работы с файлами

     сор: char; //для работы с каждым символом отдельно


    implementation

    {$R *.dfm}


    procedure TForm1.vars(var variant: integer);

    begin

     //вызываем процедуру выбора случайного вопроса question_select();

     case variant of

     1:

      begin

       Win:= TIniFile.Create(dir2); //открываем ini-файл

       //считываем вопрос

       Memo1.Text:= Win.ReadString('Q', IntToStr(a), Memo1.Text);

       //считываем правильный вариант ответа

       an1.Caption:= Win.ReadString('A', IntToStr(a), an1.Caption);

       //считываем три неверных варианта к данному вопросу

       an2.Caption:= Win.ReadString('W1', IntToStr(a), an2.Caption);

       an3.Caption:= Win.ReadString('W2', IntToStr(a), an3.Caption);

       an4.Caption:= Win.ReadString('W3', IntToStr(a), an4.Caption);

       Win.Free; //освобождаем ini-файл

       //помечаем первый вариант как правильный

       yes:= an1.Caption;

      end;

     2:

      begin

       Win:= TIniFile.Create(dir2);

       Memo1.Text:= Win.ReadString('Q', IntToStr(a), Memo1.Text);

       an2.Caption:= Win.Readstring('A', IntToStr(a), an2.Caption);

       an1.Caption:= Win.Readstring('W1', IntToStr(a), an1.Caption);

       an3.Caption:= Win.ReadString('W2', IntToStr(a), an3.Caption);

       an4.Caption:= Win.ReadString('W3', IntToStr(a), an4.Caption);

       Win.Free;

       yes: = an2.Caption;

      end;

     3:

      begin

       Win:= TIniFile.Create(dir2);

       Memo1.Text:= Win.ReadString('Q', IntToStr(a), Memo1.Text);

       an3.Caption:= Win.ReadString('A', IntToStr(a), an3.Caption);

       an2.Caption:= Win.ReadString('W1', IntToStr(a), an2.Caption);

       an1.Caption:= Win.ReadString('W2', IntToStr(a), an1.Caption);

       an4.Caption:= Win.ReadString('W3', IntToStr(a), an4.Caption);

       Win.Free;

       yes:= an3.Caption;

      end;

     4:

      begin

       Win:= TIniFile.Create(dir2);

       Memo1.Text:= Win.ReadString('Q', IntToStr(a), Memo1.Text);

       an4.Caption:= Win.ReadString('A', IntToStr(a), an4.Caption);

       an2.Caption:= Win.ReadString('Wl', IntToStr(a), an2.Caption);

       an3.Caption:= Win.ReadString('W2', IntToStr(a), an3.Caption);

       an1.Caption:= Win.ReadString('W3', IntToStr(a), an1.Caption);

       Win.Free;

       yes:= an4.Caption;

      end;

     end;

    end;


    procedure TForm1.start();

    begin

     Randomize; //Включаем генератор случайных чисел

     for i:=1 to n do mass[i] := 0; //n – количеству вопросов

     {$I-} //отключаем контроль ошибок ввода/вывода.

     //делаем все элементы видимыми для пользователя

     Memo1.Visible:= True;

     RadioGroup1.Visible:= True;

     Label1.Visible:= True;

     an1.Visible:= True;

     an2.Visible:= True;

     an3.Visible:= True;

     an4.Visible:= True;

     p1.Visible:= True;

     p2.Visible:= False;

     p3.Visible:= False;

     p4.Visible:= False;

     p5.Visible:= False;

     balls:= 0;

     Label2.Visible:= False; //прячем результаты

     Label1.Caption:= 'Первый вопрос:';

     dir2:= 'C:\base.bsd'; //путь к расшифрованной базе

     //копируем зашифрованную базу на диск С:

     CopyFile(PChar(ss), PChar(dir2), True);

     //связываем переменную f1 с зашифрованным ini-файлом

     AssignFile(f1, ss);

     //связываем переменную f2 с файлом C:\base.bsd

     AssignFile(f2, dir2);

     Reset(f1); //открываем первый файл на чтение

     Rewrite(f2); //второй – на запись

     while not Eof(fl) do

     begin //пока не достигнут конец первого файла

      Read(f1, cop); //считываем один символ из файла

      сор:= Chr(Ord(cop) xor 101); //расшифровываем символ

      Write(f2, сор); //записываем расшифрованный символ в файл

     end;

     CloseFile(f1); //закрываем первый файл

     CloseFile(f2); //закрываем второй файл

     {$I+} //включаем контроль ошибок ввода/вывода

     Win:= TIniFile.Create(dir2); //работаем с ini-файлом

     //считываем количество вопросов в базе

     ss:= Win.ReadString('num', 'num', ss);

     //преобразовываем строку в число и записываем значение в n

     n:= StrToInt(ss);

     vopr:=Random(4) + 1;

    //случайное число от 1 до 4

     vars(vopr); {передаем число процедуре vars, которая сортирует варианты ответов}

    end;


    procedure TForm1.question_seleсt();

    label ran; //метка ran для быстрого перехода

    begin

     Randomize;

    ran:

     a:=Random(n); //выбираем случайный вопрос из базы

     //проверяем: не задавали ли мы этот вопрос ранее

     for i:=1 to n do

      if mass[i] = a then goto ran;

     for i:=1 to n do

      if mass[i] = 0 then begin

       mass[i]:= а; {записываем номер вопроса, чтобы не задавать его больше }

       Break;

      end;

     //сбрасываем флажки со всех вариантов ответов

     an1.Checked:= False;

     an2.Checked:= False;

     an3.Checked:= False;

     an4.Checked:= False;

    end;


    procedure TForm1.verno();

    begin

     if an1.Checked then

      if yes = an1.Caption then balls:= balls + 1;

     if an2.Checked then

      if yes = an2.Caption then balls:= balls + 1;

     if an3.Checked then

      if yes = an3.Caption then balls:= balls + 1;

     if an4.Checked then

      if yes = an4.Caption then balls:= balls + 1;

    end;


    procedure TForm1.N2Click(Sender: TObject);

    begin

     Randomize;

     //начинаем обзор с текущего каталога

     Open1.InitialDir:= GetCurrentDir;

     if not Open1.Execute then ShowMessage('Вы не выбрали файл!')

     else begin

      ss:= Open1.FileName; //открываем выбранный файл

      zz:= ss; //запоминаем путь к базе

      start(); //начинаем тест

     end;

    end;


    procedure TForm1.FormCreate(Sender: TObject);

    begin

     Randomize;

     //получаем каталог, в котором находится наша программа

     dir:= GetCurrentDir;

     ss:= dir + '\comp.ini'; //путь к базе вопросов

     zz:= ss;

     start(); //начинаем тест

    end;


    procedure TForm1.p1Click(Sender: TObject);

    begin

     Label1.Caption:= 'Второй вопрос:';

     verno(); //принимаем вариант ответа

     p1.Visible:= False; //убираем первую панель

     р2.Visible:=True; //активизируем вторую панель

     vopr:= Random(4) +1; //выбираем случайный вариант ответа

     vars(vopr); //задаем вопрос

    end;


    procedure TForm1.p2Click(Sender: TObject);

    begin

     Label1.Caption:= 'Третий вопрос:';

     verno();

     p2.Visible:= False;

     p3.Visible:= True;

     vopr:= Random(4) + 1;

     vars(vopr);

    end;


    procedure TForm1.p3Click(Sender: TObject);

    begin

     Label1.Caption:= 'Четвертый вопрос:';

     verno();

     р3.Visible:= False;

     p4.Visible:= True;

     vopr:= Random(4) + 1;

     vars(vopr);

    end;

    procedure TForm1.p4Click(Sender: TObject);

    begin

     Label1.Caption:= 'Пятый вопрос:';

     verno();

     p4.Visible:= False;

     p5.Visible:= True;

     vopr:= Random(4) + 1;

     vars(vopr);

    end;


    procedure TForm1.p5Click(Sender: TObject);

    begin

     //проверяем правильность ответа на последний вопрос

     verno() ;

     //узнаем, сколько баллов набрал пользователь

     ss:= IntToStr(balls);

     //делаем почти все компоненты невидимыми

     Memo1.Visible:= False;

     р5.Visible:= False;

     RadioGroup1.Visible:= False;

     Label1.Visible:= False;

     an1.Visible:= False;

     an2.Visible:= False;

     an3.Visible:= False;

     an4.Visible:= False;

     Label2.Visible:=True;//показываем метку с результатом

     Label2.Align:= alClient;//растягиваем ее на всю форму

     //Отображаем процент правильных ответов

     Label2.Caption:= 'Правильных ответов' + IntToStr(balls*(100 div 5))+'%';

    end;


    procedure TForm1.N4Click(Sender: TObject);

    begin

     Halt; //выход из программы

    end;


    procedure TForm1.p1MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);

    begin

     p1.BevelInner:= bvLowered;

     p1.BevelOuter:= bvRaised;

    end;

    procedure TForm1.p1MouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);

    begin

     p1.BevelInner:=bvRaised;

     p1.BevelOuter:=bvLowered;

    end;


    procedure TForm1.p2MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);

    begin

     p2.BevelInner:= bvLowered;

     p2.BevelOuter:= bvRaised;

    end;

    procedure TForm1.p2MouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);

    begin

     p2.BevelInner:=bvRaised;

     p2.BevelOuter:=bvLowered;

    end;


    procedure TForm1.p3MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);

    begin

     p3.BevelInner:= bvLowered;

     p3.BevelOuter:= bvRaised;

    end;

    procedure TForm1.p3MouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);

    begin

     p3.BevelInner:=bvRaised;

     p3.BevelOuter:=bvLowered;

    end;


    procedure TForm1.p4MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);

    begin

     p4.BevelInner:= bvLowered;

     p4.BevelOuter:= bvRaised;

    end;

    procedure TForm1.p4MouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);

    begin

     p4.BevelInner:=bvRaised;

     p4.BevelOuter:=bvLowered;

    end;


    procedure TForm1.p5MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);

    begin

     p5.BevelInner:= bvLowered;

     p5.BevelOuter:= bvRaised;

    end;

    procedure TForm1.p5MouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);

    begin

     p5.BevelInner:=bvRaised;

     p5.BevelOuter:=bvLowered;

    end;


    procedure TForm1.N1Click(Sender: TObject);

    begin

     Randomize;

     ss:= zz;

     start(); //начало теста

    end;


    procedure TForm1.FormDestroy(Sender: TObject);

    begin

     DeleteFile('c:\base.bsd'); //удаляем расшифрованную базу

    end


    end.

    ⊚ Все файлы проекта и исполняемый файл рассмотренной программы находятся на прилагаемом к книге компакт-диске в папке Chapter_13.







     


    Главная | В избранное | Наш E-MAIL | Добавить материал | Нашёл ошибку | Наверх