InfoStart

След първото ми място на Националната олимпиада по Информационни технологии, се записах за участие в платформата „Infostart“ на „Информационно обслужване“ АД. Тя цели да обучи компютърни специалисти за минимално време, като за лектори са избрани едни от най-добрите специалисти в ИТ-индустрията в България, пр. Светлин Наков (надали има някой тукашен програмист, който да не е чувал за него). Най-добрите получават сертификат за успешно преминато обучение, а тези, които са записани присъствено, вземат дори и удостоверение за средно-специално образование, издадено от МОН. Записах се за квалифициране в специалността „Софтуерен специалист“.

В момента карам втория им модул – този по основите на езика C#. С голям ентусиазъм бих могъл да кажа, че силно типизираните езици ме кефят (или поне C# :)). Може би, това се дължи на факта, че там всичко трябва да е предварително декларирано, за да се задели точен брой количество памет. По този начин се създава ред и дисциплина (нещо както в казармата, ама без лошата ѝ част), а и се научаваме да бъдем по-добри програмисти (този факт не е фиксиран и зависи от много неща!).  При PHP пък е точно обратното, защото самият той някак си ни мотивира да пишем не особено стандартизирано спрямо другите езици. Според мен, отношението PHP:програмни езици е същото, както CodeIgniter:PHP Frameworks. Е, вярно Fuck language е много по-зле, но там вече по-скоро е заради иронията, която той създава.

Лекторите много ме кефят, особено Бат Наков. Всъщност той не е лектор, той е вдъхновител! Човек, който с толкова ентусиазъм се опитва да предаде тооолкова трудна материя, не съм срещал. Евала му казвам! Или той, или Евлоги Христов, беше дал една много дълга домашна, чиято дължина е около 35 страници (WTF?!). Всъщност първите 10-11 задачки бяха простички. Единственото, което ме спираше в решението им, е синтаксисът на C#.

Falling Rocks

Описание

Falling RocksЕкипът на СофтУни (или Академията на Телерик) са измислили една изключително интересна задачка, която доста ме заинтригува (не случайно е в заглавието на статията :D). Казва се „Falling Rocks“ и идеята при нея е, че трябва да се създаде игра, в която има джудже, което трябва да избягва падащи камъни. На първо четене се ужасих (както и на второ :D). След като, обаче, почнах да творя (тоест кодя), стигнах до извода, че имплементацията може да бъде супер елементарна. Нещо кофти беше, че някои от нещата (като например масивите или циклите) не ги бях учил в C#. Anyway, нали съм програмист – намерих начин и се справих.

Решение

Описание на решението

Възможно е то да се опрости и оптимизира доста (и съм сигурен в това). Просто съм нов в C# е не съм толкова навътре.

Реших, че най-добрият начин за създаване на различни камъни е да им създам една обща структура – Rock. В нея се задават row, col и symb (съответно ред и колона в конзолата, както и символ на камъка). За по-голямо улеснение там, създадох и конструктор, чиито параметри са съответни на по-горе описаните.

Основните настройки на приложението (като например височина и широчина на прозореца) са описани в private-свойства на основния (и единствен) клас FallingRocks:

  • rockTypes – стрингов масив, който съдържа типовете камъни. Пр. „$“, „@“, „#“ и т.н.;
  • rockColors – масив, който съдържа цветовете, използващи се при печатането на камъни в конзолата;
  • rnd – инстанция на обекта Random. Използва се основно за генериране на различни числа (пр. когато се взима решение колко камъка да бъдат на ред);
  • gameSpeed – скорост на играта в микросекунди. По задание е 150;
  • width – широчина на конзолата;
  • height – височина на конзолата;
  • maxRockPerRow – максимален брой камъни на ред.
  • dwarfRow – на кой ред да бъде разположено джуджето. Трябва да бъде height-1, за е на последния ред.
  • dwarfCol – на коя колона да бъде разположено джуджето. При стартирането на играта е по средата.

В главния метод Main() първо създавам списъка с камъни rocks и задавам параметрите на конзолата. След това правя безкраен цикъл, в който е изградената основната логика на играта. При началото на всяка интерация, конзолата бива изчистена, а цветът на текста – рестартиран (т.е. зададен до Console.Color = Gray, ако не се лъжа). После рендирам джуджето,  като за целта се извиква метода renderDwarf(). След като то се „появи на бял свят“, бива добавен нов ред с камъни, най-отгоре. Следва и тяхното рендиране (използва се отново друг метод – renderRocks()). Прави се проверка дали някакъв камък се е забил в джуджето. Ако е – играта спира, в противен случай продължава нататък и слуша за натискане на стрелките. Ако се натиснат, премества джуджето съответно наляво или надясно при следващото му рендиране. След това се изчаква gameSpeed милисекунди и цикълът продължава със следващата си интерация.

При метода renderDwarf() се проверява дали единствено джуджето не е прекалено вляво или вдясно, защото иначе ще доведе до ArgumentOutOfRangeException. След това то бива рендирано.

При renderRocks() нещата стоят малко по-сложно. Бива обходен подадения списък и всеки един камък бива смъкнат с един ред надолу (т.е. rock.row++). Прави се проверка дали той излиза от конзолата и ако – премахва го от списъка. По този начин се спестява оперативна памет (която при по-слабите компютри е мноого важна). Ако обаче камъкът е вътре в конзолата и не излиза от нея – той бива в оцветен в някакъв случаен цвят и бива рендиран.

Последният ми метод getRandomRockType() връща случаен (спорен въпрос!) вид камък.

Сега като чета това, изглежда много по-сложно, от колкото в действителност е. Опитайте се сами и ще видите, че не е кой знае колко голяма философия.

Нямам нищо против коментарите за това, че не съм добър в писането на C# код (което е нормално, уча го от 2-3 дни интензивно). Отворен съм за градивната критика (абе, и за хейта съм готов).

Надявам се, че все пак съм помогнал на някой програмист (измъчван от Наков) да се справи с тази задача. Пак Ви напомням да се опитате сами – много по-лесно е от колкото звучи. Успех и до скоро!