Как дурак C# учил. Часть 1


Запись 1
Я решил записывать. Главным образом потому, что я люблю записывать. Хотя нет. На самом деле мне хочется рассказать историю. Историю о том, что программирование это интересно. О том, что программирование может быть не только, профессией, но и отличным хобби, как фотография, шахматы, живопись или игра на гитаре. О том, что не обязательно иметь врожденный талант, суперсилу или годы специального образования чтобы добиться маленьких, но больших побед в любом деле.

Это дневник человека, изучающего программирование для удовольствия. Не для профессии, не для заработка. Я не живу в Нигерии с кнопочным телефоном и не нахожусь в отчаянном положении. Я просто учусь и программирую для развлечения в свободное от работы и семейных дел время. Шоу в реальном времени. Публикуется пачками по 5 записей.

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

Мой семилетний сын боится пробовать незнакомые занятия. Потому что не умеет. А надо понимать, что в свои годы он не умеет очень многого.

Иногда я говорю ему “Приятель, если бы люди делали только то, что умеют, мы бы до сих пор жили в пещерах, а конкретно ты целыми днями мычал, ползал и какал в штаны, вместо игры в Angry Birds. Хотя нет, ты бы ползал без штанов, потому что никто не умел бы шить”.

К чему это я? К тому что я совершенно не умею программировать. Но собираюсь научиться. Не потому, что хочу стать разработчиком — профессия у меня уже есть. А потому что могу. Хотя вообще-то у меня есть целых три причины.

Первая — размять мозг. Я убежден, что нельзя строить жизнь вокруг какой-то одной деятельности. Надо занимать свой ум разными задачами. И чем они будут разнообразнее — тем для ума лучше.

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

Третья причина — образовательная. Я попробую изменить отношение общества к программированию. Принято считать, что программирование — удел профессионалов. Никто не занимается программированием в качестве хобби. Такого понятия, как “любительское программирование” (запомните это слово) его вообще не существует.

Часть читающих меня профи сейчас набросится с комментариями о том, что я обесцениваю их профессию и наработанные годами скиллы. Не спешите. Пока просто поверьте мне, что это не так, а мы к этой теме еще потом вернемся.

Короче, я решил учить C#. Потому что для моей идеи нужен движок, и я так понял, что лучше всего Unity. А Unity — это C#. Это первое.

Второе, что я понял — начинать с Unity рановато. Почти все обучающие материалы исходят из того, что читатель уже знаком с языком. А всё, что я знаю про C# — это то, что правильно говорить «Си Шарп», а не «Цэ с решёткой». Так что начнём с самого языка.

Третье, что я понял — обучение будет основательным. Поскольку шарп для меня новый язык, нужно что-то “для чайников”, а такого нет.

Есть учебник “C# для школьников” Мартина Дрейера, но читать его решительно невозможно. Во-первых, знакомство с программированием у него начинается с изучения классов и объектов. Слишком сложно и непонятно. Во-вторых, на один абзац сути приходится три страницы примеров из реального мира. Слишком много. Я не готов тратить столько времени на историю о том, как девочка на необитаемом острове убеждает робота-инопланетянина заставить слона сорвать кокос.

Есть другая крайность. Уроки с сайта mycsharp.ru и “Полное руководство по языку программирования С# 8.0 и платформе .NET Core 3” на metanit.com/sharp/tutorial

Тут есть примеры кода, из которых можно что-то переиспользовать, но примеры слишком абстрактные типа “Давайте напишем программу, которая помещает в память объекты a, b и c, это же так увлекательно!”. Но это чуть лучше, чем слоны и кокосы, тем более, что у меня есть своя методика обучения.

В общем, я решил, что справлюсь и отправляюсь устанавливать Visual Studio.

Запись 2
Всё пошло не по плану. На следующий день, я словил Чёрный экран. Так и не понял, что это было, но похоже, что видеодрайвер обновился вперёд Windows и оказался несовместим со старой версией.

Когда-то я был аккуратен в подобных вещах. При любых проблемах просто восстанавливал раздел с ОС из бережно приготовленного образа, но это было давно. Винда стала стабильнее, я стал беспечнее. И вот.

Я провел неделю в попытках всё поправить. Перепробовал все рецепты. Нашел способ запустить командную строку, добыл древний Far, перенёс файлы, с третьей попытки подобрал подходящую сборку (я пользуюсь кастомизированной виндой) с уже установленным проблемным обновлением.

Тут надо сказать пару слов о моем бэкграунде. Я не умею программировать, но в общем-то считаю себя достаточно компьютерным человеком. Лет в 8 у нас дома появился первый в моей жизни ПК. Packard Bell 486. Крутой по тем временам. На нём было две программы — Лексикон и Инфо-бухгалтер.

Я играл в Лексикон.

Из символов I, / и я рисовал гоночную трассу, а курсор был машиной. Такие вот прибитые к полу игрушки. Ни интернета, ни друзей с компьютерами (поначалу). Я развлекался, как мог.

Кроме двух программ к компу прилагался полноценный MS-DOS на стопке дискет и я часто экспериментировал с разными командами. Дошёл и до такой, которая называлась QBASIC.

В бэйсике был небольшой мануал, и я кое-что понял. Выучил одну или две команды, и смог писать программы, которые выводили на экран какие-нибудь буквы. Было круто.

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

Так я познакомился с самыми элементарными вещами. Конструкциями if-then-else и циклами. Вершиной моего мастерства стала программа «Рулетка». Рулетка была игрой. Ты выбираешь число от 0 до 10 и делаешь ставку. Угадал — бонус, нет — потеря ставки. И так, пока не кончатся деньги. Я очень гордился.

Тем не менее, я был полным гуманитарием и не стал связывать свою жизнь с информатикой. Так что после школьных экспериментов я не вспоминал о программировании примерно 19 лет.

О! Кажется, установка Visual Studio завершена. Какая красивенькая. Чёрненькая вся. Давайте разбираться, что тут к чему.

Запись 3
Вообще-то это не первая моя попытка программирования. Где-то год назад на меня уже находила блажь, и я пробовал VBA. Смог освоить синтаксис нескольких команд и написал такую же рулетку, как тогда в школе. Только лучше. Теперь у меня был графический интерфейс из полей и кнопок, а также функции сохранения и загрузки игры (данные хранились в excel-таблицах).

Тем не менее я довольно быстро это дело бросил. По большей части от невозможности нормально использовать изображения, а может ещё и от лени. Не помню точно. В любом случае будем считать мой VBA-опыт своего рода разминкой. Теперь же пришло время настоящего хардкора.

За шарпом я провёл 4-5 вечеров. Прочитал две главы из учебника. Что я могу сказать? Меня совершенно не вдохновляет академический подход, основанный на написании бессмысленных программ, делающих абстрактрые вычисления. Не уверен, что смогу гордиться приложением, которое считает площадь треугольника.

Так что я придумал свой учебный план. С блэкджеком и… ну почти. Я выучил несколько самых важных команд: Console.WriteLine для вывода надписей, Console.Readline для ввода с клавиатуры, арифметические операции, условную конструкцию if-else, цикл while и конечно же Random для случайных чисел.

Наверное, вы уже догадались. Я снова написал консольную рулетку 🙂

Ощущения — восторг. Она работает! В ней можно проиграть или выиграть! И это настоящая программа — в ней 68 строк непонятного кода, в том числе целых 5 вызываемых методов.

Сложно ли было? Да. Я читал мануалы, допускал ошибки и всё ломал, тратил часы на поиск дефектов, снова читал мануалы, путался в коде и несколько раз всё переписывал, упрощая конструкции в циклах и убирая лишние переменные.

Но результат того стоил. Я полон надежд и двигаюсь дальше.

Запись 4
Первое препятствие. Дошел до понятия классов и объектов. Понятие совершенно непонятно. Как бы сама идея ясна, но как и для чего её применить? Создать классы для игрока, казино и рулетки? Потом придумывать объекты в них? И что они будут делать? Слишком притянуто. Кажется чем-то неестественным и только запутывает программу.

Дошло до меня через несколько дней. Я гулял с сыном на детской площадке и смотрел на мир вокруг объектно-ориентированными глазами.

class Парк {string ПаркName;},
class Ребёнок {string РебёнокName; int РебёнокAge;}
Ребёнок Дима = new Ребёнок ();
Ребёнок Саша = new Ребёнок ();

И тут я всё понял. Моя программа-рулетка слишком тупая и примитивная. Там просто не нужны классы. Это было хорошее упражнение для освоения процедурного программирования, но не более того.

Надо было придумать новое упражнение, чтобы понять классы. И я придумал. Прямо вот сел на лавочке и на телефоне написал себе задачку. Сделать мини-RPG. Там будет герой со своими параметрами силы и здоровья. Каждый ход он будет заходит в новую пещеру и встречать там тролля со своими параметрами. Они будут сражаться, бросая кубик, как в Невервинтере. А еще там можно будет найти оружие и доспехи.

Основные классы напросились сами собой:

  • Герой (сила, здоровье, деньги)
  • Предмет (урон, броня, прочность)
  • Монстр (сила, здоровье)

Должно получиться интересно. Справлюсь? Легко. Поехали.

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

Теперь у меня на экран выводится приветствие, статы игрока, оружия и брони. Есть меню, из которого можно запустить следующий ход или выйти из игры.

И даже это не было просто. Я постоянно натыкался на ошибки. Особенное при переносе кода в методы. Какая-то фигня не существует в каком-то контексте. Другая фигня недоступна из-за уровня защиты…

Мне очень не хватало какого-то руководства для чайников по структурированию кода. Куда поместить метод для генерации предмета? В класс Item? В класс Program? Просто оставить в коде? Приходится экспериментировать, ловить и исправлять ошибки.

Отдельные два дня я мучался с генератором случайных чисел, который выдавал мне щит и меч с одинаковыми параметрами. Понял, что нормальные решения моему разуму пока недоступны и сделал паузу в одну секунду между двумя генерациями.

Дальше эйфория кончилась и начался ступор. Я сумел сгенерировать два предмета, вручную, присвоив им названия Weapon1 и Armor1. Но мне потребуется делать это после каждого хода, копить их в инвентаре, менять… Как сделать создание объектов программно? Как генерировать их названия и тем более выбирать нужные для изменения их параметров?

С VBA было проще. В интернете полно примеров скриптов под каждую частную задачу. Найти и переиспользовать нужный — не проблема. Очень часто я вообще не понимал, половину написанного кода, но он волшебным образом работал, а тут приходится разбираться.

Учебник не помогает. Там уже рассказывают про лямбда-выражения и многопоточность, а примеры до сих пор на уровне “Найти сумму всех четных чисел в ряде чисел”. Скукота. Поиск в интернете тоже не даёт ответов, потому что я как-то не так формулирую вопрос.

Подозреваю, что надо подключать базу данных и записывать объекты туда. Придётся мне учить SQL.

Оставить комментарий