Как дурак 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.