Помощь - Поиск - Пользователи - Календарь
Полная версия: Задачник по ООП
Форум «Всё о Паскале» > Pascal, Object Pascal > Теоретические вопросы
Bokul
Если ли такой для Паскаля? Или просто задачи...

P.S. ссылку на форум Задачи не давать...
volvo
Хочешь задачи - "их есть у меня" smile.gif

Вот тебе, например, классический пример... Есть банк/магазин/парикмахерская/... (нужное подчеркнуть)
То есть, многопользовательская система обслуживания. А смоделируй-ка ее работу с использованием ООП. С полным ведением статистики, разумеется, какой кассир/продавец/парикмахер какого клиента обслужил, сколько времени продолжалась каждая работа с клиентом, и т.д. (если нужно - дам полную формулировку задания... Даже больше того, у нас на форуме это выкладывалось в виде программы на С++ для случая банка, но то - С++, а это - Паскаль, можешь попробовать реализовать то же самое на Паскале. Я уверяю тебя - скучно не будет smile.gif )

Lapp
Еще хороший пример - игры.
Например, типа стратегий - там просто обувешаться объектами.. Но можно и попроще - разные штуки бегают по за тобой полю и едят, бьют, размножаются.. smile.gif
Задач вокруг полно. Никакой задачник не нужен - нужно их увидеть.
Bokul
Цитата
Никакой задачник не нужен - нужно их увидеть.

nea.gif , ведь у задачника есть достаточно большой плюс - ответы...
Цитата
Например, типа стратегий - там просто обувешаться объектами.. Но можно и попроще - разные штуки бегают по за тобой полю и едят, бьют, размножаются..

А ведь тут уже нужно использовать события? Вот, например, бильярд, даже проще - шарики катаются по полю. Какие объекты надо делать? Шарик, еще что-то надо? Особо интересует вопрос их взаимодействия, столкновения. Должен ли знать шарик о существовании других? Скорее всего нет, ну тогда появляется необходимость в новом объекте - доске. Что должен уметь шарик? Доска?

Цитата
То есть, многопользовательская система обслуживания.

А под этими словами есть теория, которую нужно знать?

Цитата
банк /магазин/парикмахерская/.

Цитата
если нужно - дам полную формулировку задания..

Давай. smile.gif

Тему, нашел. Сейчас перечитаю...
Lapp
Цитата(Bokul @ 16.12.2006 5:04) *

nea.gif , ведь у задачника есть достаточно большой плюс - ответы...

Ответы есть только у самых простых задач.
Для остальных есть постоянная проверка всех отдельных частей и отдельных взаимодействий.
Полной уверенности нет никогда.
И все это тоже часть обучения программированию..
volvo
Цитата
у задачника есть достаточно большой плюс - ответы...
Вопрос на засыпку - а что подразумевается под ответом? Это же тебе не "вычислить сумму ряда", где в ответе получается число и все ясно и понятно... Приводится листинг программы? Задачу (особенно с объектами, взаимодействием между ними) можно решать далеко не одним способом, и что? Мой способ не совпал с описанным в задачнике, значит мое решение - неверное? blink.gif
Bokul
Цитата
Приводится листинг программы? Задачу (особенно с объектами, взаимодействием между ними) можно решать далеко не одним способом, и что? Мой способ не совпал с описанным в задачнике, значит мое решение - неверное?

А если своего ответа нету? wink.gif


Так, а по другим вопросам как?
volvo
Цитата
А если своего ответа нету?
Значит, плохо разобрался в теме, и чужой ответ тебе вряд ли поможет...

Теперь о других вопросах (это - как делал бы я, универсальных советов - опять же - быть не может) :
Цитата
Вот, например, бильярд, даже проще - шарики катаются по полю. Какие объекты надо делать? Шарик, еще что-то надо? Особо интересует вопрос их взаимодействия, столкновения. Должен ли знать шарик о существовании других?
Я уже где-то тебе говорил, что объект должен знать ровно столько, чтобы он мог совершать возложенные на него действия... Какие действия возложены на шарик? Кататься! Вот теперь подумай, если шар №1 будет знать, что на его траектории находится шар №2 - он что, покатится по параболе? Или по какой-то другой кривой? Нет, он продолжит движение по прямой... Значит, знание о другом шаре не изменяет его поведения, зачем оно нужно?

А вот кто будет отслеживать столкновения - это объект Supervisor (ну, или обзови его Manager-ом, от этого суть не меняется...) Он проверяет расстояния между центрами шаров, и вдруг видит, что одно из них равно диаметру шара... Ага!!! Столкновение blink.gif У шаров запрашиваются их скорости + направления движения, они пересчитываются, и шары продолжают катиться уже с учетом изменения параметров движения...
Bokul
Есть вопросы по поводу объекта Supervisor.
Я уже сделал некоторую работу, создал несколько объектов:

1 TGObject -// движущейся графический объект, умеет:
constructor init(x,y:integer; speed,color:byte; angle,time:real);// - инитиализировать себя
procedure moveto;// - двигаться
procedure calculation; virtual; //abstract; //- высчитывать свое новое положение, перекрывается в наследниках
procedure ChangeDirection(speed:byte; angle:real); //- вызывается с Supervisor, только в случае столкновения. Меняем скорость и угол полета.
procedure draw(x,y:integer); virtual;// abstract; - перекрывается в наследниках
destructor done; virtual;// - стирает себя с экрана
2 TBall - наследник TGObject, теперь это движущейся шарик
constructor init(x,y:integer; speed,color:byte; angle,time:real; r:byte);// - добавили новое поле r -радиус, инициализацию остальных полей наследуем
procedure calculation; virtual;// перекрываем
procedure draw(x,y:integer); virtual;// тоже перекрываем
destructor done; virtual; // перекрываем, наслудуем

3 TItem - элемент списка указателей на объекты TBall
constructor init(pos_x,pos_y:integer; v,col:byte;angle,time:real; r:byte; p:TPItem);// инициализирует свою информационную часть
destructor done;// удаляем информационную часть

4 TList - содержит список указателей на объеты типа TBall
constructor init;//-инициализирует список
function AddItem(pos_x,pos_y:integer; v,col:byte; angle,time:real; r:byte):boolean;//добавляем новый элемент
function DeleteItem(pdel:TPitem):boolean;//удаляем элемент
destructor done;//удаляем весь список


Так вот TSuperVisor должен быть наследником TList или содержать его в себе?
Правильна ли общая структура?
volvo
Цитата
Так вот TSuperVisor должен быть наследником TList или содержать его в себе?
Наследником? Ни в коем случае... Наблюдатель не является видом списка (что передавалось бы наследованием), он содержит список в себе...


Кстати, у тебя (на мой взгляд) многовато параметров передается в конструкторы... unsure.gif
Bokul
Цитата
Наблюдатель не является видом списка (что передавалось бы наследованием), он содержит список в себе...

good.gif Точно - наблюдатель! Не больше и не меньше.
Цитата
Кстати, у тебя (на мой взгляд) многовато параметров передается в конструкторы...

Что именно?
Цитата
x,y:integer; speed,color:byte; angle,time:real

x,y - начальные координаты
speed,color - начальная скорость, цвет
angle - начальный угол движения
time - через какое время надо перерисовываться.

Что мне не нравится - так это то, что TItem и TList должны знать о параметрах конструктора TBall. sad.gif Можно ли этого избежать?

Главный цикл должен быть методом TSupervisor?
volvo
Цитата
TItem и TList должны знать о параметрах конструктора TBall
rolleyes.gif А должны ли?

Я в своей программке (той, с елкой) делал вот так (переношу на твои названия типов):
Type
TType = ^TItem;

TItem = object ... end;

TList = object
procedure AddItem(X: TType);
end;

TGObject = Object(TType)
...
end;
PTBall = ^TBall;
TBall = Object(TGObject)
...
end;


Что это меняет?
А вот что:
Var L: Tlist;
...
L.AddItem(new(PTBall, init( ... )));
{ Но сами классы TItem/TList не имеют никакого понятия о параметрах конструктора TBall }


Цитата
Главный цикл должен быть методом TSupervisor?
Скорее всего, да...
Bokul
Спасибо! Все стало более инкапсулировано wink.gif

P.S. Уже почти все закончил, осталось сделать главный цикл... smile.gif
Bokul
Цитата
P.S. Уже почти все закончил, осталось сделать главный цикл...

Не так все просто, как думалось, а именно:

Наследование объекта TSuperVisor должно давать ему возможность работать с новыми наследниками объекта TGObject , проще говоря его наследники смогут просчитывать траектории после столкновения, не только для абстрактного объекта TGObject , но и для TBall и квадрата и т.д.
Трудность заключается в том, что для его расчетов от разных объектов ему понадобится разные данные: для круга радиус, для квадрата - длинна стороны. Так вот, я не сильно представляю как это все надо организовать объекто..

Для примера, главый цикл:
Пробегаемся несколько раз по списку, сравнивая положения объектов , если они совпадают запускаем соответственный метод просчета их новых траекторий .

Получается для троих различных типов объектов надо 6 разных процедур сравнения и просчета - для каждого последующего наследника TGObject,обрабатываемого объектом TSuperVisor-ом, придется писать все больше и больше этих процедур. Ну и пусть, но как сделать это максимально объектно и проще для наследования?
volvo
Цитата
Получается для троих различных типов объектов надо 6 разных процедур сравнения и просчета
Не совсем понятно, почему именно 6, и почему ты вообще что-то должен добавлять... Функции в самих объектах виртуальные? В чем проблема? Вызывай виртуальную функцию объекта, приведенного к TGObject, сработает позднее связывание - вызовется то, что тебе нужно...

Пример (хотя бы небольшой) КАК ты организовал обработку, можешь привести?
Bokul
Цитата
Функции в самих объектах виртуальные?

Какие именно функции?
Цитата
Вызывай виртуальную функцию объекта, приведенного к TGObject, сработает позднее связывание - вызовется то, что тебе нужно...

Дело в том, что я думал сделать процедуры просчитывания новой траектории методом не наследников TGObject, а - TSuperVisor. Смотри, для вычисления новой (после столкновения) траектории разным объектам надо разные данные - некоторым надо знать только одну точку, другим - больше, но теоретически возможны ситуации столкновения сразу несколько объектов одновременно (хотя такую реализацию такой возможность я оставляю на потом, но хочу чтобы все могло максимально легко совершенствоваться), потому я хотел оставить все расчеты траектории для TSuperVisor.

Для процедуры сравнения тоже самое. Под сравниваем я имею ввиду процедура. которая проверяет ударились ли объекты.
Цитата
Не совсем понятно, почему именно 6

При добавлении нового обрабатываемого объекта(наследника TGObject) количество процедур увеличивается на количество разных фигур. В случае 3 объектов получаем 1+2+3=6.
Нажмите для просмотра прикрепленного файла

Цитата
Пример (хотя бы небольшой) КАК ты организовал обработку, можешь привести?

Обработку чего?
volvo
Цитата
Дело в том, что я думал сделать процедуры просчитывания новой траектории методом не наследников TGObject, а - TSuperVisor.
И что тебе это даст, кроме того балагана, с которым ты уже столкнулся? Нет... Я бы, все-таки, сделал так: процедура расчета траектории - тут у тебя нет особых сложностей - и треугольник, и квадрат, и круг в основном передвигаются по одинаковым законам, поэтому само передвижение не должно вызывать сложностей - достаточно определить одну процедуру пересчета координат в TGObject, и все потомки пусть ее наследуют.

Теперь - что касаемо столкновения... Хм... Ну, допустим вот такой вариант:

function collision(var obj_1, obj_2: TGObject): boolean;
begin
{
находишь "пересечение фигур" - где-то видел реализацию,
могу попробовать найти ссылку: ищется фигура, представляющая
собой общую часть фигур Obj_1 и Obj_2 ...

Если полученная фигура НЕпуста, то есть или касание (площадь полученной
фигуры сопоставима с одним квадратным пикселом, если можно так выразиться)
или уже сильная авария (если общая площадь больше, но в этом случае ты должен
чаще производить проверки на касания)
}
collision := (S_common(Obj_1, Obj_2) > 0)
end;
При реализации S_common тоже не надо будет ничего никуда добавлять - будут использоваться данные, уже и так хранящиеся в соотв. объектах (для круга - координаты центра и радиус, например)...
Bokul
Цитата
И что тебе это даст, кроме того балагана, с которым ты уже столкнулся?

Вот по-этому и спросил. smile.gif
Цитата
процедура расчета траектории - тут у тебя нет особых сложностей - и треугольник, и квадрат, и круг в основном передвигаются по одинаковым законам, поэтому само передвижение не должно вызывать сложностей - достаточно определить одну процедуру пересчета координат в TGObject, и все потомки пусть ее наследуют.

В процедура расчета траектории проблем конечно же нет - у всех графических объектов есть общие два поля, которые задают вектор (угол, скорость) скорости и все, другое - это ихние заботы. Проблемы возникают с расчетом этого вектора после сталкивания, т.е. он меняется только в этом случае и в зависимости от наследника TGObject будет определятся по-разному. sad.gif
Цитата
При реализации S_common тоже не надо будет ничего никуда добавлять - будут использоваться данные, уже и так хранящиеся в соотв. объектах (для круга - координаты центра и радиус, например)...

Ну так правильно, но как узнать какие данные брать, ведь у наследников они могут быть совсем разные. wacko.gif
Цитата
находишь "пересечение фигур" - где-то видел реализацию,
могу попробовать найти ссылку: ищется фигура, представляющая
собой общую часть фигур Obj_1 и Obj_2 ...

Было бы классно smile.gif , только как надо задавать формы фигур?
volvo
Цитата
только как надо задавать формы фигур?
Не понял... Какие формы? Все, что тебе надо - это та информация, с помощью которой можно однозначно отрисовать фигуру... Если ты можешь 2 фигуры отрисовать - значит у тебя есть достаточно информации (по тому алгоритму, о котором я говорил выше) чтобы найти их пересечение...
Bokul
А как, в каком виде, этому алгоритму передать эту информацию?
PS чтобы не морочить больше голову сейчас выложу исходники...
Это текстовая версия — только основной контент. Для просмотра полной версии этой страницы, пожалуйста, нажмите сюда.