# Задачи по теме «Объектно-ориентированное программирование»

>В тех задачах, где нужно выполнять операции сложения, вычитания и т.п. имеется в виду операции с созданными вами типами данных, например:
>
>```cs
>HexNumber one = new HexNumber("ab10");
>HexNumber two = new HexNumber("cd05");
>Console.WriteLine(one + two);
>```
>Для реализации операции сложения, как в примере выше, в вашем классе нужно сделать [Перегрузку операторов](https://metanit.com/sharp/tutorial/3.36.php). (На лекциях этого не было, но ничего сложного там нет) 

1. Построить систему классов для описания плоских геометри­ческих фигур: круга, квадрата, прямоугольника. Предусмотреть методы для создания объектов, перемещения на плоскости, из­менения размеров и поворота на заданный угол.

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

3. Составить описание класса для представления комплексных чисел с возможностью задания вещественной и мнимой частей как числами типов **double**, так и целыми числами. Обеспечить выполнение операций сложения, вычитания и умножения комп­лексных чисел.

4. Составить описание класса для работы с цепными списками строк (строки произвольной длины) с операциями включения в список, удаления из списка элемента с заданным значением дан­ного, удаления всего списка или конца списка, начиная с задан­ного элемента.

5. Составить описание класса для объектов-векторов, задавае­мых координатами концов в трехмерном пространстве. Обеспе­чить операции сложения и вычитания векторов с получением нового вектора (суммы или разности), вычисления скалярного произведения двух векторов, длины вектора, косинуса угла меж­ду векторами.

6. Составить описание класса прямоугольников со сторонами, параллельными осям координат. Предусмотреть возможность пе­ ремещения прямоугольников на плоскости, изменения размеров, построения наименьшего прямоугольника, содержащего два заданных прямоугольника, и прямоугольника, являющегося общей частью (пересечением) двух прямоугольников.

7. Составить описание класса для определения одномерных мас­сивов целых чисел (векторов). Предусмотреть возможность обра­щения к отдельному элементу массива с контролем выхода за пределы индексов, возможность задания произвольных границ индексов при создании объекта и выполнения операций поэле­ментного сложения и вычитания массивов с одинаковыми грани­цами индексов, умножения и деления всех элементов массива на скаляр, печати (вывода на экран) элементов массива по индексам и всего массива.

8. Составить описание класса для определения одномерных массивов строк фиксированной длины. Предусмотреть возмож­ность обращения к отдельным строкам массива по индексам, контроль выхода за пределы индексов, выполнения операций поэлементного сцепления двух массивов с образованием ново­го массива, слияния двух массивов с исключением повторяю­щихся элементов, печать (вывод на экран) элементов массива и всего массива.

9. Составить описание класса многочленов от одной перемен­ной, задаваемых степенью многочлена и массивом коэффициен­тов. Предусмотреть методы для вычисления значения многочлена для заданного аргумента, операции сложения, вычитания и ум­ножения многочленов с получением нового объекта-многочлена, печать (вывод на экран) описания многочлена.

10. Составить описание класса одномерных массивов строк, каждая строка которых задается длиной и указателем на выделен­ную для нее память. Предусмотреть возможность обращения к от­дельным строкам массива по индексам, контроль выхода за пре­делы индексов, выполнения операций поэлементного сцепления двух массивов с образованием нового массива, слияния двух мас­сивов с исключением повторяющихся элементов, печать (вывод на экран) элементов массива и всего массива.

11. Составить описание объектного типа **TMatrix**, обеспечиваю­щего размещение матрицы произвольного размера с возможнос­тью изменения числа строк и столбцов, вывода на экран подмат­рицы любого размера и всей матрицы.

12. Простые и иерархические меню.

    1. Спроектировать простое меню в одной строке экрана. Меню обеспечивает перебор пунктов в результате нажатия на клавишу Пробел, позволяет зафиксировать выбор нажатием на клавишу Enter или отказаться от выбора нажатием на клавишу Esc. После выбора одного из пунктов в программу возвращается какое-то значение, связанное с выбранным пунктом, например символ. При отказе от выбора в программу возвращается #27.

        Перед началом работы меню ему надо передать названия пун­ктов и возвращаемые символы (ими могут быть первые буквы пун­ктов или какие-то специальные символы). Все это можно сделать в форме строки вида «Первое Второе Третье» или «Первое (а) Второе (о) Третье (с)» (здесь за названием пункта следует в скобках возвращаемый символ).

        Состояние меню характеризуется координатами меню на экра­не, номером отмеченного пункта, общим количеством пунктов, перечнем названий пунктов и возвращаемых символов (во втором варианте представления).

        Методами объекта являются:

        - _init_ — заполняет поле названий пунктов, подсчитывает ко­личество пунктов, делает выбранным первый пункт;
        - _select_ — позволяет выбрать пункт меню и возвращает символ выбранного пункта, при отказе от выбора возвращает #27;
        - _draw_ — рисует меню, выделяя выбранный пункт цветом;
        - _leftBoard_ — возвращает начало названия данного пункта;
        - _len_ — возвращает длину названия пункта;
        - _whatSel_ — возвращает символ выбранного пункта.

    1. Создать новый объект **TNeatMenu**, наследующий **TMenu**, ко­торый, в отличие от своего предка, будет восстанавливать вид экра­на. Для этого нужно добавить новое поле _store_, где будет храниться прежний экран во время действия меню, перекрыть метод _init_ и добавить метод _done_, который восстанавливает состояние экрана.

    1. Создать меню, которое изображает себя в форме столбца. Для этого рационально воспользоваться виртуальными методами. Достаточно изменить метод _draw_ объекта **TNeatMenu** и объявить одноименные методы виртуальными.

    1. Разместить объекты в динамической памяти, для этого дос­таточно описать указатели на них.

    1. Построить сложное иерархическое меню: пробел будет от­крывать главное меню, последовательное нажатие на клавиши **Enter** и **Пробел** будет разворачивать подсвеченный пункт в под­меню или, если пункт находится на нижнем уровне, клавиша **Enter** будет сворачивать подменю. Нажатие на клавишу Esc закан­ чивает работу программы.

    1. Построить иерархическое меню: **пробел** будет открывать глав­ное меню, нажатие на клавишу **Enter** будет разворачивать подсве­ченный пункт в меню или, если пункт находится на самом нижнем уровне, клавиша **Enter** сворачивает подменю. Нажатие на клавишу **Esc** заканчивает работу программы. Нижний уровень — вертикаль­ный.

13. Составить программу, работающую со связанными списками. Мы будем рассматривать связанный список как объект, содер­жащий связанный список данных и операций (методов), которые вы можете с ними выполнять.

    Связанный список данных состоит из указателей на начало («голову») и конец («хвост») связанного списка (в нашем примере из-за его гибкости используется дву­ направленный связанный список). Каждый элемент связанного списка представляет собой реализацию отдельного объекта. Воз­можности, необходимые для использования связанного списка, предоставляют следующие операции:

    * инициализация связанного списка;
    * деинициализация связанного списка;
    * вставка элемента в середину списка перед существующим элементом;
    * присоединение элемента к концу связанного списка;
    * удаление элемента из связанного списка;
    * возвращение первого элемента связанного списка;
    * возвращение последнего элемента связанного списка.

    Вы можете видеть, как объект связанного списка наследуется объектами стека или очереди, по­скольку очередь и стек можно реализовать как связанный список с ограниченным числом операций. Например, можно реализовать очередь в виде связанного списка, в котором элементы могут до­бавляться к концу и извлекаться из начала. Если вы таким обра­зом реализуете очередь, то нужно запретить наследуемые методы связанного списка, которые для очереди недопустимы (напри­мер, вставку в середину списка).

14. Определить объект **TFish** — аквариумная рыбка. Рыбка имеет координаты, скорость, размер, цвет, направление движения. Ме­тодами объекта являются:

    * _init_ — устанавливает значения полей объекта и рисует рыбу на экране методом _draw_.
    * _draw_ — рисует рыбу в виде уголка с острием в точке _coord_ и направленного острием по ходу движения рыбы.
    * _look_ — проверяет несколько точек на линии движения рыбы. Если хоть одна из них отличается по цвету от воды, возвращаются ее цвет и расстояние до рыбы.
    * _run_ — перемещает рыбу в текущем направлении на рассто­яние, зависящее от текущей скорости рыбы. Иногда случайным образом меняет направление движения рыбы. Если рыба видит препятствие, направление движения меняется, пока препятствие не исчезнет из поля зрения рыбы.

15. Определить объект **TAquarium**, который является местом обитания рыб (см. задачу 14 данного раздела). Он представляет со­бой область экрана, наполненную водой. Рыбы живут в аквариу­ме, поэтому экземпляры объекта **TFish** должны быть полями объекта **TAquarium**.

    Методы:

    * _init_ — включает графический режим, заполняет аквариум водой, камнями и рыбами.
    * _run_ — организует бесконечный цикл, в котором выполняет­ ся метод _run_ всех обитателей аквариума.
    * _done_ — выключает графический режим.

16. Определить два объекта **TPike** и **ТКагр**, которые наследуют объект **TFish** (см. задачу 14). Оба они отличаются от **TFish** тем, что по-разному изображают себя на экране: **TPike** — в виде зеленой стрелки, а **ТКагр** — в виде красного треугольника. Воспользуйтесь виртуальными методами. Для этого вернитесь к определению **TFish** и откорректируйте его, сделав метод _draw_ пустым и виртуальным.

17. Объединить карпов и щук (см. задачу 16) в две стаи. Стая — это связанный список рыб. Для связи до­бавьте в объекты **TPike** и **ТКагр** поле _next_ — указатель на следу­ющую рыбу в стае (связанный список). Сделайте аквариум владельцем не отдельных рыб, а двух стай и позвольте пользователю пополнять стаи, вводя рыб с клавиатуры.

18. Позволить щукам (см. задачу 16) проявить свой дурной ха­рактер и поедать карпов, как только они их увидят. Здесь возник­нет проблема — установить, какого именно карпа видит щука. Она решается путем просмотра всей стаи карпов и поиска того, чьи координаты близки к координатам данной шуки. Найденный карп удаляется из стаи.

19. Составить программу для игры в шашки. Шашка каждого нового цвета выступает в качестве отдельного объекта. Характеристики шашки — цвет и позиция на доске. Методы — перемещение. Не забудьте о таких объектах, как «дамки».

20. Составить программу для игры в домино. В качестве объектов выступают кости домино. Методы — способы выставления той или иной кости.

21. Составить программу для игры в шахматы. Каждая уникаль­ ная шахматная фигура выступает в качестве отдельного объекта. Она характеризуется цветом, положением на доске, способом перемещения. Предусмотреть возможность превращения пешки в ферзя.

22. Реализовать в виде класса набор методов для выполне­ния следующих операций над комплексными числами:

    - сложения;
    - вычитания;
    - умножения;
    - деления;
    - модуля комплексного числа;
    - возведения комплексного числа в степень п (п — натураль­ное).

23. Реализовать в виде класса набор методов для выполнения следующих операций над обыкновенными дробями вида ^ (Р — целое, Q — натуральное):

    - сложения;
    - вычитания;
    - умножения;
    - деления;
    - сокращения дроби;
    - возведения дроби в степень п (п — натуральное);
    - функций, реализующих операции отношения (равно, неравно, больше или равно, меньше или равно, больше, меньше).

24. Реализовать в виде класса набор методов для выпол­нения следующих операций с квадратными матрицами:

    - сложения двух матриц;
    - умножения одной матрицы на другую;
    - нахождения транспонированной матрицы;
    - вычисления определителя матрицы.

25. Реализовать в виде класса набор методов для выпол­нения следующих операций над векторами:

    - сложения;
    - вычитания;
    - скалярнго умножения векторов;
    - умножения вектора на число;
    - нахождения длины вектора.

26. Реализовать в класс для выполне­ния следующих операций над натуральными числами в `Р`-ичной системе счисления (`2 < Р < 9`):

    - сложения;
    - вычитания;
    - умножения;
    - деления;
    - перевода из десятичной системы счисления в Р-ичную;
    - перевода из Р-ичной системы счисления в десятичную;
    - функции проверки правильности записи числа в Р-ичной системе счисления;
    - функций, реализующих операции отношения (равно, неравно, больше или равно, меньше или равно, больше, меньше).

27. Реализовать класс для выпол­нения следующих операций над натуральными числами в шест­надцатеричной системе счисления:

    - сложения;
    - вычитания;
    - умножения;
    - деления;
    - перевода из двоичной системы счисления в шестнадцатеричную;
    - перевода из шестнадцатеричной системы счисления в деся­тичную;
    - функции проверки правильности записи числа в шестнад­цатеричной системе счисления;
    - функций, реализующих операции отношения (равно, неравно, больше или равно, меньше или равно, больше, меньше).

28. Реализовать класс для выпол­нения следующих операций над длинными числами:

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

29. Реализовать класс для выпол­нения операций с многочленами от одной переменной (первый многочлен степени `т`, второй — степени `п`):

    - сложения;
    - вычитания;
    - умножения;
    - деления с остатком;
    - операций отношения (равно, не равно);
    - возведения в натуральную степень `к`;
    - вычисления производной от многочлена;
    - вычисления значения в точке `х0`.

30. Разработать способ представления множеств, содержащих более 255 элементов (до 2000). Создать модуль, позволяющий вы­ полнять следующие операции над элементами таких множеств:

    - объединение;
    - пересечение;
    - разность;
    - функция проверки принадлежности элемента множеству;
    - функция проверки, является ли данное множество подмно­жеством (надмножеством) другого.
