Во вступительной части был приведен небольшой список статей, которые будут в цикле учебного примера. От себя же добавлю, что некоторые статьи могут быть разбиты на части, при условии, что слишком огромны по своему содержанию, что нормально для учебных примеров.
Введение
В данной статье, под названием «Постановка проекта с нуля или как правильно начать программу», будет рассматриваться ситуация «чистого листа» в рамках данной темы и как с этим работать. А более детальное рассмотрение дилеммы «чистого листа», стоит прочесть и поискать самим в интернете, благо тема важная и про нее можно много чего узнать, коли есть желание. А мы, с вами, пойдем далее в рамках самой статьи и все, что будет не попадать в нее, упомяну.
Ну что ж, для начала сделаю маленькую ремарку о том, что данный пункт из списка будет небольшим и больше поясняющим, направляющим и т.п. Т.к. по части проектирования, более подробно можно будет прочитать из книги «Совершенный код» автора Макконел С. Книга полезная для тех, кто хочет взяться за серьезный проект или по меньше ошибаться на этапах проектирования, при этом независимо от формального языка, на котором будет применять полученные знания. Однако, на мой взгляд это одна из немногих книг, написанная американцами, которая дотягивает до уровня профессоров СССР 80-ых годов, где открыл и понятно, что куда, и каким образом. Видимо, дозрели, так что книгу стоило назвать, «Пособие по проектированию нормально работающего кода, руками растущими не из жопы». Да-да, такова суровость русского языка, говорить более прямо и по существу вопроса. А теперь, перейдем, конкретно к теме статьи, и напомню, что пример будет описывать не с позиции знания вышеприведенной книги, а с позиции личного, накопленного опыта, т.к. это ценее. Да, и книгу, нашел год спустя после накопления своего опыта. Так что, почитал ее не с позиции утенка, а с позиции человека будучи в определенной мере в потоке.
Зеленый новичок
Самая первая проблема, любого зеленого программиста в том, что после универа или других источников обучения, есть ярая и порою детская уверенность в том, что можно спокойно собрать велосипед из трактора или наоборот. Т.к. отсутствие практического опыта на ходу заменяется самоуверенностью или самоубеждением в собственных силах. Это прямой и легкий путь, либо к разочарованию, либо к костылестроению. А как всем, «неизвестно», внутреннее часто проецируются на внешнее, а потом по обратной связи начинает взращивать в участнике такого процесса, внутренние конструкции, дающие еще большую прогрессию в этом деле. Для примера, взгляните в зеркало, и задайте себе внутренний вопрос: «А у меня не также?». Полагаю, ответ, вам сильно «понравится». 😉
Однако, разобраться в самоопределении — это еще только часть дилеммы «чистого листа», т.к. вышеописанная проблема — это не желание принять себя новичком и постоянный уход от этого, который неизбежно создает в себе упадок. А другая проблема, в том чтобы правильно начать. И ответ на этот вопрос ищут все по разному, у меня например удалось найти его через описание по составлению проектов в виде документации для архитекторов. Вкратце говоря, взял сам каркас подхода остальное отбросил и вложил со сферы деятельности программистов разных мастей. И, получилось, заработало. А по части реализации исходного кода программы могу сказать, что в силу опытности написания простых программ, сложную программу начал писать с самого простого места — с середины, т.к. сложно было обозначить начало и конец. Как раз об этом моменте и поговорим, подробнее.
Середина программы — движение механики
Сделаю еще одну, маленькую, ремарку. На вопрос «движение механики чего?», для особо страждущих у меня ответ таков. Все, как в том старом китайском фильме, где рабочему-новичку дали изоленту, и сказали, примерно следующее: «Вот, это твой рабочий инструмент, им можно починить, все, тебе будет его достаточно». Так, что движение механики — это ответ на ваш вопрос и он поможет вам понять все в этом мире. И это, работающая, правда.
Начать с середины программы — это умеренный путь и подход к написанию любых программ, и к тому же работающий подход. Однако, эту умеренность и практичность подхода проявим через учебный пример.
И как ранее говорилось, учебный пример игры «Виселица», является по сути игрой, следовательно игровой процесс — это середина программы. А начало и конец, пока отложим в сторону. В итоге, пользователь программы принимает участие в работе программы, будучи игроком.
Каркас середины программы из себя представляет отгадывание слова, которое неизвестно игроку, а известно программе, при этом отгадывается по буквам. Значит, основной каркас программы в том, что игрок отгадывает слово по буквам и для реализации этого процесса применяется вся логика, конструкция и механика программы «Виселица». И смысл не в том, что это элементарно, т.к. элементарно для меня, потому что мне понятно, о чем идет речь, вам, наоборот. Т.к. умение разбирать программу на составляющие — это одно из умений, необходимых, для создания программ разного рода и уровня сложностей, без этого можно с легкостью создавать костыли, а не программы. И не надо убеждать меня в том, что якобы не прав — это значит, что вы ни разу не то, чтобы не брались за дело, даже в некоторой мере не реализовали сложный проект, пройдя все его тернии.
А теперь, представим себе игру «Виселица», как некий механизм (чем по сути оно и является, т.е. программный механизм). У любого механизма всегда есть начало, середина и конец. Помимо этого, любой, механизм состоит из основы (это каркас), и дополняющих направлений — это дополнения, которые задают границы возможностей механизма, закладываемые в него на этапе проектирования. То бишь, достаточно нарисовать круг и поставить в центре точку, где точка — это каркас программы, окружность — это дополнения, а пространство между ними — это конкретный алгоритм, классы, и т.д. Этот принцип построения программ применяется везде и всюду, т.к. основан на более древних принципах созидания, не только в искусстве разработки программ. А, остальное зависит от развития вашего умения высматривать и находить механику в любых местах деятельности.
И, учитывая все вышеописанное, стоит вспомнить, что игровой процесс в виде отгадывания слова по буквам — это, каркас программы. Тогда, следовательно в самом элементарном варианте, кол-во допустимых ошибок — это, дополнение программы, причем одно из многих. Но, об этом несколько позже.
Подытоживая данную пункт темы скажу что, нет смысла заниматься реализацией кода, пока не смогли полностью разложить программу на составляющие, т.к. это путь дилетанта, не желающего работать над собой, а желающего всего и сразу, да за короткое время. По собственному опыту, рекомендую, применять начало с толком, а не растрачивать его на подобную лажу, иначе никогда не научитесь своему дело. И дело не во времени, как многие заблуждаются, а в участии, можно и через неделю продолжить, важно наработать в себе умение, возвращаться в процесс деятельности, а не пытаться выжимать из себя все соки, т.к. такая практика изматывает и вызывает серое отношение к конечному результату вне зависимости от его ценности.
Возвращаясь к теме, сразу становится понятно, что окружность — это кол-во ошибок, а точка — сам игровой процесс. Следовательно, реализованный код в конечном итоге это заполненное пространство. А заполненное пространство можно заштриховать по разному, следовательно содержание этого пространства может быть разным. Примеров, подобного вывода можно найти в достатке на просторах Рунета, а также на Андроид-телефонах в виде графически оформленных игр. Однако, суть и смысл данной статьи не в этом, а в простоте и практичности свободного восприятия информации и умения регулировать меру, как соотношение абстракции/конкретики информации, чтобы иметь возможность, при разном соотношении увидеть разные интересные моменты описания содержания программы, вместо того, чтобы увлекаться в самом начале только одним описанием, сильно ограничивая свое развитие.
И натренированные умения, в конечном итоге, сокращают время на проектирование и дают доступ к новым возможностям, то бишь передвигают на новый уровень возможностей и там-то начинается то самое интересное, к чему все и идут, собственно говоря.
Исходный код
А теперь, пора бы выложить все вышеописанное в исходном коде, коим будет сама реализация нашего содержания программы. Код, разумеется прост, как дважды, два, четыре. При этом, несмотря на простую реализацию игры, данный исходный код — это нормально работающий код, который можно превратить в нормальную программу-игру «Виселица». С этого варианта и продолжим развитие темы данного учебного примера.
И для краткости, немного по коду. Сам, игровой процесс начинается со строки 84, где запускается бесконечный цикл, пока игрок, либо отгадает слово, либо не отгадает слово и истратит допустимое кол-во ошибок. Также, помимо этого, была добавлена не только проверка на соответствие символов, вводимых с клавиатуры, буквам русского алфавита, а также проверка на повторный ввод ранее введенных букв. И разумеется в самом начале, игра вежливым общением, с элементами диалога, предлагает игроку сыграть в игру, объяснив ее правила. Также дает возможность выйти из программы до старта игрового процесса.
И как, было мною упомянуто ранее в статье, вне темы идут вопросы о wchar_t, wcin, wcout, setlocale, using, т.к. они выходят за рамки темы, поэтому объясняться не будут. И единственное, что скажу. Это то, что «L» перед кавычками ставится не просто так, это связано с кодировкой Utf8, в которой пишется файл на gedit в Линуксе. И разумеется, все ранее перечисленное применяется без создания очередных костылей. Да, и новичкам есть, что почерпнуть для своей практики из кода.
В заключение, пример того какой командой делал компиляцию после сохранения файла с исходными кодами.
1 2 |
g++ viselica-1.cpp -o viselica-1 ./viselica-1 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 |
// ====================================================================== // viselica-1.cpp // ====================================================================== // ====================================================================== // Имя программы: viselica-1 (Программа-игра "Виселица") // Авторское право (c) 2016 Смирнов Андрей Владимирович известный, как Мирра Андрюхан // Лицензия: GNU GPL 2 // Автор: Смирнов Андрей Владимирович // Почта: mirra.andryuhan@yandex.ru // Веб-сайт: http://andryuhan.ru // Лицензию можно прочитать, здесь http://www.gnu.org/licenses/old-licenses/gpl-2.0.html // ====================================================================== #include <iostream> #include <wchar.h> using namespace std; //Сбрасывает лишние символы, т.к. ввод идет с клавиатуры inline void SbrosVvoda() { if (wcin.peek() != '\n') while (wcin.peek() != '\n') wcin.ignore(); } int main() { //Устанавливаем локаль ru_RU.UTF-8, чтобы применять русские буквы в программе. setlocale (LC_ALL,"ru_RU.UTF-8"); //Флаг выхода из бесконечного цикла, по умолчанию ставится ложь. bool isExit = false; //Символ ответа wchar_t simvol = ' '; //Вступительный текст программы-игры "Виселица". wcout << L"Привет, пользователь. Давай сыграем в игру \"Виселица\", правила которой просты.\n Я, программа, загадываю слово, а ты его отгадываешь по буквам. Если ошибешься десять раз, то проиграешь.\n Слово будет состоять из букв Русского алфавита.\n\n"; //Получение ответа или повтор запроса от программы while (!isExit) { wcout << L"Будем играть? (Дд/Нн)"; wcin >> simvol; SbrosVvoda(); if (simvol != L'Д' && simvol != L'Н' && simvol != L'д' && simvol != L'н') { wcout << L"\nВведены не верные данные в качестве ответа, вводи Д или д, и Н или н!\n"; continue; } if (simvol == L'Н' || simvol == L'н') { wcout << L"\nСпасибо, за внимание. До свидания, пользователь.\n"; //Выход из программы-игры "Виселица". return 0; } else isExit = true; } //---------------------------------------------- //Проведение игрового процесса игры "Виселица". //Алфавит Русского языка wchar_t alhavit[33] = {L'а', L'б', L'в', L'г', L'д', L'е', L'ё', L'ж', L'з', L'и', L'й', L'к', L'л', L'м', L'н', L'о', L'п', L'р', L'с', L'т', L'у', L'ф', L'х', L'ц', L'ч', L'ш', L'щ', L'ь', L'ы', L'ъ', L'э', L'ю', L'я'}; //Счетчик для циклов short i; //Массив загаданного слова wchar_t slovo[7] = {L'ч', L'е', L'м', L'о', L'д', L'а', L'н'}; //Массив отгадываемого слова wchar_t otgSlovo[7] = {'?', '?', '?', '?', '?', '?', '?'}; //Массив букв введеных игроком, для исключения дублированного ответа. wchar_t vvedBukva[16] = {L'#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#'}; //Индекс введенных букв. short indBukva = 0; //Флаг соответствия введенного символа буквам русского алфавита или букве в загаданном слове. bool isPravilno; //Счетчик допустимых ошибок short kolOshibok = 9; //Счетчик отгаданных букв short kolPravilno = 0; //Переинициализация Символа ответа simvol = ' '; wcout << L"Загадываю слово... Хорошо, слово на строке ниже.\n"; //Собственно, сам процесс игры while (true) { //Если игрок отгадал, загаданное слово, тогда поздравляем и завершаем программу. if (kolPravilno == 7) { wcout << L"Поздравляю, ты, угадал мое слово.\n"; wcout << L"Слово было такое: \""; wcout << slovo; wcout << L"\".\n"; wcout << L"Спасибо, за игру, было приятно с тобой поиграть.\n"; //Выход из программы-игры "Виселица". return 0; } //Если игрок, не угадал слово и истратил кол-во допустимых ошибок, то сообщаем ему и завершаем программу. if (kolOshibok < 0) { wcout << L"\nУвы, у тебя, закончились допустимые ошибки.\n"; wcout << L"Слово было такое: \""; wcout << slovo; wcout << L"\".\n"; wcout << L"Спасибо, за игру, было приятно с тобой поиграть.\n"; //Выход из программы-игры "Виселица". return 0; } Povtor: //Вывод отгадываемого слова на экран wcout << otgSlovo << L"\n"; //Запрос на получение ответа от игрока wcout << L"Кол-во допустимых ошибок:" << kolOshibok + 1 << ".\n"; wcout << L"Какая будет твоя буква из Русского Алфавита, пожайлуста, вводи маленькой буквой?\n"; wcin >> simvol; SbrosVvoda(); //Проверка на ввод данных от пользователя isPravilno = false; for (i=0; i < 33; i++) if (simvol == alhavit[i]) { isPravilno = true; break; } if (!isPravilno) { wcout << L"\nВведены неверные данные.\n\n"; goto Povtor; } //Проверка на повторение выбранной буквы for (i=0; i < 15; i++) if (simvol == vvedBukva[i]) { wcout << L"\nЭта буква, уже была введена, введи другую букву.\n\n"; goto Povtor; } //Сравнение введеной буквы игроком с буквами загаданного слова isPravilno = false; for (i=0; i<7; i++) if (simvol == slovo[i]) { wcout << L"Правильно, есть такая буква в загаданном слове.\n\n"; otgSlovo[i] = slovo[i]; kolPravilno++; isPravilno = true; break; } if (!isPravilno) { wcout << L"Не правильно, такой буквы в загаданом слове нет.\n\n"; kolOshibok--; }; //Запоминаем введенную букву vvedBukva[indBukva] = simvol; indBukva++; } //--------------------------------------------- //Выход из программы-игры "Виселица". return 0; } |
Сделал видеозапись и добавил ее к статье. В ней рассказаны моменты из статьи, а также дополнено по теме самой статьи. Описание исходного кода начинается с 38 минуты.
В эти выходные приболел, малость, так что, не смогу по планам сегодня закончить следующую статью. Допилю, по кусочкам на следующей неделе.
З.Ы.
И вам, не хворать.
Внесены, некоторые поправки по части пунктуации и орфографии.