Программирование кода игры пятнашки на море с. Домашнее задание. WPF версия игры "Пятнашки" на платформе.NET

27.08.2012 13:22

Подписаться на статьи

Все знают, что в Африке голодают дети. Вопрос - почему они там голодают?

Еда обеспечивается ареалом обитания. И ресурсы ареала обитания контролируют популяцию, которая на нём обитает. И как же так получилось, что раньше ареал обитания афроафриканцев обеспечивал едой определённую популяцию, позволяя ей разрастись, а теперь заставляет всех поголовно голодать?

И тут намвидится только один правильный ответ: колониализм. Белые люди научились покорять природу, заставляя одну и ту же территорию приносить больше еды. Соответственно, уменьшать ареал обитания, необходимый одному человеку, а значит повышать плотность населения. С приходом колонистов в Африку, там стали создаваться условия, которые могли прокормить больше людей (сельское хозяйство, дороги, фабрики). Но где-то в середине XX века белый человек стал отказываться от своих колоний, а афроафриканцы вместе с тем стали бороться за независимость. И в итоге остались одни. Но поддерживать тот уровень цивилизации, который мог прокормить всех, они не могли и не хотели. В результате ареал обитания отдельного индивида стал снова расширяться, поскольку его эффективность падала. И теперь природа снова подгоняет популяцию к её естественному числу путём голода. Ну а та гуманитарная помощь, которую шлют добросердечные граждане из ООН - успешно проедается, но не может изменить ситуацию.

Современные ученые выделяют следующие причины массового голода в Африке:

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

2. Войны и политические конфликты, вызывающие нестабильность и приводящие к появлению беженцев.

3. СПИД и ВИЧ-инфекции. Особенно серьезно эта проблема стоит в странах юга Африки, где около 30% сексуально активного взрослого населения заражено ВИЧ-инфекцией.

4. Демографический бум. "Население стран экваториальной Африки в последние 30 лет росло быстрее, чем в остальных регионах, несмотря на большую смертность от пандемии СПИДа", - говорится в отчете Фонда ООН по народонаселению.

К концу августа от голода на юге Сомали ежедневно будет умирать 2500 человек, если уже сейчас не начать оказывать необходимую помощь голодающим, прогнозирует ООН.

В середине июля ООН официально объявила о голоде в двух южных регионах Сомали, а уже в начале августа о том, что еще 6 регионов приблизились к этой черте. Голод в Сомали уже признали одной из самых крупных гуманитарных катастроф этого рода за всю историю человечества. Согласно нынешним прогнозам, голод может унести жизни свыше 12 миллионов человек по всей Африке.

1. Женщина рядом с ребенком, который страдает от последствий недоедания, в больнице «Банадир» в столице Сомали, Могадишо, .


2. Мухи облепили лицо страдающего от последствий недоедания мальчика в больнице столицs Сомали. Голод - не только результат длительной засухи, но и действий исламистской группировки «Джамаат Аш-Шабааб», которая вытеснила из страны множество западных гуманитарных организаций, тем самым лишив пострадавших от засухи местных жителей необходимой помощи. Ситуация с каждым днем становиться все сложнее и сложнее - десятки тысяч сомалийцев уже умерли, и более 500 тысяч детей находятся на грани голодной смерти.


3. Лицо страдающего от последствий недоедания мальчика закрыто вуалью от мух в больнице Могадишо.


4. Ежедневно тысячи сомалийцев покидают эпицентр кризиса и бегут в столицу или в переполненные лагеря беженцев в Кении и Эфиопии. На фото: Люди, бежавшие из своих поселений, прибывают в столицу Сомали, Могадишо.


5. По данным ООН, в помощи остро нуждаются около 12 миллионов человек, причем не только в Сомали, но также в Эфиопии и Кении - двух других странах региона, чье население страдает от голода, ставшего результатом засухи. На фото: Люди сооружают палатку во временном лагере в Могадишо.


6. Люди, бежавшие из своих деревень, строят временное жилище по прибытии в столицу Сомали.


7. Каждый день около тысячи сомалийцев из южных районов страны пополняют армию обездоленных в Могадишо. На фото: Женщина держит на руках ребенка, страдающего от голода и последствий недоедания.


8. Дети на грани голодной смерти в больнице Могадишо. Нынешняя засуха — сильнейшая на востоке Африки за 60 лет.


9. Ребенок, страдающий от недоедания, в больнице в Могадишо. Связанная с "аль-Каидой" исламистская группировка "Джамаат Аш-Шабааб" контролирует большую часть территории южного Сомали и не дает страдающим от голода людям покинуть страну. Исламисты основали лагеря, где содержатся люди, пытавшиеся бежать с подконтрольных группировке территорий.


10. Женщина купает ребенка, страдающего от недоедания. Члены группировки «Аль-Шабааб» заявили, что сообщения ООН о сильном голоде в стране являются «явной пропагандой», и оставили в силе запрет на оказание гуманитарной помощи западными организациями.


11. Женщина несет ребенка во временное жилище в Могадишо. По данным ООН, на грани выживания находится около трети населения Сомали, а также миллионы жителей других стран Африканского Рога — Джибути, Кении, Уганды и Эфиопии.


12. Власти предупреждают, что около 800 тысяч детей могут погибнуть от голода в странах Восточной Африки - Сомали, Эфиопии, Эритреи и Кении.


13. Солдаты Временного федерального правительства Сомали патрулируют пограничный сомалийский город Дхобли. Тысячи людей прибыли в Могадишо в надежде получить гуманитарную помощь. Исполнительный директор Всемирной продовольственной программы Жозетт Ширан сообщила, что организация не в состоянии обеспечить продовольствием 2,2 миллиона сомалийцев, которые отчаянно нуждаются в гуманитарной помощи.


14. Сомалийцы стоят в очереди за гуманитарной помощью в Могадишо. Пункты гуманитарной помощи в пораженных засухой странах Восточной Африки переполнены тысячами голодающих, многие женщины оставляют своих детей умирать на обочине, так как они не могут дойти до центров помощи.


15. Вид с воздуха на лагерь Дадааб в Кении. C началом праздника Рамадан регистрация новоприбывших проходит намного медленнее, чем обычно. Ситуация усложняется и тем, что многие беженцы, и так уже сильно истощённые, полны решимости соблюдать предписанный Рамаданом дневной пост.


16. Недавно прибывшие сомалийские беженцы селятся на окраине лагеря «Dagahaley», который является частью огромного поселения беженцев в Дадаабе, Кения. Лагерь для беженцев в Дадаабе, основанный в начале 1990-х годов недалеко от границы Кении и Сомали, первоначально был рассчитан на 90 тысяч человек, но, по оценкам ООН, сейчас здесь проживает в 4 раз больше беженцев. В результате гражданской войны и сильнейшей за последние 60 лет засухи, жизни около 12 миллионов людей оказались в опасности.


17. Сомалийская беженка гонит стадо коз в лагере «IFO», который является частью огромного поселения беженцев в Дадаабе, Кения. ООН призывает Кению открыть новый лагерь для беженцев. Дадааб, разросшийся до гигантских размеров, уже не вмещает всех беженцев из Сомали.


18. Работники склада разгружают мешки с продовольствием в лагере Дадааб.


19. Сомалийские беженцы ожидают у входа в зону регистрации лагеря для беженцев «IFO», который является частью огромного поселения беженцев в Дадаабе.


20. Куфоу Али Абди несет тело своей 3-летней дочери, которая умерла от кори в одной больниц Могадишо. "Я надеюсь, что им удастся спасти остальных", - говорит Абди, у которого осталось еще двое детей.


21. Сомалийская беженка несет мешок с гуманитарной помощью мимо людей, ожидающих в зоне регистрации лагеря для беженцев «IFO».


22. Сомалийские женщины и дети ожидают распределения продовольствия в районе Долоу на юге Сомали. 26 июля воздушные поставки продуктов питания, осуществляемые Всемирной продовольственной программой, были приостановлены из-за возникших в последний момент проблем с документами.


23. Сомалийские беженцы выходят из своей хижины на окраине лагеря «Dagahaley», который является частью огромного поселения беженцев в Дадаабе, Кения. Тысячи жителей Сомали покинули страну, спасаясь от голода и насилия.


24. Сомалийский беженец копает яму для отхожего места на окраине лагеря «IFO», который является частью огромного поселения беженцев в Дадаабе.


25. Пожилая женщина сидит в ожидании раздачи продуктов в центре раздачи продовольствия в Локуте, возле Ваджира.


26. Сомалийский беженец отдыхает на тачке у входа в зону регистрации лагеря для беженцев «IFO», который является частью огромного поселения беженцев в Дадаабе.


27. Мальчик из южного Сомали завернулся в целлофановую пленку в лагере для беженцев в Могадишу.


28. Доктор осматривает истощенного семимесячного мальчика в полевом госпитале Международного комитета спасения лагеря Дадааб.


29. Страдающий от недоедания слабоумный ребенок из Сомали привязан к кровати, чтобы не упасть с нее. Снимок сделан в полевом госпитале Международного комитета спасения лагеря Дадааб.


30. Врач берет кровь на анализ у страдающего от недоедания сомалийского беженца в полевом госпитале Международного комитета спасения в Дадаабе, Кения.


31. Халиф Юсуф пытается уснуть в полевом госпитале Международного комитета спасения в Дадаабе.


32. Недавно прибывшая в лагерь для беженцев Дадааб сомалийка с ребенком ждет своей очереди на медосмотр.


Итак, на протяжении семи уроков мы с вами овладели минимальным набором знаний и умений для написания простейших игр на C++. Однако "простейших" не значит "скучных"! Инструментов, описанных в предыдущих уроках вполне хватит, чтобы написать игру под названием "пятнашки". На ее примере я покажу, как происходит создание программы на C++, о чем вы должны думать при работе над программой, чем обусловлен выбор того или иного инструмента языка и как вообще из отдельных элементов собрать цельную программу. В книгах и учебниках по программированию почему-то эти вопросы часто игнорируются, внимание уделяется только отдельным элементам языка, поэтому новичку в программировании приходится самому изобретать велосипед, пытаясь понять, как из этого, этого и вот этого создать работающую программу. Поэтому данный урок будет посвящен скорее общим идеям программирования, в частности - программирования на C++.
Быть может, кое-что из нижесказанного покажется вам описанным излишне подробно, а что-то вы и вовсе сочтете излишним, однако я рекомендую вам очень внимательно отнестись к моим рассуждениям и советам - они содержат действительно нужные и полезные сведения, которые пригодятся вам при написании и более серьезных программ.
Итак, приступим!

Шаг первый: постановка задачи
Самый первый вопрос, который вы должны себе задать, звучит примерно так: "Что должна делать эта программа? Какие функции она должна выполнять? Какими особенностями должна она обладать? Как должна выглядеть работа программы?" Ответы на эти вопросы составят приблизительный список требований, предъявляемый к программе и помогут нам яснее представить себе, что именно нам предстоит сделать.
В нашем случае я представил себе ответы на эти вопросы (и, соответственно, реализацию игры) так: "Программа должна реализовывать игру "Пятнашки". Первоначально поле должно быть перемешано произвольным образом, а игрок должен перемещать костяшки до тех пор, пока поле не будет собрана должным образом. При этом задача должна быть обязательно разрешимой. Рисование будет производиться с помощью псевдографики, а управление должно осуществляться с помощью клавиатуры." Пока это все, что нам нужно. Исходя из такой постановки задачи можно уже представить себе примерную структуру программы.

Шаг второй: проектирование структуры программы
Следующий не менее вопрос, который вам предстоит себе задать, после того, как вы определились с конкретизацией своей цели: "Какова должна быть структура программы? Из каких частей она должна состоять? Как эти части должны взаимодействовать друг с другом?" Поверьте мне, не стоит лепить код, если вы даже близко себе не представляете, как будет организована ваша программа. В лучшем случае наделаете кучу лишнего, в худшем - просто не сможете увязать друг с другом отдельные обрывки кода. При увеличении объема проекта важность проектирования возрастает в геометрической (приблизительно!;)) прогрессии!
На этом этапе нам уже необходимо обратиться к особенностям конкретного языка программирования (вообще говоря, выбор средств и инструментов, таких как конкретный язык программирования предшествует данному этапу, но для нас такой вопрос не стоит, поэтому мы его опустим). Во-первых, как театр начинается с вешалки, так и выполнение программы, написанной на языке C++, начинается с функции main . Она должна стать центром, в котором происходит обращение ко всем прочим частям и элементам программы. Кроме того, функция main должна во многом отражать структуру программы. Чаще всего в главной функции, и в главном модуле программы содержится меньшая часть кода по сравнению со всеми прочими частями. Итак, в функцию main мы сведем все прочие элементы программы, придав им четкую и ясную структуру. Но сначала определимся с этими самыми элементами.
Работая на языке C++ мы для разделения кода данной конкретной игры применим функции, каждая из которых будет выполнять строго определенные действия, реализуя вполне определенные части поставленной задачи. Итак, как должна выглядеть игра "Пятнашки", и какими данными должна оперировать программа?
Разумеется, что центральным объектом в данной игре является игровое поле размером 4 на 4 клетки. Естественным образом будет представить его в виде массива (краткий ликбез по массивам вы найдете чуть ниже по тексту, а более полный рассказ - в следующих уроках) целых чисел - каждый элемент массива будет содержать в себе номер костяшки. Представляется, что других фундаментальных объектов нам не понадобится.
Теперь представим себе, какие действия и в каком порядке должна будет выполнять программа. Во-первых, нам нужно будет сгенерировать первоначальное расположение костяшек (помним, что мы требуем от этого начального расположения разрешимость всей задачи!). Во-вторых, нам, несомненно, потребуется рисовать поле. В-третьих, игра должна завершиться как только поле будет собрано правильно, поэтому нам понадобится функция, выполняющая проверку правильности текущего положения костяшек. Сам же процесс игры будет происходить следующим образом. Сначала программа генерирует поле с учетом всех требований. Затем вплоть до завершения сборки поля происходит игровой цикл, включающий в себя: считывание с клавиатуры нажатия клавиши, перемещение костяшек в соответствии с нажатой клавишей, перерисовку поля. И наконец (после выхода из игрового цикла, т.е. после сборки поля) программа поздравляет победителя и завершается.
И здесь мы обнаруживаем, что забыли про функцию, перемещающую костяшки! Это естественно, т.к. прикидывая в уме список функций еще до определения четкой структуры программы мы далеко не всегда можем себе представить, что нам действительно понадобится, а что - нет. К счастью, наша забывчивость не смертельна, и ошибка была обнаружена еще на раннем этапе проектирования, и ничего не мешает нам добавить в список четвертую функцию. Впрочем, в больших проектах подобные (а также более серьезные) ошибки могут произойти позже, что в итоге может привести к кардинальному пересмотру всей структуры программы. Именно поэтому так важно заранее спроектировать программу, чтобы заранее предусмотреть все возможные сложные места и потенциальные ошибки.

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

Шаг третий: объявляем переменные и пишем функции
Надеюсь, вам еще не наскучило столь продолжительное словоблудие?;) Мужайтесь, мы переходим непосредственно к программированию! Но не забывайте также, что все, что было сказано выше - действительно важно и представляет вам вполне подходящий образец рассуждений, помогающих писать понятные и эффективные программы!
Итак, начинаем оформлять все эти мысли в виде кода, понятного нашему компилятору. Первым делом мы объявим объект, который будет представлением игрового поля. Как я уже говорил выше, мы представим его в виде массива, причем двумерного, целых чисел. Для каждого типа T существует тип T[N] - массив элементов типа T. Массив представляет собой набор из N элементов (N должна быть константой) данного типа, пронумерованных от 0 до N - 1. Массив объявляется следующим образом:
Теперь, однако, мы можем вполне четко представить себе структуру программы:

К i-му элементу массива Type Array мы обратимся с помощью конструкции Array[i] :

double series;
double sum = 0;
for (int i = 0; i {
series[i] = 1 / i;
sum += series[i];
}

Многомерные массивы представляются как массивы массивов: int Matrix - массив элементов типа массив целых чисел, по сути - двумерный массив (матрица) целых чисел. Пожалуй, это все, что нам пока надо знать о массивах для написания этой программы.
Итак, мы объявим двумерный массив целых чисел, причем сделаем это в самом начале кода программы, вне блоков, заключенных в фигурные скобки, в том числе - и вне каких-либо функций. Т.е. мы объявим его в глобальной области видимости , сделав этот массив глобальной переменной . Это облегчит нам жизнь, упростив доступ к нему функций - его не надо будет передавать им в качестве аргумента. Встречайте, первая строка кода нашей программы:

Теперь же перейдем к функциям. Самой первой мы напишем функцию генерации поля, коль скоро она у нас первой и вызывается. Определимся сначала с алгоритмом, который мы будем использовать. Как известно, среди всех возможных комбинаций расположения костяшек не всякое является разрешимым. Мы же изначально требовали, чтобы при генерации было получено поле, которое можно привести к правильному виду. Зачастую эту проблему решают не слишком изящно, просто устанавливая сначала поле в правильное положение, а потом перемешивая костяшки по правилам игры. Чтобы получить пристойный результат, надо совершить достаточно большое количество случайных перемещений костяшек, да и алгоритм получается не самым простым.
Но - открою вам секрет! - на самом деле так мучиться не надо! Существует гораздо более простой и рациональный способ определить разрешимое начальное положение костяшек. Для этого мы прибегнем к помощи математической теории игры "пятнашки". Лично я необходимые для этого знания почерпнул давно - после того, как в детском саду стал обладателем книжек "Занимательные задачи для маленьких" и "Смекалка для малышей" (о том, что детям полезно читать правильные книжки даже в наш цифровой век - как-нибудь в другой раз!;)). Именно, первая из них, составленная на основе книг Я. И. Перельмана, рассказывала об истории этой игры, разрешимых и неразрешимых задачах в ней, а также о способе, позволяющем узнать, можно ли данное расположение костяшек привести к исходному. Суть его заключается в следующем. Пусть у нас имеется некоторое расположение костяшек на поле, причем в правом нижнем углу костяшек нет. Беспорядком называется такое положение костяшки, при котором она стоит ранее другой костяшки, имеющей меньший номер. Сколько костяшек с меньшими номерами стоят после данной - таково количество беспорядков для нее. Если общее число беспорядков на всем поле - четное, то его можно привести в правильное расположение, если же нечетное - то этого никак нельзя сделать согласна правилам игры.
Вооружившись этой ценной информацией, приступим теперь к написанию кода функции. Первым делом мы просто-напросто сгенерируем абсолютно случайное расположение костяшек.

void CreateField()
{
bool NumIsFree; //NumIsFree[i] показывает, определили ли мы уже позицию i-й костяшки
int Nums; //Nums[i] содержит номер костяшки, находящейся в i-й позиции
for (int i = 0; i NumIsFree[i] = true;
randomize(); //randomize позволяет при каждом прогоне программы получать разные последовательности псевдослучайных чисел
bool Ok; //Флаг, определяющий корректность выбора костяшки для данной позиции
int RandNum; //Номер костяшки, генерируемый в дальнейшем случайным образом
for (int i = 0; i {
Ok = false; //Каждый раз сбрасываем значение флага
while (!Ok) //Продолжаем случайным образом определять номер костяшки, пока он не окажется корректным
{
RandNum = random(15) + 1; //random(n) генерирует псевдослучайное число от 0 до n - 1, а нам нужно от 1 до 15
if (NumIsFree) //Если костяшка с таким номером еще свободна (помним, что массивы нумеруются начиная с нуля)
Ok = true; //то мы определили ее номер корректно
}
Nums[i] = RandNum; //Записываем этот корректный номер в i-ю позицию
NumIsFree = false; //Костяшка с этим номером теперь занята
}
}

Затем нам нужно будет посчитать общее число беспорядков на поле, и если их окажется нечетное число, то мы поменяем местами костяшки на 14-й и 15-й позиции - при этом число беспорядков изменится на единицу и станет четным. В код функции добавится следующее:

И наконец нам осталось только перевести информацию о расположении костяшек из вида, удобного для анализа, в вид, удобный для игры, а также назначить координаты пустой ячейки:

Следующая функция, которую мы напишем - функция рисования игрового поля. Рисовать мы его будем псевдографически, впрочем, для простоты будем использовать не собственно символы псевдографики, а вполне обычные печатные символы. Каждая костяшка будет занимать пространство четыре символа в ширину и три в высоту, номер будет выводиться посередине второго ряда. Допустим, что "рамку" костяшки мы будем рисовать с помощью знаков +. Т.е. в собранном виде поле будет иметь такой вид:

++++++++++++++++
+ 1++ 2++ 3++ 4+
++++++++++++++++
++++++++++++++++
+ 5++ 6++ 7++ 8+
++++++++++++++++
++++++++++++++++
+ 9++10++11++12+
++++++++++++++++
++++++++++++
+13++14++15+
++++++++++++

Реализовать функцию можно двумя способами: либо рисовать по отдельности каждую костяшку с использованием функции gotoxy , либо рисовать по очереди все 12 рядов символов, представляющих изображение поля с использованием просто перевода строки. Первый способ более логичный и наглядный, однако, плохо переносимый, т.к. функция gotoxy , устанавливающая курсор в точке с указанными координатами, есть не во всех средах разработки (например, в IDE от фирмы Borland - Borland C++ и Borland C++ Builder она есть, а в Microsoft Visual C++ ее нет). Второй способ менее прозрачный, но использует только стандартные функции. Итак, приведем пример обоих реализаций функции:

Соответственно, здесь мы не рисуем ничего в клетке, содержащей 0, т.е. в которой нет костяшки. С помощью функции cout.width(2) мы указываем программе, что при следующем выводе потока cout (ко всем остальным это уже не будет относиться) ширина поля будет не менее двух символов; если для вывода потребуется всего один символ, то перед ним будет выведен пробел, если потребуется больше двух символов, то будут выведены все они (в нашем случае этого не произойдет).

Теперь напишем функцию, осуществляющую перемещение костяшек. Именно для этой функции нам будут полезны координаты свободной клетки игрового поля - EmptyX и EmptyY: во-первых, не надо будет каждый раз просматривать все поле в поисках этой клетки, во-вторых, даже если это делать, ее координаты все равно понадобятся - для самого перемещения соседней костяшки и для проверки корректности попытки перемещения.
Сделаем небольшое уточнение по работе функции. Будем считать, что при нажатии игроком клавиш со стрелками мы перемещаем одну из костяшек на свободную клетку в направлении, соответствующем этой стрелке. Т.е. если игрок нажал клавишу "влево", то на свободное поле (влево) перемещается костяшка, находившаяся справа от него, если только это можно сделать (свободная клетка не была в правом столбце).
Логично было бы при нажатии клавиши в функции main просто вызывать функцию перемещения, передавая ей информацию о том, какая из клавиш со стрелками была нажата, т.е. куда следует передвинуть одну из костяшек, если это возможно. Поэтому функция перемещения должна иметь аргумент, обозначающий направление. Конечно, можно для этой цели использовать, например, целые значения, но лучше всего определить для понятия "направление" особый тип-перечисление и передавать в качестве аргумента переменную этого типа. Это сделать очень просто: в самом начале кода программы, непосредственно перед объявлением наших глобальных переменных напишем:

enum Direction {LEFT, UP, RIGHT, DOWN};

И теперь мы можем передавать LEFT , UP , RIGHT и DOWN (прямо так, без всяких кавычек или еще чего-то) в качестве аргументов и вообще использовать как любые другие объекты любого другого встроенного типа. Реализация же функции тогда будет простой и прозрачной:

void Move(Direction dir)
{
switch (dir)
{
case LEFT:
{
if (EmptyX {
Field = Field;
Field = 0;
EmptyX++;
}
} break;
case UP:
{
if (EmptyY {
Field = Field;
Field = 0;
EmptyY++;
}
} break;
case RIGHT:
{
if (EmptyX > 0)
{
Field = Field;
Field = 0;
EmptyX--;
}
} break;
case DOWN:
{
if (EmptyY > 0)
{
Field = Field;
Field = 0;
EmptyY--;
}
} break;
}
}

И наконец, напишем функцию, проверяющую, является ли текущее положение костяшек на поле правильным. В отличие от предыдущих, эта функция возвращает значение, именно - значение логического типа bool . Мы организуем ее код с помощью простого цикла, проверяющего первые пятнадцать позиций поля. Если во время этой проверки обнаруживается хотя бы одна костяшка, находящаяся не на месте, то функция тут же возвращает значение false , не проверяя уже последующие позиции. И только если за всю проверку не будет найдено ни одного несоответствия, и, стало быть, причин преждевременно выйти из функции, будет возвращено значение true:

Теперь мы написали все функции, необходимые для работы программы и можем приступать к написанию функции main .

Шаг четвертый: функция main и заголовочные файлы
Для того, чтобы наши разрозненные функции обрели вид законченной программы, осталось сделать совсем немного - написать функцию main , а также объявить заголовочные файлы, содержащие объявления используемых нами функций. Сначала напишем нашу самую главную функцию - в самом низу кода, под всеми объявлениями и определениями. По сути под программой можно понимать именно ее - все остальные функции будут вызываться внутри нее, сама же функция main определяет логику работы программы. Поскольку мы уже в самом начале определили структуру нашей программы, то сейчас мы запишем то же самое, только в виде кода C++:

И теперь нам осталось только подключить нужные нам заголовочные файлы, добавив в самое начало кода (перед чем бы то ни было) следующие строки:

Хотя чаще всего подключение заголовочных файлов происходит по мере написания кода программы. Например, если я знаю, что в программе мне обязательно придется что-то выводить или считывать с помощью стандартных потоков ввода/вывода, то первой строкой ее кода обычно будет подключение заголовочного файла iostream . В дальнейшем если я использую в коде какую-то функцию из одного из заголовочных файлов, то одновременно с ее первым появлением в коде подключается необходимый файл. Ну а если я забываю это сделать, то я подключаю его после того, как компилятор заругается на незнакомую ему функцию!)

Заключение
Итак, наша первая программа, игра "Пятнашки" наконец готова! Рассказывая вам о ее написании, я постарался как можно более подробно описать вам логику создания программ, показав, о чем нужно думать, чтобы точно и корректно превратить изначальную задумку программы в готовый и работоспособный код, достаточно простой для понимания и эффективный. Возможно, некоторые из моих рассуждений покажутся вам чересчур подробными и занудными, однако эта подробность призвана наиболее полно ответить на вопросы, встающие перед начинающим программистом, не имеющим опыта создания программ на каком бы то ни было языке программирования. Скорее всего, в дальнейшем большую часть этих рассуждений вы будете проделывать "в фоновом режиме", не разделяя их на отдельные пункты, однако, чтобы довести что-то до автоматизма, необходимо сперва понять, как точно это должно делаться.
Следующий мой урок будет посвящен правильной организации кода - я расскажу о правилах, которыми нужно руководствоваться, чтобы хорошо писать программы, делая их более читаемыми и более логичными по структуре. Не пропустите!

Статьи по теме: