Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Распределение строк по captions [D7, WinME]


Garfunkel ©   (2004-09-08 16:43:00) 

Есть текстовый файл с четырьмя строками. На форме есть 4 кнопки. Требуется:
при загрузке программы считывать эти строки и СЛУЧАЙНЫМ ОБРАЗОМ распределить их по captions этих четырех кнопок. Например, button1.caption:=3-ая строка, button2.caption:=1-ая строка... и.т.д. Причем чтобы каждый раз распределение было разным. Помогите, пожалуйста!


Garfunkel   (2004-09-09 13:36:00) [1]

Мой текстовый файл вопросов и ответов состоит из блоков, блоки по 4 ответа на один вопрос. Один блок выглядит так:
--------------------------------------

Вопрос
Ответ 1
1 // 1= верный ответ, 0=неверный ответ
Ответ 2
0
Ответ 3
0
Ответ 4
0

------------------------------------

Я нашел решение проблемы таким путем :

....
var
 button:Array[1..4]of TButton;
 correct:string;
......

procedure TForm1.LoadQuestion;
var
 str:string;
 s:TStringList;
 i,x:Byte;
begin
 Randomize;
 s:=TStringList.Create;
 for i:=1 to 4 do
 begin
   ReadLn(f,str);
   s.Add(str);
   ReadLn(f,str);
   if str='1' then correct:=s.Strings[i-1]; // считывание строк с цифрами 1/0
 end;
 for i:=0 to 3 do
 begin
   x:=Random(s.Count);
   button[i+1].Caption:=s.Strings[x];
   s.Delete(x);
 end;
 s.Free;
end;
-------------------------------------------
но может есть более изящный путь решения? Всем спасибо за помощь!


Cosinus   (2004-09-09 12:05:00) [2]

>>Чайник   (09.09.04 10:03) [17]
Да какая разница то? Плюс\минус две строчки.
Кстати, по-моему, тот алгоритм, который я написал элементарно изменить под нужную задачу.


Чайник   (2004-09-09 10:03:00) [3]

А тебе первые 4 строки надо или неважно какие?


Александр1   (2004-09-09 08:09:00) [4]


> Garfunkel   (09.09.04 00:07) [14]

Слушай я тут недавно почти с тем же самым мучился. Я пешу программу тестирование для студентов. Мне надо было считать из файла строки и распределить их по редакторам Memo. Ну в смысле в файле записаны вопрос и варианты ответа. Я долго мучился с этой проблемой. Пока всё таки через две недели решил её даже двумя способами.
{1-й способ}
var
MemoArray: array [1..3] of TMemo;
  s:string;
........
procedure TForm1.BitBtn2Click(Sender: TObject);
var F:TextFile; I:integer;//когда I локальна, будет чуть быстрее
begin
MemoArray[1] := Memo1;
MemoArray[2] := Memo2;
MemoArray[3] := Memo3;

AssignFile(F, ExtractFilePath(Application.ExeName)+'vopr\1.vop');
Reset(F);
I := 1;
repeat
ReadLn(f, S);
if S <> '' then MemoArray[i].Lines.Add(S)
else I := I + 1;
until Eof(F);
CloseFile(F);

end;

{2-й способ}
procedure TForm1.BitBtn3Click(Sender: TObject);
const AnzahlMemo = 7; {колличество Memo на форме}
var Datei: TextFile;
  TmpStr: string;
  MatrixMemo: array[0..AnzahlMemo - 1] of TMemo;
  i, NumMemo: integer;
begin
NumMemo := AnzahlMemo - 1;
for i := ComponentCount - 1 downto 0 do
  if Components[i] is TMemo then
  begin
    MatrixMemo[NumMemo] := Components[i] as TMemo;
    Dec(NumMemo);
  end;

  if NumMemo < -1 then exit; {выход, если к-во Memo на форме больше, чем в AnzahlMemo}

NumMemo := 0;
AssignFile(Datei, ExtractFilePath(Application.ExeName)+'vopr\1.vop');
Reset(Datei);
try
  while not Eof(Datei) do
  begin
    ReadLn(Datei, TmpStr);
    if (Length(TmpStr) > 0) and
              ((TmpStr[1] <> '') or (TmpStr[1] <> ' ')) then
      MatrixMemo[NumMemo].Lines.Add(TmpStr)
    else
     Inc(NumMemo);

    if NumMemo >= AnzahlMemo then Break;
  end;
finally
  CloseFile(Datei);
end;

end;


> Чтобы вопросы каждый раз шли наугад а не так как записано
> в файлах вопроса.


Ну я бы это вопрос когда пешу программу тестирования решаю так. Это может немного не удобно. Но у меня в принципе и вопросов обычно не так много. И храню я их в отдельной папки. Хотя тогда писал программу слабое звено и русскую рулетку, так там у меня было по 500 вопросов. Короче я создаю столько файлов, сколько вопросов. Например 1.vop, 2.vop  и т.д. А потом пешу что-то вроде этого
AssignFile(F, ExtractFilePath(Application.ExeName)+'vopr'\+ IntToStr(v)+.vop');
……….
Где v:=random(50);
Не забудь включить счётчик случайных чисел  Randomize;

Да ещё кстати хотел сказать. Чтобы в процессе твоей игры пользователи не запоминали варианты ответов (т.е. номера вариантов ответа), можно например сделать так, чтобы варианты ответа менялись местами. Даже если попадается такой вопрос, который уже был у него порядок вариантов ответа будет другой и поэтому вопрос вроде как и старый, а ответ на него не всегда и вспомнишь. Ну этого проще всего достичь сменой координат у носителя варианта ответа. Например в моём случае таким носителем является Memo1,2,3,4.
Соответственно можно их менять местами изменяя их координаты Memo1.Left:=368; Memo1.Top:=72; Перестановку Memo можно тоже поставить на random.


wl   (2004-09-09 00:17:00) [5]

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


Garfunkel   (2004-09-09 00:07:00) [6]

Не подходят к сожалению ваши ответы. LoadFromFile загружает ВЕСЬ файл. А мне надо считывать по 4 строки, потом из них считывать допустим в stringlist и уже оттуда назначать наугад четырем кнопкам captions. Потом все повторяется - опять 4 строки и.т.д... Это надо для тестовой игры типа Миллионер. Чтобы вопросы каждый раз шли наугад а не так как записано в файлах вопроса.


Чайник   (2004-09-08 20:21:00) [7]

Гы :)) а вопрос то интересный... :)


Cosinus   (2004-09-08 19:34:00) [8]

Кстати вопрос к автору. А зачем это надо то??? Я вот, честно, так и не придумал не одной задачи, для которой надо бы было так извращться.


Cosinus   (2004-09-08 19:32:00) [9]

Зато универсальности на порядок больше...
Да и повеселее он как то :))))


Чайник   (2004-09-08 19:31:00) [10]

:)) можно и так, но мне тот код прост попроще показался...


Cosinus   (2004-09-08 19:30:00) [11]

Мне кажется, что так правильнее будет...

procedure TForm1.SetCaptions;
var
  i: integer;
  Component: TComponent;
  ListCount: byte;
  s: TStrings;
  N: byte;
begin
  s:=TStrings.Create;
  s.LoadFromFile(...);
  ListCount:=S.Count-1;
  for i := 0 to ComponentCount - 1 do
  begin
    Component := Components[i];
    if (Component is TButton) then
      if (Component as TButton).tag=$10 then
      begin
        N:=Random(ListCount);
        (Component as TButton).Caption:=s.Strings[N];
        s.Delete(i);
        dec(ListCount);
      end;
  end;
  s.Free;
end;


Чайник   (2004-09-08 18:39:00) [12]

а в цикле кнопки неудобно перебирать :)


Cosinus   (2004-09-08 18:34:00) [13]

>>Чайник   (08.09.04 17:01) [4]
А в цикл чего не запихал?


Ega23   (2004-09-08 17:11:00) [14]

Гы, а нафига тогда AssignFile и reset(F)?

ну и closefile соответственно ?


Чайник   (2004-09-08 17:01:00) [15]

ну и closefile соответственно


Чайник   (2004-09-08 17:01:00) [16]

var
f:Textfile;
s:tstrings;
i:integer;
begin
assignfile('....',f);
reset(f);
s:=tstrings.create;
s.loadfromfile(...);
randomize;
i:=random(4);
button1.caption:=s.strings[i-1];
s.delete(i-1);
i:=random(3);
button2.caption:=s.strings[i-1];
s.delete(i-1);
i:=random(2);
button3.caption:=s.strings[i-1];
s.delete(i-1);
button1.caption:=s.strings[0];
s.delete(0);
end;
end;


Cosinus   (2004-09-08 16:51:00) [17]

Randomize+F1


Ega23   (2004-09-08 16:51:00) [18]

AssignFile
ReadLn
CloseFile

или

List:=TStringList.Create
List.LoadFromFile()
List.Free

потом ещё

Randomize
Random

Button1.Caption:=...

Ну и самое главное:   F1


Digitman   (2004-09-08 16:46:00) [19]


> Помогите, пожалуйста!


т.е. написать за тебя программу .. а ты будешь сидеть и в носу ковырять, ожидая готовенькое ...

так что ли ?


Наверх

Титульная страница Поиск, карта сайта Написать письмо