Изучение c# на примерах

Формула программиста
основатель — Волосатов Евгений Витольдович
У вас нет доступа для просмотра этой записи.

Получить доступ

Теория ООП

Практический курс по теории Объектно-ориентированного программирования.
С нуля создаётся проект по рисованию различных геометрических фигур,
которые потом объединяются в спрайты, взаимодействуют друг с другом.

Во время создания проекта постоянно применяется рефакторинг кода,
при этом демонстрируются приёмы Объектно-ориентированного программирования.

Во второй части курса мы проработаем понятие Интерфейса.

Объём: 39 коротких видеоуроков
Время: 7 часов 40 минут.
Доступ на 30 дней.

3000 руб.


Для подписки на пакет необходимо авторизоваться.

Список уроков | фото | видео

# Название видеоурока Решило Рейтинг Доступ
1 Инкапсуляция мечты 00:09:02 99 чел. ★ 4.9 Done
  Отчёт отправил: 7276. Ильшат Решено за 35 мин. [Показать отчёт]
Научился: Выражать свои мысли про интерфейс) 
Сложности: Подобрать пример для описания различий между интерфейсом/реализацией. 
Комментарии: Инкапсуляция - это разделение структуры некоторого процесса, явления на две части: интерфейс и реализацию. Необходимость интерфейса обуславливается тем, что для пользователя не имеет значения то, как реализован некий процесс. Например, я как пользователь мобильного телефона не заинтересован в том, каким образом реализуется функция набора номера. Более того, в разных моделях эта функция реализована по разному. Мне эти детали не нужны. Мне нужно лишь знать общую последовательность действий, чтобы позвонить необходимому человеку. Т.е., я ожидаю получить удобный интерфейс, который позволит мне быстро и удобно набрать номер друга, а не изучать схемотехнику и замыкать нужные провода на схеме телефона. В итоге, интерфейс необходим для того, чтобы оградить пользователя от деталей реализации, от сложных процессов в начинке, от ошибочных действий с системой. Кроме того, интерфейс подбирается с учетом требований пользователя; возможно создание нескольких интерфейсов. Например, интерфейс для новичков, с ограниченными возможностями для управления процессом, где большинство параметров устанавливается по умолчанию. Интерфейс для опытных пользователей, для более тонкой "настройки под себя". Инкапсуляция в программировании выражается в правильной модульности исходного кода, разделении интерфейса и реализации. Например, в языке C++ для создания интерфейса используются заголовочные файлы, например MyLib.h, где пользователю доступны интерфейсы, а детали реализации расположены в файлах .cpp. На более низком структурном уровне инкапсуляция выражается в виде namespace, и далее в виде классов, где для разделения интерфейса и реализации используются секции кода public:, private:. На скриншоте показана кабина самолета Ил-96 (интерфейс) и общий вид самолета (его реализация) 
2 Урок рисования 00:08:10 95 чел. ★ 4.9 Done
  Отчёт отправил: 7276. Ильшат Решено за 9 мин. [Показать отчёт]
Научился: Свойство Dock у объектов на форме. 
Сложности: Сложностей не было. 
Комментарии: Все отлично) 
3 Первый класс 00:09:53 88 чел. ★ 4.9 Done
  Отчёт отправил: 7276. Ильшат Решено за 12 мин. [Показать отчёт]
Научился: Описывать класс и его конструктор, создавать объект. 
Сложности: Сложностей не было. 
Комментарии: Все отлично) 
4 Второй класс 00:09:13 84 чел. ★ 4.9 Done
  Отчёт отправил: 7276. Ильшат Решено за 14 мин. [Показать отчёт]
Научился: Для объекта класса Box рассчитывать значение ширины и высоты внутри класса. 
Сложности: Прикрепить к левой части экрана дерево классов во время исполнения программы. 
Комментарии: "Линия это не прямоугольник", "Любой студент это человек" - понравились примеры) 
5 Круглый класс 00:08:10 81 чел. ★ 4.9 Done
  Отчёт отправил: 7276. Ильшат Решено за 12 мин. [Показать отчёт]
Научился: Узнал, что для рисования эллипса необходимо задать координаты верхнего левого угла и ширину/высоту воображаемого прямоугольника вокруг эллипса. 
Сложности: Сложностей не было. 
Комментарии: Интересное название урока "Круглый класс") 
6 Структура пикселя 00:10:55 70 чел. ★ 4.9 Done
  Отчёт отправил: 7276. Ильшат Решено за 15 мин. [Показать отчёт]
Научился: Познакомился с понятием "структура" в языке C#. 
Сложности: Сложностей не было. 
Комментарии: Все понятно объясняется, идем дальше) 
7 Структура vs Класс 00:25:05 63 чел. ★ 4.9 Done
  Отчёт отправил: 7276. Ильшат Решено за 40 мин. [Показать отчёт]
Научился: 1) Более подробно изучил понятие "структура" в языке C#; 2) Понял отличие структуры от класса в C#; 3) Передача параметров в функцию с помощью квалификаторов ref, out. 
Сложности: Сложностей не было. 
Комментарии: Все понятно, спасибо за урок) 
8 Пиксели для классов 00:14:44 60 чел. ★ 4.9 Done
  Отчёт отправил: 7276. Ильшат Решено за 20 мин. [Показать отчёт]
Научился: Вызывать один конструктор через другой в C#. 
Сложности: Сложностей не было. 
Комментарии: Полезная фича, делегирующие конструкторы, спасибо) 
9 Расстояние между пикселями 00:12:12 60 чел. ★ 4.9 Done
  Отчёт отправил: 7276. Ильшат Решено за 15 мин. [Показать отчёт]
Научился: Более сложной инициализации аргументов для делегирующего конструктора (в данном случае, с помощью функции distance()) 
Сложности: Сложностей не было. 
Комментарии: Красота, идем дальше) 
10 Цветные карандаши 00:14:54 58 чел. ★ 4.9 Done
  Отчёт отправил: 7276. Ильшат Решено за 25 мин. [Показать отчёт]
Научился: Осознал неудобство ручного (copy/paste) создания новых классов со схожими свойствами на базе уже существующих . 
Сложности: Все понятно, сложностей нет. 
Комментарии: Хороший подход, постепенное улучшение структуры программы как было сказано в начале видео) 
11 Рисуем Снеговика 00:14:40 57 чел. ★ 4.9 Done
  Отчёт отправил: 7276. Ильшат Решено за 44 мин. [Показать отчёт]
Научился: Рисовать снеговика в paint:D 
Сложности: Определить координаты центров окружностей, углов прямоугольников и концов отрезков. 
Комментарии: Абстракция прекрасна: используя заранее определенные необходимые типы данных (Line, Circle, Box) удобно создавать интересные фигуры, не задумываясь о деталях) 
12 Второй Снеговик 00:09:46 57 чел. ★ 4.9 Done
  Отчёт отправил: 7276. Ильшат Решено за 15 мин. [Показать отчёт]
Научился: Добавил второго снеговика, путем смещения координат 'x' базовых точек первого снеговика. 
Сложности: Сложностей не было. 
Комментарии: Для начала, для удобства, можно создать класс SnowMan, где, в качестве полей определены: x, y - координаты верхнего-левого угла снеговика; angle_x, angle_y - текущие углы поворота снеговика относительно осей x, y; scale_x, scale_y - коэффициенты масштабирования относительно осей x, y. 1) для перемещения можно добавить функцию move(int dx, int dy) {x += dx; y += dy;} 2) для поворота можно добавить функцию rotate(int rx, int ry) { angle_x += rx; angle_y += ry; } 3) для изменения размеров можно добавить функцию scale(int sx, int sy) {scale_x *= sx; scale_y *= sy;} Кроме того, можно добавить функции set_position(int x, int y), set_rotation(int rx, int ry), set_scale(int sx, int sy), которые устанавливают абсолютные значения необходимых полей. 
13 Богатое наследство 00:12:53 56 чел. ★ 4.9 Done
  Отчёт отправил: 7276. Ильшат Решено за 20 мин. [Показать отчёт]
Научился: 1) Познакомился с наследованием в C#. 2) Вызов конструктора базового класса в конструкторе производного класса с помощью ключевого слова base в С#. 
Сложности: Сложностей не было, все по аналогии с C++, правда до сих пор слегка неловко, когда вижу в коде голые 'new', явные 'this'. 
Комментарии: На этот раз кратко опишу, как это отражается в коде. Наследование - это способ создания новых типов на базе существующих, путем повторного использования их интерфейса (и реализации), и с добавлением каких-либо новых свойств, поведений, которые явно отличают производный тип от базового. 
14 Фигуральный базовый класс 00:10:56 55 чел. ★ 4.9 Done
  Отчёт отправил: 7276. Ильшат Решено за 30 мин. [Показать отчёт]
Научился: 1) Создавать массив объектов и использовать цикл для итерации в указанном диапазоне. 2) Свойство или поле Length у массива. 3) Динамическая идентификация типа в C#. 
Сложности: Реализовать функцию Draw(Shape). 
Комментарии: Общая идея такова, что среда выполнения C# как бы должна знать динамический тип объекта. Как раз на видео было показано, что хоть у массива статический тип это Shape, но динамический тип может быть другим(Circle, Box и т.д.). Для реализации Draw(Shape) обратился к гуглу, почитал в википедии про динамическую идентификацию типа в C#, обнаружил, что для этого есть несколько способов реализации (GetType, typeof, is, as), подробнее почитал в msdn, поигрался с is, GetType(), выбрал GetType. Получился эдакий брутальный способ вызова соответствующей перегруженной функции Draw). 
15 Рисователь снеговиков 00:11:51 55 чел. ★ 4.9 Done
  Отчёт отправил: 7276. Ильшат Решено за 15 мин. [Показать отчёт]
Научился: Закрепил знания, полученные на предыдущем уроке (функция GetType()) 
Сложности: Сложностей не было. 
Комментарии: Переменная Shape.position необходима для удобства, простоты расчетов, "независимости от контекста", то есть, это единственная переменная, которая хранит в себе абсолютные координаты снеговика в целом, как фигуры. Остальные координаты зависят от Shape.position, что удобно для расчетов поворота, масштабирования и прочее. 
16 Переезд метода Draw 00:11:54 55 чел. ★ 4.9 Done
  Отчёт отправил: 7276. Ильшат Решено за 15 мин. [Показать отчёт]
Научился: 1) Приведению типа Shape к типу Circle. 2) Новому способу прохода через breakpoint, на видео(10:58). Отличие этого способа, от двух других (F10, F11) в том, что после нажатия на F5 программа продолжает свое обычное выполнение (пока не встретит новый breakpoint). Это удобно в определенных случаях, когда нет необходимости пошагово проходить через выражения; экономит время. 
Сложности: Сложностей не было. 
Комментарии: Все понятно, идем дальше) 
17 Переезд graph в базовый класс 00:13:10 55 чел. ★ 4.9 Done
  Отчёт отправил: 7276. Ильшат Решено за 20 мин. [Показать отчёт]
Научился: Использовать функционал базовых классов. 
Сложности: Сложностей не было. 
Комментарии: Наша программа постепенно становится более удобной: там закинули в массив, тут прошлись в цикле, дальше унифицировали обращение к функции Draw - красота) 
18 Мощь полиморфизма 00:09:01 53 чел. ★ 5 Done
  Отчёт отправил: 7276. Ильшат Решено за 15 мин. [Показать отчёт]
Научился: 1) Ключевые слова abstract, virtual, override их смысл и применение. 2) Реализация полиморфизма в C#. 
Сложности: Сложностей не было, все по аналогии с C++, правда с другим синтаксисом. 
Комментарии: Да, дождались, полиморфизм, ура!) 
19 Спрайт для Снеговика 00:12:28 53 чел. ★ 5 Done
  Отчёт отправил: 7276. Ильшат Решено за 20 мин. [Показать отчёт]
Научился: Познакомился с коллекцией List в C#; удобно, мощно. 
Сложности: Сложностей не было. 
Комментарии: Спасибо за урок, приятно познакомиться с коллекциями в C#) 
20 Перемещение круга 00:11:42 53 чел. ★ 4.9 Done
  Отчёт отправил: 7276. Ильшат Решено за 15 мин. [Показать отчёт]
Научился: Отличать координаты position от координат расположения круга. 
Сложности: Сложностей не было. 
Комментарии: На мой взгляд, Move(int offset_x, int offset_y) это функция, которая принимает смещения относительно текущих координат; для абсолютного размещения лучше подойдет функция MoveTo(int x, int y) или SetPosition(int x, int y). 
21 Перемещение других фигур 00:08:37 53 чел. ★ 4.9 Done
  Отчёт отправил: 7276. Ильшат Решено за 20 мин. [Показать отчёт]
Научился: Закрепил материал с прошлого урока, координаты position и внутренние координаты для Circle, Box, Line. 
Сложности: Придумать фигуру из трех фигур) 
Комментарии: Если использовать данную структуру классов, то для реализации перемещения спрайта необходимо объявить функцию Move с ключевым словом virtual в классе Shape, затем перегрузить функцию Move для класса Sprite, которая пробежится по коллекции shapes и для каждого объекта вызовет функцию Move: public override void Move(Pixel position) { base.Move(position); foreach(Shape shape in shapes) shapes.Move(position); } 
22 Перемещение Снеговиков 00:10:48 52 чел. ★ 4.9 Done
  Отчёт отправил: 7276. Ильшат Решено за 15 мин. [Показать отчёт]
Научился: Перемещать снеговиков, закрепил навыки предыдущих уроков. 
Сложности: Сложностей не было, все ок. 
Комментарии: Перемещать спрайты научились, теперь необходимо их поворачивать и масштабировать) 
23 ПОЛУФИНАЛЬНЫЙ УРОК. 46 чел. ★ 5 Done
  Отчёт отправил: 7276. Ильшат Решено за 20 мин. [Показать отчёт]
Научился: Курс теория ООП хорошо подойдет для тех курсантов, которые уже имеют опыт программирования на C#, возможно использовали в своих проектах наследование, полиморфизм, но не понимают зачем это нужно, если можно создавать программы без "заумных" способов. Материал сам по себе достаточно сложный, именно теоретические основы, которые не привязаны конкретно к языку программирования. Но на уроках Евгений Витольдович основной упор делает на практику и материал подается легко, без суровой теории и декомпозиции предметной области. При этом, на практике обосновываются те или иные проектные решения, демонстрируется недостатки и неудобства "первоначальной" реализации и постепенно улучшается структура программы, что позволяет ей быть более жизнеспособной для новых задач. Цели, которые я ставил перед собой до этого курса: 1) Послушать лекции Евгения Витольдовича о том, как он будет рассказывать понятия ООП с полного нуля, чтобы освежить свои знания и возможно с другой стороны посмотреть на ООП. 2) Познакомиться с реализацией ООП в C#. 3) На одном из вебинаров Евгений Витольдович спросил у зрителей, на сколько процентов вы знаете ООП. Я ответил на 75%. То есть, я понимаю для чего это нужно, какие возможности открываются перед программистом, но как это все грамотно вместе организовать, как грамотно декомпозировать предметную область, чтобы решение получилось универсальным, а не ad-hoc? Оставшиеся 25% процентов знаний требуют практики, которую, как я полагаю, я смогу получить в продолжении курса ООП. Курс в целом понравился, целей достиг, оставшиеся 25% будем добирать) Спасибо за данный курс! Хужахметов Ильшат. 
Сложности: Написать отзыв. 
Комментарии: Фото с профиля) 
24 Интерфейс. Зачем он нужен. 00:09:33 44 чел. ★ 4.9 Done
  Отчёт отправил: 7276. Ильшат Решено за 20 мин. [Показать отчёт]
Научился: Познакомился с интерфейсами в C#. 
Сложности: Понять, связать действия в интерфейсе Player (Игрок) с правилами в игре "Голя", выразить вкратце мысли про интерфейс. 
Комментарии: На мой взгляд, интерфейс это некий контракт, правила, которые должны выполнены (реализованы в коде), прежде чем мы можем создавать различные реализации конкретных классов. Эти классы будут представляться от имени интерфейса, как допущенные к использованию (подчиняющиеся правилам контракта) и могут быть вызываться любой функцией, которая работает с данным интерфейсом. На примере данной игры "Голя", интерфейс это требования к человеку, которые должны быть соблюдены, прежде чем он сможет принимать участие в игре. То есть, надо уметь бегать, становиться Голей, становиться не Голей и ловить других игроков. В коде это означает, что любой класс, который хочет принимать участие в игре, должен реализовать все 4 функции интерфейса Игрок. Если он это сделал, система довольна и разрешает доступ к тем классам, функциям, которые работают с интерфейсом Игрок. 
25 Интерфейс. Правила игры. 00:12:23 43 чел. ★ 5 Done
  Отчёт отправил: 7276. Ильшат Решено за 17 мин. [Показать отчёт]
Научился: Автоматическая генерация заглушки stub для методов. 
Сложности: Продумать словесный алгоритм. 
Комментарии: Алгоритм FindNewLeader(): Начало Игрок := Первый игрок в списке игроков Цикл: Пока Игрок != Последний игрок в списке Если Лидер Поймал Игрока ТО Блок Лидер := Игрок Выход из цикла Конец Блока Конец Цикла Конец //--------------------------------- Алгоритм SetNewLeader(Игрок игрок): Начало Лидер установить Не Голя Лидер := игрок Лидер установить Голя Конец 
26 Интерфейс. Алгоритм игры. 00:07:48 43 чел. ★ 5 Done
  Отчёт отправил: 7276. Ильшат Решено за 15 мин. [Показать отчёт]
Научился: Узнал, что если в списке не будет элементов, то foreach корректно обработает эту ситуацию. 
Сложности: Сложностей не было. 
Комментарии: Чтобы начать играть, нам необходимо продумать "интерфейс" игры, как и что рисовать на форме, панели или pictureBox, реализовать интерфейс Игрок в виде конкретного класса, добавить несколько объектов этого класса в список gamers в классе GameCatch и как-нибудь по-хитрому все это запустить) 
27 Интерфейс. Создаём кружок. 00:08:36 42 чел. ★ 5 Done
  Отчёт отправил: 7276. Ильшат Решено за 15 мин. [Показать отчёт]
Научился: Закрепил полученные знания из предыдущих уроков. 
Сложности: Сложностей не было. 
Комментарии: Дальше необходимо каким-нибудь образом связать Circle с интерфейсом Игрок. Как было сказано в конце урока, что если Circle стал Голей, то меняет цвет на красный, если не Голя, то обратно синий. 
28 Интерфейс. Площадка для игры. 00:11:58 41 чел. ★ 5 Done
  Отчёт отправил: 7276. Ильшат Решено за 20 мин. [Показать отчёт]
Научился: Кириллу респект, хорошо подметил, что в конструкторе переменная picture ссылается на аргумент, а не на член класса Arena. Код и так и сяк будет работать, согласен с Евгением Витольдовичем, но менять косвенно состояние this.picture через аргумент на мой взгляд это словно зайти в дом через черный вход, мало ли, что тебя там ожидает. Возможно в C# есть какой-нибудь механизм, защищающий от этого, аналогичный const ссылкам и указателям C++ на аргументы функций. 
Сложности: Нарисовать окольными путями кружок на форме, для этого добавил pictuteBox на форму, добавил Arena.Show(), создал объект Arena в коде инициализации формы. 
Комментарии: Класс Арена нужен для того, чтобы инкапсулировать отображение наших игроков Circle на форме, чтобы, например, не вручную в коде форме вызывать функции DrawEllipse, а создать какой-нибудь удобный интерфейс Arena.Show(object). Вообще говоря, класс Арена малек перегружен по смыслу, он кроме того, умеет создавать новые Circle и статический Range меня немного смущает, но соглашусь с Евгением Витольдовичем, не стоит усложнять код) 
29 Интерфейс. Кружок на площадке. 00:11:49 41 чел. ★ 5 Done
  Отчёт отправил: 7276. Ильшат Решено за 14 мин. [Показать отчёт]
Научился: PictureBox.Refresh() удобная штука) 
Сложности: Сложностей не было. 
Комментарии: Свое творчество с прошлого урока удалил) Идем дальше) 
30 Интерфейс. Запускаем кружки на площадку! 00:11:49 40 чел. ★ 5 Done
  Отчёт отправил: 7276. Ильшат Решено за 20 мин. [Показать отчёт]
Научился: Рисовать круги на форме в рандомных местах, с рандомным радиусом, это красиво) 
Сложности: Три функции Refresh(), Clear(), Arena.NewCircle(). Они взаимосвязаны и их нужно вызывать в правильном порядке. Сначала не понимал, как так получается, что мы создали объект в куче, вызвали для него Show(), потом потеряли ссылку, значит объект уничтожился, а на форме он все так же рисуется. Вся магия в том, что на pictureBox остается не сам объект, а его бледная тень, словно рисуешь карандашом на бумаге. И если случайно вызвать Clear(), то все тени исчезнут, словно стирающей резинкой все очистил) И конечно нужно вовремя вызывать Refresh(), чтобы показать результат изменения после итерации. 
Комментарии: Это был долгий путь в несколько уроков, прежде чем мы нарисовали заветные круги, причем в рандомных местах, с рандомным радиусом) Результат понравился, спасибо!) 
31 Интерфейс. Кружок хочет играть. 00:09:42 40 чел. ★ 5 Done
  Отчёт отправил: 7276. Ильшат Решено за 20 мин. [Показать отчёт]
Научился: Закрепил навыки. 
Сложности: Описать словами содержимое методов Беги(), Поймал(). 
Комментарии: Метод Беги(). Наш круг описывается координатами центра center (Point) и радиусом(int). В конце урока была дана подсказка, две целочисленные переменные sx, sy. Эти переменные могут означать смещение координат центра. Могут означать изменение радиуса. Но мы должны реализовать не метод Расширься(), а метод Беги(), то есть изменение координат самого круга, а это определяется координатами центра. Так что, думаю что надо в методе Беги() изменить координаты центра: center = new Point(center.x + sx, center.y + sy); В методе Поймал(object obj) нам надо проверить поймал ли текущий кружок this того, что мы получили в аргументах. Физическая реализация этого представляется проверкой на столкновение или, точнее, пересечение двух окружностей (Так как у нас объекты круги). Пересечение двух окружностей это не rocket science, решение известно - это определение дистанции между центрами окружностей и сравнение этого значения с суммой радиусов. Если дистанция меньше суммы, то ... кружок поймал другой кружок. public bool Catch(object obj) { Circle second_circle = (Circle)obj; int distance = Convert.ToInt16(Math.Sqrt( (center.X - second_circle.center.X) * (center.X - second_circle.center.X) + (center.Y - second_circle.center.Y) * (center.Y - second_circle.center.Y))); return distance < radius + second_circle.radius; } 
32 Интерфейс. Кружок готов к игре! 00:20:47 39 чел. ★ 5 Done
  Отчёт отправил: 7276. Ильшат Решено за 45 мин. [Показать отчёт]
Научился: Поэкспериментировал с выводом класса Circle на экран. Попробовал FillEllipse, различные Brush. Оставил вывод через DrawEllipse, мне показались более симпатичными. От себя добавил, что если Circle Голя, то у него толщина окружности в три раза больше, чем у остальных, это помогло в наглядности тестирования. 
Сложности: В 4 пункте было указано, что нужно описать словами что нужно сделать. Я малость не удержался, и реализовал в коде, правда достаточно долгое время, около 10 минут не понимал, почему у меня круги двигаются, но не Голятся. Оказалось, что в функции SetNewLeader() мы выходили из функции, если Лидер был НЕ null. Исправил как надо - заработало) Ошибка была глупой:D Надо быть внимательнее.  
Комментарии: Решил записать видео демонстрацию, без звука. В конце видео выделил мышкой добавленный код, а в самом конце - проблемный участок, надо которым сидел 10 минут) 
Видеообзор: https://youtu.be/0tObhwEck74
33 Интерфейс. Кружочки гоняются друг за другом. 00:11:53 39 чел. ★ 5 Done
  Отчёт отправил: 7276. Ильшат Решено за 25 мин. [Показать отчёт]
Научился: Метод Equals() у объекта. 
Сложности: Продумать как исправить недочеты с переголением. 
Комментарии: Как исправить недочет с переголением? 1) Можно определить время в течение которого новый Голя не может Голить игроков. 2) Как и в первом случае, указать время, но в течение этого времени новый Голя не может двигаться. 3) Сделать какую-нибудь форму иммунитета игроков на действия нового Голи. Из всех способов, думаю первый самый простой и подходящий. 
34 Интерфейс. Изменяем правила игры. 00:10:22 38 чел. ★ 5 Done
  Отчёт отправил: 7276. Ильшат Решено за 45 мин. [Показать отчёт]
Научился: Понял значимость класса GameCatch, благодаря которому легко меняются правила игры. Увидел реализацию задержки нового Голи, понравилось то, что код обработки этой ситуации локален внутри GameCatch, хотя и зависит от внешнего таймера. 
Сложности: Сложностей не было, интересный урок, попробовал версию игры, где новый Голя стоит на месте в течение 10 итераций. Получается менее динамично, но есть ощущение уже несколько другой игры. 
Комментарии: Суть новой игры. В начале игры все игроки имеют статус Голя, им дается команда Беги. Когда Голя ловит другого Голю, то оба становятся Не Голями и замирают на месте (Не получают команду Беги). Если после этого какой-нибудь другой Голя поймает Не Голю, то Не Голя оживает, становиться Голей и снова начинает двигаться. Если в игре не останется Голь, то игра сбрасывается и все становятся Голями и так по кругу. Записал видео, для этой версии игры. 
Видеообзор: https://youtu.be/14YzZfzjnQY
35 Интерфейс. Создаём новую игру. 00:12:31 37 чел. ★ 5 Done
  Отчёт отправил: 7276. Ильшат Решено за 20 мин. [Показать отчёт]
Научился: Закрепил навыки из прошлых уроков, добавил новый класс GameVirused для реализации новой игры. 
Сложности: Сложностей не было. 
Комментарии: У нас имеется два массива, gamers и virused. gamers хранит всех текущих игроков, virused - тех игроков, которые заражены. В SetNewVirus(Игрок) нам необходимо добавить игрока в список virused и сказать ему - Ты Голя. В FindNewVirus несколько сложнее, у нас два массива данных, как такового отдельного лидера уже нет, лидер растворен среди зараженных игроков, поэтому необходимо пройтись в двух циклах по gamers и virused и проверить Поймал ли тот, кто заражен того, кто не заражен. Если поймал, то вызвать функцию SetNewVirus. Если остался всего один не зараженный игрок, то сделать его зараженным, остальных в цикле не зараженными. 
36 Интерфейс. ФИНАЛЬНЫЙ УРОК. 00:13:05 34 чел. ★ 5 Done
  Отчёт отправил: 7276. Ильшат Решено за 45 мин. [Показать отчёт]
Научился: Метод Contains у класса List<>, удобная штука. 
Сложности: Не было, все понятно, хорошо показано, как изменить правила в игре. 
Комментарии: Перед началом второй части курса теории ООП я ожидал, что мы продолжим работать со снеговиками, научим их каким-нибудь действиями (помню Оля писала мне в комментариях, что "они у нас еще потанцуют, а мы отлично потренируемся"). Кроме того, в шапке курса было указано, "При создании программы мы будем использовать некоторые шаблоны проектирования, такие как "Одиночка", "Фабрика", "Строитель", "Наблюдатель" и другие. Когда я это увидел, еще до того, как пройти первую часть курса, то загорелся желанием пройти курс ООП. В первой части курса паттернов не было, поэтому ожидал их увидеть во второй части. Но и во второй части их не было. Да, были моменты с методами Arena.NewCircle(), но упор в курсе был сделан не на паттерны, а на интерфейсы. Однако это ни в коей мере не говорит о том, что курс мне не подошел. Я присутствовал на вебинаре, на котором производилась запись курса, это восхитительная атмосфера, всем советую ходить на вебинары!) Тематика второй части курса меня сразу захватила, Евгений Витольдович придумал интересный пример для объяснения этой важной концепции в объектно-ориентированном программировании. При этом, в первых уроках упор был сделан на абстракцию, логику программу, а отображением результатов на форме мы занимались во второй половине курса, и, что примечательно, программа сразу со старта заработала корректно, это достойно уважения!) Кроме того, практически после каждого урока были дополнительные вопросы на проработку материала. Нам было необходимо написать словесные алгоритмы или попробовать самим реализовать действия из следующих уроков. Это сильно мотивирует и проверяет на сколько качественно усваивается материал. В целом, я считаю, что неплохо прокачался за эти два курса ООП. Кому стоит рекомендовать данный курс? В своем полуфинальном отчете я писал, что курс теория ООП хорошо подойдет для программистов, которые достаточно уверенно знают C#, но не уверенно понимают понятия ООП. Мои коллеги по проекту не разделяют этого мнения (я читал их отзывы с полуфинального урока) и считают, что курс мастхев для новичков. На вкус и цвет конечно, но я своего мнения не меняю. Лучше сначала хорошо проработать задачи из консоли, бесплатные курсы, понять, что ты не боишься языка программирования и можешь написать программу любой разумной сложности, и потом понять для себя, чего не хватает и к чему лежит интерес) Получился достаточно длинный отчет, спасибо тем, кто прочитал его до конца) Спасибо Евгений Витольдович, мне было приятно пройти курс теория ООП, появились новые идеи, открылись пробелы по некоторым вопросам, будем изучать дальше!) 
37 Интерфейс. VIP. Квадратики тоже хотят играть. 00:16:23 34 чел. ★ 5 Done
  Отчёт отправил: 7276. Ильшат Решено за 4 час. 10 мин. [Показать отчёт]
Научился: Повторил применение интерфейсов. 
Сложности: Реализовать функцию пересечения прямоугольников. 
Комментарии: Данный урок выполнил в Linux Mint с использованием Qt. Я давно интересовался Linux, неделю назад установил себе на компьютер и теперь осваиваю работу в этой ОС. Вчера получил письмо от Евгения Витольдовича с предложением закончить курс ООП, Согласился, продлил курс, но решил выполнить задание с использованием C++ Qt. Программу писал с нуля, по памяти и это большой плюс для меня, так как в завершении совершенно другими глазами смотрел на код Евгения Витольдовича и оценивал как он решал те или иные архитектурные задачи. В целом, функционально код во многом совпал, но структурно были отличия, позже корректировал с учетом решения в видеоуроке. В конце урока было предложено реализовать функцию пересечения прямоугольников, это было сделано, на скриншотах результаты игры GameVirused с "боксиками". P.S. Евгений Витольдович, я хочу продолжить обучение с использованием своих инструментов разработки, Вы это одобряете? То есть, функционально я буду выполнять требования из видеоуроков, получать навыки программирования, но с помощью C++. 
38 Интерфейс. VIP. Пересечение прямоугольников. 00:09:47 32 чел. ★ 5 Done
  Отчёт отправил: 7276. Ильшат Решено за 1 час. 20 мин. [Показать отчёт]
Научился: Условие пересечения прямоугольников. 
Сложности: Сложностей не было. 
Комментарии: Поначалу решил, что предложенная в уроке функция проверки пересечения двух прямоугольников рассматривает только один частный случай, слишком уж "простая" она на вид. Однако проверил на практике - работает. Здесь я предположил, что боксики двигаются слишком быстро, поэтому в какой-то момент срабатывает "то самое" частное условие и боксик голится. Я не верил, что это решение корректное. Для полной проверки нужно было замедлять боксики и проверять на глаз пересечения, но мне не хотелось этим заниматься. Я уже хотел было отправить отчет, но тут вспомнил совет Евгения Витольдовича, что следует довести дело до конца. Тут осенило, думаю, дай-ка создам unit-тесты на функцию isIntersect и проверю все возможные варианты пересечений и не пересечений. В итоге, нарисовал на бумаге разные варианты расположения прямоугольников, получалась 31 комбинация, создал для каждой из них свой тест, каждый тест запускал по мере написания и меня каждый раз шокировало, что функция-то работает:D На втором скриншоте показаны результаты выполнения 31 теста, все проходят. Подумал, может в Qt какая-нибудь бага, регрессировал код тестируемой функции, добавил в нее ошибку и тесты посыпались как надо, чудо. В общем, функция Евгения Витольдовича работает как надо. Позже я еще раз логически проанализировал функцию проверки и да, тут уже понял, что код корректен. Первое впечатление оказалось обманчивым, следует внимательно читать код. Хороший урок для меня. 
39 Интерфейс. VIP. Тяжёлая дружба кругов и квадратов. 00:22:25 26 чел. ★ 5 Done
  Отчёт отправил: 7276. Ильшат Решено за 3 час. 00 мин. [Показать отчёт]
Научился: Поэкспериментировал с интерфейсами, повторил создание видео обзоров. 
Сложности: Выбрать какое-то одно решение проблемы на проверку пересечения объектов. 
Комментарии: Проблему проверки пересечения объектов решил немного другим путем, с помощью интерфейса Boundable, который требует, чтобы реализующие его объекты определили ограничивающие круги и прямоугольники вокруг фигуры. Это позволяет сравнивать не сами объекты со сложной конфигурацией, а упрощенные элементы, например, такие как круги. Для того, чтобы добавить нового игрока в игру, достаточно описать список этих ограничивающих поверхностей, а другие функции более высокого уровня уже работают не с самими объектами, а их границами, таким образом нет тесной связи между типами. Да, проверка получается грубее и менее точная. Здесь можно было бы изменить начальный интерфейс, но я пошел другим путем, оставил все как есть и искал куда бы добавить свой интерфейс Boundable. Мое решение так себе, пока не знаю как сделать лучше, но это позволяет создавать новых игроков и не беспокоиться об их сравнении с другими игроками. Для верности, добавил двух новых игроков с более сложной конфигурацией. Курс понравился, стоит пересмотреть еще раз, так как многие "очевидные" моменты открываются с новой стороны. Спасибо, Евгений Витольдович! 
Видеообзор: https://youtu.be/lemoIWg72Ps
  Итого:   39 видеоуроков общей продолжительностью 7 час. 40 мин. 26 чел. ★ 4.95  
  Финалисты:   lomik,   Роман,   Максим Базуев,   Neverwinter 2,   Владимир,   Никита,   Оля,   Валера Луцевич,   Anton Sozykin,   Permitin Alexey,   Артём,   Максим Лапшинов,   Frank,   Archi,   Александр Львович,   Ильшат,   Олег Михайлович,   Дмитрий,   Новопашин Владимир,   Евгений,   Сергей Соколов,   Александр Б.,   Максим Саратов,   Алексей В.,   Александр,   Rita .

Начинаем практику по языку C#




Чтобы стать хорошим программистом — нужно писать программы. На нашем сайте очень много практических упражнений.

После заполнения формы ты будешь подписан на рассылку «C# Вебинары и Видеоуроки», у тебя появится доступ к видеоурокам и консольным задачам.

Несколько раз в неделю тебе будут приходить письма — приглашения на вебинары, информация об акциях и скидках, полезная информация по C#.

Ты в любой момент сможешь отписаться от рассылки.
Научился: Создали новую игру на старом интерфейсе.
Трудности: Сложностей не возникло, но все новое.
Курс ООП очень понравился, познакомился с новыми понятиями "Инкапсуляция", "Наследование", "Полиморфизм". Научился создавать спрайты, а также создавать множество игр на одном интерфейсе. Планирую активно использовать полученные навыки на практике, в частности, при создании своей игры.
Научился: простоте модификации
Трудности: понять
Очень здорово! Я в восторге!