Лысаков. Основы программирования (1247269), страница 7
Текст из файла (страница 7)
При этом пользователь мог бы управлятьигроком внутри поля и перемещать его внутри лабиринта.4.1.1. Создание программПри решении любой задачи сначала пишется текст основнойпрограммы, в котором, вместо каждого связного логического фрагментатекста, вставляется вызов подпрограммы, которая будет выполнять этот4.2.1. Подключение внешней библиотекиДляработыстекстовойграфикойпредлагаетсяиспользоватьбиблиотеку текстовой графики Conlib.фрагмент. Вместо настоящих, работающих подпрограмм, в программувставляются «заглушки», которые ничего не делают. Полученнаяпрограмма проверяется и отлаживается. После того, как программистубедится,чтоподпрограммывызываютсявпоследовательнозаменяютсянареальноработающие, причём разработка каждой подпрограммы ведётся тем жеметодом, что и основной программы. Разработка заканчивается тогда,когда не останется ни одной «затычки», которая не была бы удалена.Такаяпоследовательностьгарантирует,чтонакаждомэтаперазработки программист одновременно имеет дело с обозримым ипонятным ему множеством фрагментов, и может быть уверен, что общаяструктуравсехболеевысокихуровнейпрограммыверна.Присопровождении и внесении изменений в программу выясняется, в какиеименно процедуры нужно внести изменения, и они вносятся, не затрагиваячасти программы, непосредственно не связанные с ними.
Это позволяетгарантировать, что при внесении изменений и исправлении ошибок невыйдет из строя какая-то часть программы, находящаяся в данный моментвне зоны внимания программиста.•Conlib.h – описание реализованных в библиотеке функций иописание их вызовов.правильнойпоследовательности (то есть общая структура программы верна),подпрограммы-заглушкиБиблиотека предоставляется в виде двух файлов:•Conlib.lib – реализация функций.Для работы необходимо скопировать оба эти файла в директориюпроекта. После этого прописать добавление деклараций функцийбиблиотеки:#include "conlib.h"Если работа происходит в MSVS2008, то отдельно прописыватьConlib.lib нигде не нужно.Если же работа происходит в MSVS2005, то необходимо явно указать внастройках проекта файл Conlib.lib.
Это делается следующим образом(рис. 7):Настройки проекта –> Configuration options -> Linker ->-> Input -> Additional Dependencies -> … прописать названиеПосле этого библиотека будет включаться в проект и будут доступнывсе ее функции.5556www.phys.nsu.ru•int ClearConsole();производит полную очистку консоли от всего содержимого•int KeyPressed();возвращает не 0, если была нажата какая-либо клавиша наклавиатуре•int GetKey();возвращает код нажатой клавиши•int SetColor(short color);позволяет задавать цвет шрифта и фона4.2.3.
Создание каркаса программыСогласно сформулированным в первой главе описанием алгоритмоврешения задачи, необходимо во-первых определиться с входнымиРис. 7. Добавление внешней библиотеки в проект4.2.2. Основные функции библиотеки ConlibОсновными функциями данной библиотеки для программы бродилкаявляются функции позиционирования на экране и обработка нажатийданными и результатом программы.Итак, входными данными являются:•размер игрового поля;•количество препятствий внутри лабиринта (либо процентзаполнения лабиринта препятствиями).клавиш на клавиатуре для реализации интерактивности и перемещенияигрока по экрану.•Результатом является представление игрового поля в следующем виде(рис.
8):int GotoXY(int x, int y);функция перемещает курсор в заданную координату на экране.•int MaxXY(int *px, int *py);функция определяет максимальные размеры консоли5758www.phys.nsu.ruPlayerY = MaxY / 2;Play(pPole, PlayerX, PlayerY, MaxX, MaxY);}ClearConsole();GotoXY(10, 5);cout << "Press any key to continue...";Разберем более подробно данный код:•функцияInit()определяетвходныепараметрыдляпрограммы, в которые входят размеры игрового поля иколичество препятсвий;Рис. 8.
Проект «бродилка»•функция FillPole() производит заполнение игрового полясодержимым: границами и препятствиямиДалее необходимо составить алгоритм решения задачи. Если у•функция PrintPole() распечатывает игровое поле на экран.человека не возникает больших трудностей с формулировками, то решение•После этого определяются начальные координаты игрока иможет быть сразу представлено в виде кода программы, в которой будутвызывается функция Play(), которая отвечает за обработкуиспользованы функции в качестве логических блоков.клавиатуры и собственно перемещение игрока по полю.int main(){4.2.4. Инициализация переменных программыint MaxX, MaxY;int BarrierCount;Init(&MaxX, &MaxY, &BarrierCount);int* pPole;pPole = new int[MaxX * MaxY];FillPole(pPole, MaxX, MaxY, BarrierCount);PrintPole(pPole, MaxX, MaxY);int PlayerX, PlayerY;PlayerX = MaxX / 2;59Функция Init() получает в качестве аргументов адреса переменных,куда производит запись данных.
Таким образом, вызывая одну функцию,мы получаем все необходимые значения переменных.void Init(int* pMaxX, int* pMaxY, int* pBarrierCount){MaxXY(pMaxX, pMaxY);int Pr;cout << "Input Barriers % = ";cin >> Pr;int PoleSize = (*pMaxX) * (*pMaxY);60www.phys.nsu.ru*pBarrierCount = PoleSize * Pr / 100;}строки последовательно в памяти. В этом случае функция преобразованиядвумерных координат в индекс массива будет выглядеть следующимобразом:4.2.5. Заполнение игрового поляРазумным решением является разделить этот этап на несколько частей:•Прописать все значения в поле нулем. Это необходимо,поскольку при выделении памяти этого автоматически непроисходит.•Расставить границы поля.•Расставить препятствия внутри поля.Помимо этого нам потребуются некоторые вспомогательные функции,которые мы должны реализовать сами.int GetPoleIndex(int x, int y, int MaxX){return (y*MaxX + x);}Определение границ игрового поляФункция последовательно расставляет верхнюю, нижнбб, левую иправую границы.
Особенностями является то, что горизонтальныеграницы закодированы единицей, а вертикальные – двойкой.Это необходимо, поскольку в постановке задачи границы имеютразличное отобраджение.Получение случайного числаСтандартная функция rand() позволяет получить псевдослучайноечисло в диапазоне от 0 до RAND_MAX.Описанная ниже функция позволяет получить псевдослучайноеvoid CreatePoleBorders(int* pPole,int MaxX, int MaxY){int x, y;значение в заданном диапазоне.y = 0;for(x= 0; x < MaxX; x++)*(pPole + GetPoleIndex(x, y, MaxX)) = 1;int GetRandomValue(int Min, int Max){int Val = rand();y = MaxY-1;for(x= 0; x < MaxX; x++)*(pPole + GetPoleIndex(x, y, MaxX)) = 1;int Range = Max - Min;double q = ((double)Val / RAND_MAX) * Range;x = 0;for(y= 0; y < MaxY; y++)*(pPole + GetPoleIndex(x, y, MaxX)) = 2;return (q + Min);}x = MaxX-1;for(y= 0; y < MaxY; y++)*(pPole + GetPoleIndex(x, y, MaxX)) = 2;Правило отображения игрового поляСложность состоит в том, что игровое поле является двумерным, авыделенная память – линейной.
Разумным является расположить все61}62www.phys.nsu.ruПри отображении необходимо учесть возможность сопоставлятьРезультирующая функция заполнения игрового поляС использование всех перечисленных вспомогательных функций,различным кодам – различные символы на экране. Удобнее всегоиспользовать для этого переключатель switch.требуемый блок по заполнению поля препятствиями будет иметьvoid PrintPole(int* pPole, int MaxX, int MaxY){следующий вид:void FillPole(int* pPole, int MaxX,int MaxY, int BarrierCount)int x, y;GotoXY(0, 0);for(y = 0; y < MaxY; y++){for(x= 0; x < MaxX; x++)switch(*(pPole + GetPoleIndex(x, y, MaxX))){case 1: cout << '-'; break;case 2: cout << '|'; break;case 3: cout << '*'; break;default: cout << ' ';break;}cout << endl;}{int x, y;0;for(y = 0; y < MaxY; y++)for(x= 0; x < MaxX; x++)*(pPole + GetPoleIndex(x, y, MaxX)) =CreatePoleBorders(pPole, MaxX, MaxY);int i;for(i = 0; i < BarrierCount; i++){x = GetRandomValue(1, MaxX-1);y = GetRandomValue(1, MaxY-1);*(pPole + GetPoleIndex(x, y, MaxX)) = 3;}}4.2.6.
Отображение игрового поляОтображение поля использует созданные выше вспомогательныефункции отображения.}4.2.7. Обработка клавиатуры и перемещение игрокаvoid Play(int *pPole, int CurX, int CurY,int MaxX, int MaxY){GotoXY(CurX, CurY);cout << 'X';int key;int bExit = 0;while(!bExit){while(!KeyPressed());key = GetKey();GotoXY(CurX, CurY);cout << ' ';6364www.phys.nsu.ruif (key == KEY_ESC)bExit = 1;else if (key == KEY_UP)CurY--;else if (key == KEY_DOWN)CurY++;else if (key == KEY_LEFT)CurX--;else if (key == KEY_RIGHT)CurX++;GotoXY(CurX, CurY);cout << 'X';}}5.
Алгоритмы сортировки данныхСортировка —этоупорядочиваниеэлементовповыбранномупризнаку. В случае чисел критерием может быть признак «больше» или«меньше»,врезультатеотсортированнуюпочегомывозрастаниюполучим(первыйпоследовательность,элементбудетсамыммаленьким) либо по убыванию (первый элемент будет иметь самоебольшое значение).Единственного эффективнейшего алгоритма сортировки не существуетввиду множества параметров оценки эффективности:1.Время — основной параметр, характеризующий быстродействиеалгоритма. Называется также вычислительной сложностью.