![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Распределение строк по 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]
> Помогите, пожалуйста!
т.е. написать за тебя программу .. а ты будешь сидеть и в носу ковырять, ожидая готовенькое ...
так что ли ?