Игра "Пятнашки"
Игра "Пятнашки"
2
Содержание
1. Введение 3
2. Назначение и область применения 4
3. Цели и задачи 4
4. Используемые методы 5
5. Описание алгоритма программы 8
6. Описание входных и выводных данных 24
7. Программное и аппаратное обеспечение программы 24
8. Руководство пользователя 25
9. Заключение 30
10. Список литературы 31
Приложение 1 Листинг программы 32
Приложение 2 Результаты работы. 46
1. Введение
После изучения предмета Основы алгоритмизации и программирования, необходимо выполнить курсовой проект.
После изучение предложенных тем выбрана очень популярная и всем известная игра в «пятнашки».
При изучении предметной области, выяснилось, что «пятнашки» на первый взгляд простая игра, но для ее реализации необходимо обратится практически ко всем разделам программирования в среде Турбо Паскаль.
Суть самой игры заключается в следующем:
- Игрок на экране видит табло, которое разбито на 16 клеток. В пятнадцати из них расположены неповторяющиеся цифры, в случайном порядке от 1 до 15 и одна пустая.
В общем виде данное табло можно представить в виде таблицы 1:
Таблица 1 - Образец табло.
5
|
7
|
3
|
8
|
|
15
|
1
|
13
|
2
|
|
14
|
10
|
6
|
4
|
|
|
9
|
11
|
12
|
|
|
- Игрок должен перемещать по одной клетки с цифрой на пустое место.
- Так происходит до тех пор, пока пользователь не выстроит последовательную комбинацию цифр (Таблица 2), и лишь после этого игрок считается победителем.
Таблица 2 - Правильное заполнение табло.
1
|
2
|
3
|
4
|
|
5
|
6
|
7
|
8
|
|
9
|
10
|
11
|
12
|
|
13
|
14
|
15
|
|
|
|
2. Назначение и область применения
Данная программа является, компьютерной версии знаменитой игры «пятнашки». Это логически не сложная и достаточно простая в управлении и использовании программа. Применения данной программы возможны везде, ведь в любой работе нужен отдых, а данная простенькая игра поможет расслабиться и отвлечься от повседневных дел.
3. Цели и задачи.
Целью данной курсовой работы является углубление знаний и расширение навыков по разработке алгоритмов и их реализации на персональном компьютере. Курсовая работа выполнена в среде Турбо Паскаль с использованием графических возможностей языка.
В курсовой работе используются основные возможности языка в работе со структурами, файлами, графикой.
В данной игре предполагалось создание:
a. интуитивно понятного интерфейса;
b. скромного, но графически точного табло, где осуществляется перемещение цифр;
c. удобного для пользователя управления;
d. доступного для понимания руководства пользователя;
e. списка лучших игроков, т.е. тех игроков, которые за наименьшее количество ходов собрали требуемую комбинацию цифр.
f. Возможность в любой момент покинуть игру.
В данной программе использовались следующие разделы Турбо Паскаль:
- Управляющие структуры (условие, циклы);
- Массивы (одномерные, двумерные);
- Символы и строки;
- Процедуры;
- Работа с файлами;
- Работа с графическими возможностями.
В итоги получилась программа - игра, в которой использовались основные возможности среды Турбо Паскаль.
4. Используемые методы
Программа выполнена в среде программирования Турбо Паскаль. Сама программа - приложение Windows. Для вывода графических объектов используются модуль Graph. Программой обрабатываются события от нажатия клавиш на клавиатуре, выбора соответствующих пунктов меню, а также считывание количества ходов для ведение статистики лучших игроков.
Для того чтобы не усложнять листинг программы, вся программа разбита на процедуры, каждая из которых отвечает за определенное действие. Всю программу можно разделить на два основных раздела:
- Основные процедуры, т.е. те процедуры, которые отвечают за саму игру и взаимодействие с пользователем во время игры;
- Вспомогательные процедуры. Это те процедуры, которые дополняют данное приложение дополнительными и очень полезными функциями;
- Основная программа.
К основным процедурам относятся:
- Tablo;
- Vivod;
- Napravlenie;
- Poisk;
- Zamena;
- Proverka;
- Mesto;
- Game15
К вспомогательным процедурам относится:
- ReadFile;
- WriteFile;
- Bonus.
Алгоритм всей программы описан в пункте 5, а в данном разделе опишем основные приемы используемых процедур.
4.1 Основные процедуры.
4.1.1 procedure Tablo;
Данная процедура формирует табло, заполненное случайными, неповторяющимися цифрами от 1 до 15 и одной пустой клеткой. Процедура реализована с использованием двух массивов: одномерный и двумерный.
Одномерный массив с 16 целыми числами заполняется случайным образом, причем, учитывается, чтобы цифры в данном массиве не повторялись.
Каждой цифре из одномерного массива присваивается, аналогичный ей строковый элемент и вводится в двумерный массив. К примеру, цифре 5, присваивается строковый элемент `5 `. Исключение составляет цифра 16, ей присваивается пробел.
4.1.2 procedure Vivod;
Процедура вывода на экран табло с цифрами сформированное на момент отображения. Если программа только запущенна, тогда на экран выводится таблица заполненное случайным образом. Если игра уже идет то данная процедура выводит на экран ту комбинацию цифр, которая определена пользователем во время игры.
4.1.3 procedure Napravlenie;
В данной процедуре пользователю, при помощи курсора, предлагается ввести направление перехода. В данной процедуре считывается код нажатой клавиши, чтоб в дальнейшем можно было осуществлять передвижение.
4.1.4 Procedure Poisk;
В этой процедуре осуществляется поиск пустого элемента. Это необходимо для того, чтоб в дальнейшем пользователь смог относительно пустого элемента сделать свой ход. Процедура считывает каждый элемент двумерного массива и сравнивает его с пустым. После того как пустой найден процедура запоминает координаты пустого элемента, а именно строку и столбец.
4.1.5 procedure Zamena;
Программа в зависимости от выбора направления осуществляет перестановку элементов в двумерном массиве.
Также в данной процедуре считывается каждый ход пользователя, чтобы в дальнейшем, если пользователь разложит требуемый расклад быстрее, чем игроки, игравшие ранее, можно было ввести информацию об игроке в файл.
4.1.6 procedure proverka;
После совершения перестановки цифр, а иными словами после очередного хода, программа сравнивает расстановку цифр в двумерной матрицы. Если текущая комбинация является правильной, тогда игрок считается победителем.
4.1.7 procedure Mesto;
В случае если игрок считается победителем, то в данная процедура сравнивает текущей результат (количество ходов за которое игрок разложил расклад), с игроками игравшими ранее. Если данный игрок разложил быстрее, то ему предлагается ввести имя и его имя и результат сохранятся в файл.
4.1.8 procedure Game15;
Эта процедура является основной. В ней подключается графический модуль и происходит основной процесс игры.
Игра будет продолжаться до тех пор, пока не будет разложен правильный расклад или до тех пор пока пользователь не прервет игру при помощи клавиши ESC.
4.2 Вспомогательные процедуры.
4.2.2 procedure readFile;
После ввода имени пользователя (пункт 4.1.7), информация добавляется в файл res.txt
4.2.3 procedure writeFile;
Данная процедура считывает информацию с файла res.txt и выводит на экран полученные данные, а именно игроков, которые за наименьшее количество ходов разложили требуемую комбинацию.
4.2.4 procedure bonus;
Маленькая хитрость данной программы. Она предназначена для разработчика программы и для преподавателя проверяющего правильность написания игры. Чтобы, при проверке, преподавателю не требовалась проходить всю игру, достаточно нажать клавишу End на клавиатуре и расклад почти разолжется. Также эта процедура была бы очень полезна разработчику, для отладки и тестирования программы.
4.3 Основная программа.
В основной программе на экране выводится Главное меню и в зависимости от выбранных пользователем действий происходит взаимодействие с процедурами.
В действительности некоторые процедуры можно было объединить, т.к. основная цель использования процедур это исключение повторяющихся действий, а в данной программе некоторые процедуры используются один раз и их можно было записать в другие процедуры или основную программу, но, на мой взгляд, так гораздо удобнее, как при программировании, так и при проверки.
5. Описание алгоритма программы
Несмотря на простоту данной программы, написание алгоритма оказалось достаточно не простой задачей. В связи с этим пришлось разделить его, в целях его читаемости и доступности.
Основной алгоритм программы разбит на четыре раздела (схема 1):
- Описание;
- Управление;
- Игра;
- Результаты.
Схема 1 - Основной алгоритм программы
5.1 Раздел Описание.
Данный раздел предназначен для ознакомления пользователем, с возможностями, программы.
Раздел реализован при помощи процедуры Avtor. Данная процедура считывает информацию из файла fhelp1.txt и выводит считанную информацию на экран, для ознакомления пользователю.
Общий алгоритм данного раздела заключается в следующем (Схема 2):
– Чтение информации из файла fhelp1.txt;
– Вывод информации из файла на экран;
– Закрытие файла.
Схема 2 Алгоритм - Описание
5.1.1 Чтение файла.
При помощи процедуры assign(f,'fhelp1.txt'), связываем файловую переменную f с файлом fhelp1.txt, к которому происходит обращение. В данном варианте не описывается полный путь к файлу, подразумевая, что данный файл находится в корне каталога с программой. Это необходимо в тех случаях, когда пользователь захочет перенести файлы программы в любое удобное для него место, если бы был прописан полный путь, тогда пользователь не мог бы перемещать файлы программы, а в случае перемещения, информация из раздела Описание, не выводилась бы на экран. В этом случае, необходимо было бы точно устанавливать файлы программы, в то место, где было бы прописано. Далее при помощи процедуры reset(f) открываем файл для чтения.
5.1.2 Вывод информации на экран осуществляется при помощи инструкций readln(f,g1); writeln(g1). В данной инструкции, переменной g1, сначала при помощи readln присваивается строка из файла fhelp1.txt, а затем при помощи writeln выводится на экран содержимое переменной g1.
5.1.3 Закрытие файла, осуществляется при помощи процедуры close (f);
5.2 Раздел Управление.
В данном разделе, пользователю предлагается ознакомиться с клавишами управления.
Раздел реализован при помощи процедуры help. Данная процедура считывает информацию из файла fhelp.txt и выводит считанную информацию на экран для ознакомления пользователю.
Реализована данная процедура, точно таким же способом, как и в разделе 5.1 Описание, за исключением того, что обращение происходит к файлу fhelp.txt, по этому подробно останавливаться на данном разделе не имеет смысла.
5.3 Раздел Игра.
Данный раздел является основным. Именно в этом разделе происходят основные события. Реализован данный алгоритм при помощи процедуры Game15.
Алгоритм данного раздела заключается в следующем:
- Инициализация графического режима;
- Заполнение в памяти компьютера табло случайными цифрами;
- Вывод табло на экран;
- Ввод направления перехода;
- Поиск пустого элемента;
- Перемещение элементов табло;
- Проверка;
- Итог;
- Ввод личных данных.
Схематично, данный алгоритм, показан на схеме 3.
Нет
Нет
Да
Да
Нет
Схема 3 - Раздел Игра.
5.3.1 Инициализация графического режима осуществляется в этой же процедуре Game15, при переходе из Главного меню программы в раздел ИГРА. Переход к графическому режиму осуществляется, при помощи процедуры InitGraph (grDriver, grMode, grPath), где grDriver - это используемы программой драйвер видеоадаптера (VGA), grMode - режим работы видеосистемы (VGAHi), grPath - это место нахождения файла EGAVGA.BGI на диске (как и в случае с файлами, пишем только имя и расширение файла, а не полный путь, для того чтоб в будущем можно было перемещать файлы программы).
5.3.2 Заполнение табло случайными цифрами.
В памяти компьютера создается табло, в котором, в дальнейшем будут производиться перестановки. Табло состоит из шестнадцати клеток (четыре строки и четыре столбца), которое заполняется пятнадцатью, неповторяющимися цифрами от 1 до 15 и одной пустой клеткой.
Данный раздел реализован при помощи процедуры Tablo. Фактически табло, которое описывается ранее это двумерный массив с цифрами от 1 до 15 и ноль. Но отображение цифр на экране и ноля, вместо пустого элемента, делает табло не красивым. Отсюда следует, что двумерный массив, должен содержать строковые или символьные элементы.
Следующем моментом реализации данной процедуры, является заполнение табло случайными цифрами. Для заполнения табло случайными цифрами используется функция random, которая является генератором случайных цифр, но работает соответственно только с цифрами, а у нас строковый двумерный массив.
Проанализировав выше сказанное, приходим к тому, что необходимо создать два массива. Один одномерный из шестнадцати элементов типа integer, второй двумерный, четыре на четыре, типа string. Сначала одномерный массив, в случайном порядке, заполняется целыми неповторяющимися цифрами от 1 до 16, а затем в зависимости от расположения цифр, заполняется двумерный строковый массив. К примеру, если первый элемент одномерного массива равен цифре 11 тогда первому элементу двумерного массива будет присвоено строка «11».
Общий алгоритм данного раздела заключается в следующем (Схема 4):
– Выбор случайного числа;
– Проверка на наличие совпадений в массиве;
– Занесение информации в массив;
– Проверка заполнен ли массив;
– Заполнение двумерного массива.
Да
Нет
Нет
Да
Схема 4 - Раздел Табло
5.3.2.1 Выбор случайного числа.
Некоторой переменной b присваивается случайное число, при помощи функции random. При чем функция random ограничена интервалом от 1 до 16.
5.3.2.2 Проверка на наличие совпадений в массиве
Переменная b сравнивается с каждым элементом массива bs[i], при помощи инструкций For и if. Если такой элемент уже присутствует в одномерном массиве, тогда переменной b, вновь присваивается случайное число. Так происходит до тех пор, пока переменной b не будет присвоена цифра, которой еще нет в массиве.
5.3.2.3 Занесение информации в массив.
Значение переменной b, которое было найдено ранее, вносится в массив bs[i], за последним элементом внесенный в массив
5.3.2.4 Проверка заполнен ли массив.
Программа проверяет заполнен ли массив полностью, если нет, то алгоритм начинается с пункта 5.3.2.1.
В итоге мы имеем одномерный массив заполненный, в случайном порядке неповторяющемся цифрами от 1 до 16.
5.3.2.5 Заполнение двумерного массива.
Заполнение двумерного массива, при помощи инструкции For и переменных i и j, которые обозначают столбец и строку.
Алгоритм заполнения двумерного массива заключается в следующем:
– Первоначально переменной z присваивается единица. Данная переменная нам необходима как счетчик.
– Каждому элементу j строки и i столбца присваивается строковый элемент, в зависимости от цифры стоящей под номером z в одномерном массиве, если текущей элемент одномерного массива содержит цифру 8, то текущему элементу двумерного массива присваивается строковый элемент «8 ». Исключением составляет цифра 16. В этом случае в двумерный массив вводится пробел. Выбор строкового элемента осуществляется при помощи инструкции case.
– Так происходит до тех пор, пока двумерный массив не будет полностью заполнен.
5.3.3 Вывод табло.
В данном разделе на экране появляется табло с текущей комбинацией цифр. Первоначально, табло заполняется случайным образом п. 5.3.2, а в дальнейшем на экране будет отражено текущее состояния цифр на табло, в зависимости от сделанных пользователем ходов.
Данный раздел реализован в процедуре Vivod.
Общий алгоритм данного раздела заключается в следующем (Схема 5):
– Прорисовка клеток;
– Прорисовка рамки;
– Вывод элементов массива по верх клеток табло.
Схема 5 - Раздел Вывод
5.3.3.1 Прорисовка клеток.
Рисование клеток осуществляется в следующем порядке:
- Определения размера будущих клеток, при помощи двух переменных (h1, w1, координаты верхней левой и правой нижней точек);
- При помощи процедуры SetFillStyle, задаем нужный цвет и стиль заполнения. Цвет выберем синий, а стиль заполнения возьмем SolidFill - сплошная заливка текущем цветом, т.е. синим.
- При помощи процедуры Bar вычерчиваем на экране квадрат.
- Чтобы данные действия не повторять 16 раз, используем инструкцию For.
5.3.3.2 Прорисовка рамки.
Для того, чтобы табло имело законченный вид, поместим ранее созданные клетки в рамку, при помощи процедуры Line.
5.3.3.3 Вывод элементов массива по верх клеток табло.
В итоге на экране появляется табло с шестнадцатью клетками, остается лишь в центр этих клеток поместить цифры из двумерного массива.
Так как мы находимся в графическом режиме, то для вывода элементов двумерного массива используем процедуру OutTextXY.
В итоге на экране появится достаточно аккуратное и не плохо оформленное табло с клетками, в центре каждой из которых, находится цифра.
В будущем, когда пользователь будет перемещать клетки, он фактически будет совершать операции с массивом и на экран будет выводиться информация из массива, в котором осуществлена перестановка, а клетки останутся неизменными.
5.3.4 Поиск пустого элемента.
В данном разделе осуществляется поиск пустого элемента, чтобы в дальнейшем относительно него можно было бы осуществлять передвижение
Данный раздел реализован в процедуре Poisk. Программа при помощи инструкции For и переменных i и j сравнивает каждый элемент двумерного массива AS, с пустым элементом, при помощи инструкции IF и когда находит, присваивает значения переменных i и j переменным strok и stolb. Таким образом, переменные strok и stolb как бы являются координатами пустого элемента.
Общий алгоритм данного раздела заключается в следующем (Схема 6):
– Выбор элемента массива;
– Проверка, является ли данный элемент пробелом;
– Присвоение координат строки и столбца переменным.
Нет Нет
Да
Схема 6 - Раздел Поиск
5.3.4.1 Выбор элемента массива.
При помощи инструкции For поочередно будем выбирать каждый элемент массива.
5.3.4.2 Проверка, является ли данный элемент пробелом.
При помощи инструкции If, сравниваем каждый элемент массива с пробелом.
5.3.4.3 Запоминание координат пробела.
Переменным strok и Stolb присваиваем координаты пустого элемента.
5.3.5 Ввод направления перехода.
В данном разделе пользователю предлагается выбрать направление перехода клеток с цифрами, относительно пустой клетки. Выбор осуществляется при помощи курсора, на клавиатуре.
Данный раздел алгоритма реализован в процедуре Napravlenie.
Фактически некоторой переменной ch (типа char) присваивается код нажатой клавиши.
Алгоритм процедуры заключается в следующем:
– Пользователю предлагается, при помощи курсора, ввести направления перехода.
– После того как пользователь, нажал кнопку на клавиатуре, код клавиши присваивается переменной ch, при помощи функции readkey.
К примеру, если пользователь ввел направление курсора вверх, это означает, что пользователь нажал служебную клавишу под кодом 72.
5.3.6 Перемещение элементов табло.
В данном разделе, в зависимости от направления перехода, выбранное ранее при помощи курсора, и местоположение пустой клетки, происходит перемещение:
- Стрелка влево - перемещает влево цифру, стоящую справа от пустой клетки;
- Стрелка вправо - перемещает вправо цифру стоящую слева от пустой клетки;
- Стрелка вниз - перемещает вниз цифру стоящую сверху от пустой клетки;
- Стрелка вверх - перемещает вверх цифру стоящую снизу от пустой клетки.
Данный алгоритм реализован в процедуре Zamena.
Общий алгоритм данного раздела заключается в следующем (Схема 7):
- Выбор направления перестановки;
- Перемещение клеток;
- Запись об очередном сделанном ходе.
Схема 7 - Раздел Замена.
5.3.6.1 Выбор направления перестановки.
Ранее пользователь сделал ход, а это значит, что мы имеем нажатую служебную клавишу, под каким либо номером. При помощи инструкции IF и функции ord, выбирается направления перестановки элементов.
5.3.6.2 Перемещение клеток.
В зависимости от значений переменных Strok, Stolb, которым было присвоено координаты пустого элемента в массиве (5.3.4) и выбранного направления, осуществляется перемещение.
Например, пользователь ввел направление курсора вверх, это означает, что пользователь нажал служебную клавишу под кодом 72, тогда, при помощи инструкции if и функции ord (if ord(ch)=72 then), осуществляется перемещение.
Перемещение осуществляется по следующему принципу: пустой клетки, а именно элементу массива с координатами as[strok,stolb], присваивается содержимое элемента стоящего под пустой клеткой (as[strok,stolb]:= as[strok+1,stolb];), а соответственно элементу, стоящему под пустой клеткой присваивается пробел (as[strok+1,stolb]:=' ';).
5.3.6.3 Запись об очередном сделанном ходе.
При запуске раздела Игра, некоторой переменной hod присваивается 0. Это означает, что пользователь приступил к игре. После каждого сделанного хода, значение переменной hod увеличивается на единицу. В дальнейшем эта информация будет использована, при определении лучших результатов.
5.3.7 Проверка.
В данном разделе программа сравнивает текущую комбинацию цифр, с правильной комбинацией. Если расклады совпадают, то алгоритм выполнен и осуществляется переход к следующему пункту, в противном случае, алгоритм вновь повторяется, начиная с пункта 5.3.3.
Данный раздел реализован в процедуре proverka.
По умолчанию логическая переменная prov равна false (ложь). Программа проверяет если элемент первой строки и первого столбца равен 1, второй равен двум и т.д. и элемент последней строки и последнего столбца равен пустому элементу, то расклад считается, выполнен и переменной prov присваивается значение true (истина).
5.3.8 Итог.
В данном разделе, программа считывает, за какое количество ходов игрок, выполнил требуемый расклад и сравнивает с результатами прошлых игр. Если игрок разложил табло за большее количество ходов, чем это сделали игроки ранее, тогда программа завершает свою работу и переходит в Главное меню, в противном случае пользователю предлагается ввести свое имя. В дальнейшем его имя будет, отображается в списке лучших игроков.
Данный раздел реализован в процедуре Mesto.
Общий алгоритм данного раздела заключается в следующем (Схема 8):
- Количество ходов;
- Считывание результатов из файла;
- Проверка, входит ли данный результат в список лучших;
- Ввод имени;
- Перестановки в файле результатов;
- Сохранения результатов в файл.
Нет
Да
Схема - 8 Раздел Итог.
5.3.8.1 Количество ходов
В течение всей игры, программа записывает каждый сделанный ход. Таким образом, по завершению игры, т.е. когда пользователь разложил верный расклад, а не когда просто покинул игру, мы знаем точное количество ходов, за которое игрок разложил расклад (Количество ходов присваивается переменной hod).
5.3.8.2 Считывание результатов из файла.
В данном разделе программа считывает данные из файла res.txt и для удобства обработки этой информации, вносит ее в два массива it и res. Массив it содержит информацию о количестве ходов, за которое игроки, игравшие ранее разложили расклад, массив res содержит имена этих игроков.
5.3.8.3 Проверка, входит ли данный результат в список лучших
В данном разделе результат текущего игрока сравнивается с результатами игроков из массива it.
В случае если игроки, игравшие ранее разложили расклад за наименьшее количество ходов, то программа завершает свою работу и переходит в Главное меню, в противном случае программа продолжает свою работу (сл. пункт.)
5.3.8.4 Ввод имени.
Пользователю предлагается ввести свое имя, чтобы его имя и результат были сохранены в списке лучших игроков.
5.3.8.5 Перестановки в файле результатов.
В данном разделе необходимо совершить перестановки в массиве, но нужно не просто удалить какой то элемент, а на его место поставить текущий результат, нужно осуществить сдвиг всех элементов на один, а если текущей результат будет десятым, то заменить его.
Эту задачу можно решить несколькими способами. Один из способов, это совершать перестановки непосредственно в массивах it и res и осуществлять сдвиг элементов, но, на мой взгляд, наиболее простой способ, это создать еще два массива, для удобства назовем их itv и resv, и в результате совершить простейшие операции перемещения элементов из одного массива в другой. Эти операции совершим по следующей схеме:
При помощи инструкции For сравниваем каждый элемент массива результатов (it), с результатом текущего игрока (переменная hod). Если результат игрока из массива it меньше результата текущего игрока, то результат и имя игрока из массива it и res присваиваем массивам itv и resv. Если результат текущего игрока меньше чем очередной элемент массива it и больше предыдущего элемента массива it, то результат текущего игрока вносится в очередной элемент массивов itv и его имя присваивается очередному элементу массива resv, а результат текущего элемента массивов it и res добавляется в массивы itv и resv за результатами текущего игрока. Соответственно когда инструкция For начнет сравнивать следующий элемент массива it, то результат текущего игрока, будет меньше, как текущего так и предыдущего элементов массива it, а это не удовлетворяет условию. Это означает, что очередной элемент массивов it и res просто добавится за последним элементом массивов itv и resv. Так будет происходить пока массивы itv и resv не будут полностью заполнены, а последний элемент массивов it и res, соответственно не войдут, во вновь созданный список лучших игроков, которые описаны в массивах itv и resv. В итоге мы осуществим сдвиг результатов на одну позицию.
Для более полного описания данной процедуры рассмотрим пример:
В таблице 3 расположены две строки. В верхней содержатся элементы массива it, а в нижней массива res.
Таблица 3 - Массивы it и res.
It
|
10
|
20
|
30
|
40
|
50
|
60
|
70
|
80
|
90
|
95
|
|
res
|
A
|
B
|
C
|
D
|
E
|
F
|
G
|
H
|
K
|
L
|
|
|
Предположим, что текущий игрок, под именем Z, победил за 44 хода.
Программа начинает искать в каком интервале расположен текущей результат (44). Для этого каждый элемент массива it сравнивается с переменной hod. Если первый элемент меньше 44, то его имя и результат переносится в массивы itv и resv, если следующий элемент меньше 44, то и его переносят в массивы itv и resv (таблица 4)
Таблица 4 - Массивы it и res.
Так происходит до тех пор пока, программа не найдет элемент в массиве it, который больше 44, но при этом программа проверяет, что 44 больше и предыдущего элемента массива it. Если данное условие выполняется, то программа добавляет результат и имя текущего игрока под именем Z, в массивы itv и resv соответственно, а текущий результат из массивов it и res, также добавляется в массив, но уже за результатами игрока Z (Таблица 5).
Таблица 5 - Массивы it и res.
Itv
|
10
|
20
|
30
|
40
|
44
|
50
|
|
|
|
|
|
resv
|
A
|
B
|
C
|
D
|
Z
|
E
|
|
|
|
|
|
|
У нас получилось, что 44 меньше 50, но больше 40, по этому за результатом 40 добавили 44, а за ним текущий элемент с результатом 50.
Далее, при проверки результата 44 со следующем элементом с результатом 60, 44 будет меньше результата 60, но 44 и меньше результата 50, а следовательно, условие не выполняется и игрок с результатом 60 переносится в массивы itv и resv. Так происходит пока оба массива itv и resv, не будут заполнены. А последний результат соответственно исчезнет (Таблица 6)
Таблица 6 - Массивы it и res.
Itv
|
10
|
20
|
30
|
40
|
44
|
50
|
60
|
70
|
80
|
90
|
|
resv
|
A
|
B
|
C
|
D
|
Z
|
E
|
F
|
G
|
H
|
K
|
|
|
На первый взгляд, все достаточно усложнено, но при создании алгоритма перестановки непосредственно внутри массивов it и res, получается еще хуже.
5.3.8.6 Сохранения результатов в файл.
В данном разделе информация из массивов itv и resv вносится в файл res.txt. Данный файл открывается в режиме перезаписи и информация в файле обновляется и когда пользователь выдя в Главное меню зайдет в раздел Результаты, он уже уведет обновленную информацию из файла res.txt и соответственно и свой результат.
5.4 Результаты.
В данном разделе для пользователя отображается информация о лучших игроках, которые за наименьшее количество ходов собрали требуемую комбинацию.
Данный раздел реализован при помощи процедуры result. Данная процедура считывает информацию из файла res.txt и выводит считанную информацию на экран для ознакомления пользователю.
Реализована данная процедура, точно таким же способом, как и в разделе 5.1 Описание, за исключением, того, что обращение происходит к файлу res.txt, по этому подробно останавливаться на данном разделе не имеет смысла.
6. Описание входных и выводных данных
В таблице 7 описываются входные и выходные данные, которые выстроены примерно в том порядке, в котором они должны взаимодействовать с пользователем
Таблица 7 Описание входных и выходных данных
Входные
|
Выходные
|
|
2. Выбор раздела в Главном меню программы
4. Ввод при помощи курсора направления перехода:
- Влево;
- Вправо;
- Вверх
- Вниз;
- ESC - покинуть игру в любой момент
5. Ввод имени в случае победы за наименьшее количество ходов.
|
1. Отображение на экране Главного меню
3. Вывод на экран ранее выбранного раздела:
- Описание - вывод на экран описание программы
- Управление - вывод на экран информацию о клавишах управления
- Результаты - вывод на экран списка лучших игроков
- Игра - Вывод на экран табло с комбинацией цифр
|
|
|
7. Программное и аппаратное обеспечение программы.
Для запуска игры достаточно любого компьютера, на котором установлена хоть какая-нибудь операционная система, семейство Windows.
8. Руководство пользователя
9.
8.1. Для запуска программы необходимо запустить файл Super15.exe. Откроется Главное меню (Рисунок 1)
Рисунок 1 - Главное меню
Основное меню содержит пять пунктов:
1. Описание (About program).
2. Управление (Key).
3. Игра (Play).
4. Результаты (Results).
5. Выход (Exit).
Перемещаясь при помощи курсора вверх или вниз, можно выбирать интересующие Вас меню.
8.2 При первом запуске программы пользователю рекомендуется прочитать раздел Описание (Рисунок 2), в котором указанно:
- Назначение программы;
- Разработчик;
- Описание программы;
Рисунок 2 - Окно Описание
8.3 Раздел Управление.
Здесь пользователю выводится на экран клавиши управления (Рисунок 3).
Рисунок 3 - Управление
8.4 Раздел Игра.
При переходе в этот раздел перед пользователем открывается основное табло игры (Рисунок 4), на котором расположены 15 цифр, заполненные в случайном порядке и одно пустое поле.
Рисунок 4 - Основное игровое поле.
Управление происходит при помощи клавиш курсора:
- Стрелка влево - перемещает влево цифру, стоящую справа от пустой клетки;
- Стрелка вправо - перемещает вправо цифру стоящую слева от пустой клетки;
- Стрелка вниз - перемещает вниз цифру стоящую сверху от пустой клетки;
Стрелка вверх - перемещает вверх цифру стоящую снизу от пустой клетки.
Пользователю необходимо при помощи курсора перемещать клетки табло, до тех пор, пока на экране не отобразится, последовательная комбинация цифр, как показано на рисунке 5
Рисунок 5 - Игровое поле с правильно заполненной, комбинацией.
В течение всей игры, пользователь в любой момент может покинуть игру, для этого достаточно нажать клавишу ESC и игра завершает свою работу, а на экране появится Главное меню программы.
В течение всей игры, программа считает каждый ход игрока и если игрок раскладывает требуемую комбинацию, за меньшее количество ходов, чем это сделали игроки ранее, то после победы, пользователю предлагается ввести свое имя и информация об игроке, который разложил расклад быстрее, заносится в список лучших игроков (Рисунок 6).
Рисунок 6 - Ввод имени
8.5 пункт Результаты.
В данном разделе меню можно посмотреть результаты лучших игроков (Рисунок 7), а именно тех игроков, которые собрали требуемую комбинацию за наименьшее количество ходов.
На экране небольшая табличка в левом столбце Move записано количество ходов, а в правом Name имя игрока.
Рисунок 7 - Список лучших игроков
8.5 Последний пункт меню Выход.
При нажатии на данный пункт меню, программа завершает свою работу.
10. Заключение
Не смотря на внешне кажущуюся простоту данной программы, он таит в себе ряд сложностей, которые реализуются с использованием всех основных приемов Турбо Паскаль. Вообще Турбо Паскаль как среда программирование уже давно устарела, но основы, которые лежат в среде программировании в Турбо Паскаль, лежат в болшенстве известных и популярных приложений. На мой взгляд, изучая программирование в Турбо Паскаль, можно освоить основные приемы программирования.
Целью данной курсовой работы, являлось углубление знаний и расширение навыков по разработке алгоритмов и их реализации на персональном компьютере, на мой взгляд, разработанная мной программа, вполне отвечает поставленным целям. Особенностями данной программы является:
- Четко построенный алгоритм;
- Интуитивно понятный интерфейс;
- Удобное управление;
- Простота в использовании;
- Вполне понятное руководство пользователя;
- Отсутствие лишних дополнений.
11. Список литературы
10.1 Учебное пособие. «Основы алгоритмизации и программирования», Е. Н. Сафьяновой
10.2 Самоучитель. «Программирование в Turbo Pascal», Н. Культин.
10.3 Открытие Интернет источники.
Приложение 1 Листинг программы
program Game;
uses crt, Graph;
var
as:array[1..4,1..4] of string; {Двухмерный массив, содержит элементы табло}
bs:array[1..16] of integer; {Массив для заполнения случайными числами}
men:array[1..5] of integer; {Массив выводи элементы Главного меню}
res:array[1..10] of string; {Имена игроков с лучшими результатами}
it:array[1..10] of integer; {Результаты лучших игроков}
resv:array[1..10] of string; {Массив со вновь сформированным списком лучших игроков}
itv:array[1..10] of integer; {Массив со вновь сформированным списком результатов лучших игроков}
i,j:integer; {Переменные для работы с массивами}
strok, stolb:integer; {Координаты пустого элемента}
hod:integer; {Счетчик, считывает каждый ход сделанный пользователем}
lom:integer; {Переменная для работы с Главным меню}
name:string; {Имя игравшего пользователя}
ch:char; {Переменная, которой присваивается код нажатой клавиши на клавиатуре}
prov:boolean;{Проверка правильности расклада}
f: text; {файловая переменная}
procedure Vivod;
{Процедура вывода на экран табло с цифрами сформированное на момент отображения}
var lx,ly:integer; {Координаты вывода двухмерного массива}
x,y:integer; {Координаты клеток}
j1,i1:integer; {Переменные счетчики, для рисование клеток}
w1,h1:integer; {Ширина и высота клеток}
begin
OutTextXY(210,50,'For leaving press ESC');
w1:=30;
h1:=30; {Клетка размером 30 на 30}
for i1:=0 to 3 do {Цикл, прорисовки клеток}
for j1:=0 to 3 do
begin
x:=235+j1*35; {Сдвиг клеток по х}
y:=150+i1*35; {Сдвиг клеток по у}
setFillStyle(1,1); {Цвет и стиль клеток, цвет синий, стиль заполнение текущем цветом}
Bar(x,y,x+w1,y+h1); {Рисование клетки}
end;
lx:=245;
ly:=162;
for i:=1 to 4 do {Цикл вывода двухмерного массива по вверх клеток}
begin
for j:=1 to 4 do
begin
OutTextXY(lx,ly,as[i,j]); {Вывод текста на экран}
lx:=lx+35;
end;
lx:=245;
ly:=ly+35;
end;
line(220,135,220,300); {Рисование рамки}
line(385,135,385,300);
line(220,135,385,135);
line(220,300,385,300);
end;
procedure Tablo;
{Формирование табло при первом запуске заполненное случайными и неповторяющимися цифрами}
var b:integer; {Переменная, которой присваивается случайное число}
k,z:integer;{Счетчики для операций с массивами}
begin
randomize;
For z:=1 to 16 do
begin
b:=random(15); {Выбор случайного числа}
k:=1;
while k<>17 do {Цикл пока не будет заполнен массив с целыми цифрами}
begin
if bs[k]=b then
begin
b:=random(17);
k:=1;
end
else k:=k+1;
end;
bs[z]:=b; {Присвоение очередного неповторяющегося элемента массива}
end;
z:=1;
for i:=1 to 4 do {Заполнение двухмерного массива, вместо цифр из одномерного, присваиваются строковые элементы}
begin
for j:=1 to 4 do
begin
case bs[z] of
1: as[i,j]:='1 ';
2: as[i,j]:='2 ';
3: as[i,j]:='3 ';
4: as[i,j]:='4 ';
5: as[i,j]:='5 ';
6: as[i,j]:='6 ';
7: as[i,j]:='7 ';
8: as[i,j]:='8 ';
9: as[i,j]:='9 ';
10: as[i,j]:='10';
11: as[i,j]:='11';
12: as[i,j]:='12';
13: as[i,j]:='13';
14: as[i,j]:='14';
15: as[i,j]:='15';
16: as[i,j]:=' ';
end;
z:=z+1;
end;
end;
vivod; {Вывод табло на экран}
end;
Procedure Poisk;
{Поиск пустого элемента в табло}
begin
for i:=1 to 4 do
begin
for j:=1 to 4 do
begin
if as[i,j] = ' ' Then {Поиск, равен ли текущий элемент пробелу}
begin
Strok:=i; {Если равен, то присваиваются координаты пустого элемента}
Stolb:=J
end;
end;
end;
end;
procedure bonus;
{Бонус, для проверки. При нажатии клавиши END на клавиатуре расклад собирается}
begin
as[1,1]:='1 ';as[1,2]:='2 ';as[1,3]:='3 ';as[1,4]:='4 ';
as[2,1]:='5 ';as[2,2]:='6 ';as[2,3]:='7 ';as[2,4]:='8 ';
as[3,1]:='9 ';as[3,2]:='10';as[3,3]:='11';as[3,4]:='12';
as[4,1]:='13';as[4,2]:='14';as[4,4]:='15'; as[4,3]:=' ';
Strok:=4; Stolb:=3;
end;
procedure napravlenie;
{Ввод направления перехода}
begin
ch:=readkey; {Переменной присваивается код нажатой пользователем клавиши на клавиатуре}
end;
procedure Zamena;
{Передвижение клеток с цифрами в зависимости от выбора пользователя}
begin
napravlenie; {Процедура, ввод направления перехода}
if ord (ch)=79 then bonus; {Если нажата клавиша END на клавиатуре то расклад сам собирается}
if ord(ch)=75 then {Если нажата клавиша влево}
begin
if stolb<>4 then {Если это не последний элемент, стоящий у границы табло}
begin
as[strok,stolb]:=as[strok,stolb+1]; {На место пустого элемента присваивается элемент стоящий справа от пустого}
as[strok,stolb+1]:=' '; {Элементу стоящему справа от пустого присваивается пустой элемент}
stolb:=stolb+1; {Новая координата пустого элемента}
hod:=hod+1; {Очередной сделанный ход}
end;
end;
if ord(ch)=72 then {Если нажата клавиша вверх}
begin
if strok<>4 then {Если это не последний элемент, стоящий у границы табло}
begin
as[strok,stolb]:=as[strok+1,stolb]; {На место пустого элемента присваевается элемент стоящий снизу от пустого}
as[strok+1,stolb]:=' '; {Элементу стоящему снизу от пустого присваевается пустой элемент}
strok:=strok+1;{Новая координата пустого элемента}
hod:=hod+1; {Очередной сделанный ход}
end;
end;
if ord(ch)=77 then {Если нажата клавиша вправо}
begin
if stolb<>1 then {Если это не последний элемент, стоящий у границы табло}
begin
as[strok,stolb]:=as[strok,stolb-1]; {На место пустого элемента присваивается элемент стоящий слева от пустого}
as[strok,stolb-1]:=' '; {Элементу стоящему слева от пустого присваивается пустой элемент}
stolb:=stolb-1; {Новая координата пустого элемента}
hod:=hod+1; {Очередной сделанный ход}
end;
end;
if ord(ch)= 80 then {Если нажата клавиша вниз}
begin
if strok<>1 then {Если это не последний элемент, стоящий у границы табло}
begin
as[strok,stolb]:=as[strok-1,stolb];{На место пустого элемента присваивается элемент стоящий сверху от пустого}
as[strok-1,stolb]:=' '; {Элементу стоящему сверху от пустого присваивается пустой элемент}
strok:=strok-1; {Новая координата пустого элемента}
hod:=hod+1; {Очередной сделанный ход}
end;
end;
Vivod;
end;
procedure readFile;
{Добавляет в файл информацию о лучших результатах}
begin
assign(f,'res.txt'); {Объявления файла}
reset(f); {Открытие файла}
j:=1;
for i:=1 to 10 do
begin
readln(f,res[i]); {Занесение имен лучших игроков из файла в массив}
readln(f,it[j]); {Занесение результатов лучших игроков в массив}
j:=j+1; {Счетчик для лучших результатов}
end;
close(f);
end;
procedure writeFile;
{Считывает файл с лучшими результатами}
begin
assign(f,'res.txt'); {Объявление файла}
rewrite(f);{Открытие в режиме перезаписи}
for i:=1 to 10 do
begin
writeln(f,resv[i]);writeln(f,itv[i]); {Внесение информации о лучших игроках и их результатах из массивов в файл}
end;
close(f);
end;
procedure Mesto;
{Процедура в которой устанавливается занял ли игрок какое либо место, если да то занесение в список лучших игроков}
var chetcik:integer; {Счетчик, объявляет что информация о лучим игроке уже внесена, повторной информации не должно быть}
begin
if prov = true then {Если игрок разложил расклад}
begin
readfile; {Процедура считывание информации из файла с лучшими результатами}
chetcik:=0;
j:=1;
for i:=1 to 10 do
begin
if (hod<=it[i]) and (hod>=it[i-1]) and (chetcik<1) then
begin
{Ввод имени игрока}
OutTextXY(132,325,'will Enter name and press Enter:');
line(400,338,530,338);
GoToXY(52,21);
read(name);
{Присвоение очередному элементу данных текущего игрока}
itv[i]:=hod;
resv[i]:=name;
j:=j+1;
chetcik:=1;
end;
{Перенос из одного массива в другой}
if j<=10 then
begin
itv[j]:=it[i];
resv[j]:=res[i];
j:=j+1;
end;
end;
writeFile; {Сохранение информации в файл}
OutTextXY(230,360,'For leaving press ENTER');
readln;
end;
end;
procedure proverka;
{Проверка правильно ли разложено табло}
begin
prov:=false;
if (as[1,1]='1 ') and (as[1,2]='2 ') and (as[1,3]='3 ') and (as[1,4]='4 ')
and (as[2,1]='5 ') and (as[2,2]='6 ') and (as[2,3]='7 ') and (as[2,4]='8 ')
and (as[3,1]='9 ') and (as[3,2]='10') and (as[3,3]='11') and (as[3,4]='12')
and (as[4,1]='13') and (as[4,2]='14') and (as[4,3]='15') and (as[4,4]=' ')
then
begin
prov:=true; {Если табло разложено верно, то ИСТИНА}
OutTextXY(230,100,'Congratulate You have won');
Mesto; {Процедура, устанавливающая на каком месте текущий пользователь}
end;
end;
procedure Game15;
{Подключение графики и переход в режим ИГРЫ}
var grMode:integer; {Режим работы видеосистемы}
grPath:string; {Путь к файлу}
grDriver:integer;{Используемый программой драйвер видеоадаптера}
begin
hod:=0;
grDriver:=VGA;
grmode:=VGAHi;
grPath:='EGAVGA.BGI';
initGraph(grDriver, grMode,grPath); {Инициализация графического режима}
Tablo; {Формирование табло}
Poisk; {Поиск пустого элемента}
repeat {Цикл, пока не нажата клавиша ESC или пока игрок не победил играть}
Zamena; {Передвижение в массиве}
proverka; {Проверка является ли данный расклад верным}
until (ord (ch)=27) or (prov=true);
closeGraph; {Закрытие графического режима}
end;
procedure help;
{Переход в режим справки}
var f: text; {Файловая переменная}
g1:string; {Переменная для работы со строками в файле}
begin
clrscr;
assign(f,'fhelp.txt'); {Объявление файла}
reset(f); {Открытие файла}
readln(f,g1); writeln(g1); {Присвоение переменной строки файла и вывод ее на экран}
readln(f,g1); writeln(g1);
readln(f,g1); writeln(g1);
readln(f,g1); writeln(g1);
readln(f,g1); writeln(g1);
readln(f,g1); writeln(g1);
readln(f,g1); writeln(g1);
writeln('For leaving press ENTER');
readln;
close(f);{Закрытие файла}
end;
procedure result;
{Отображение лучших игроков}
begin
clrscr;
GoToXY(26,5);
writeln('Best players');
assign(f,'res.txt');
reset(f);
readfile; {Считывание информации из файла лучших результатов}
{Вывод на экран в строгом порядке имена и результаты лучших игроков}
GoToXY(26,8); write('Move Name');
GoToXY(26,10); write(it[1]);GoToXY(36,10); writeln(res[1]);
GoToXY(26,11); write(it[2]);GoToXY(36,11);writeln(res[2]);
GoToXY(26,12); write(it[3]);GoToXY(36,12);writeln(res[3]);
GoToXY(26,13); write(it[4]);GoToXY(36,13);writeln(res[4]);
GoToXY(26,14); write(it[5]);GoToXY(36,14);writeln(res[5]);
GoToXY(26,15); write(it[6]);GoToXY(36,15);writeln(res[6]);
GoToXY(26,16); write(it[7]);GoToXY(36,16);writeln(res[7]);
GoToXY(26,17); write(it[8]);GoToXY(36,17);writeln(res[8]);
GoToXY(26,18); write(it[9]);GoToXY(36,18);writeln(res[9]);
GoToXY(26,19); write(it[10]);GoToXY(36,19);;writeln(res[10]);
GoToXY(26,23);writeln('For leaving press ENTER');
readln;
end;
procedure avtor;
{Вывод общей информации на экран в раздел описание }
var f: text; {Файловая переменная}
g1:string; {Переменная которой присваивается очередная строка из файла и выводится на экран}
begin
clrscr;
assign(f,'fhelp1.txt');
reset(f);
readln(f,g1); writeln(g1);
readln(f,g1); writeln(g1);
readln(f,g1); writeln(g1);
readln(f,g1); writeln(g1);
readln(f,g1); writeln(g1);
readln(f,g1); writeln(g1);
readln(f,g1); writeln(g1);
readln(f,g1); writeln(g1);
readln(f,g1); writeln(g1);
readln(f,g1); writeln(g1);
readln(f,g1); writeln(g1);
readln(f,g1); writeln(g1);
readln(f,g1); writeln(g1);
readln(f,g1); writeln(g1);
readln(f,g1); writeln(g1);
readln(f,g1); writeln(g1);
readln(f,g1); writeln(g1);
writeln('For exit press ENTER');
readln;
close(f);
end;
begin
{Основная программа}
{Вывод на экран главного меню}
{Элементы Главного меню, один из которых закрашен белым цветом, а остальные зеленым}
men[1]:=15;
men[2]:=2;
men[3]:=2;
men[4]:=2;
men[5]:=2;
repeat
clrscr;
strok:=1; {Текущая строка}
Lom:=1;
{Выбор цветов}
GoToXY(32,10); Textcolor(men[1]); writeln('Key');
GoToXY(32,11); Textcolor(men[2]); writeln('About program');
GoToXY(32,12); Textcolor(men[3]); writeln('Play');
GoToXY(32,13); Textcolor(men[4]); writeln('Results');
GoToXY(32,14); Textcolor(men[5]); writeln('Exit');
ch:=readkey; {Выбор направления передвижение элементов меню}
if (ord(ch)=80) then {Если вниз тогда текущий становится белым, а нижний становится зеленым}
begin
for i:=1 to 5 do
begin
if (men[i]=15) and (strok<>5) then
begin
men[strok]:=2;
men[strok+1]:=15;
end
else strok:=strok+1;
end;
end;
if ord(ch)=72 then {Если вверх, то текущий белым, а верхний зеленым}
begin
for i:=1 to 5 do
begin
if (men[i]=15) and (strok<>1)then
begin
men[strok]:=2;
men[strok-1]:=15;
end
else strok:=strok+1;
end;
end;
if ord(ch)=13 then {Если нажат ENTER}
begin
for i:=1 to 5 do
begin
if men[i]=15 then
begin
if Lom=1 then begin Help; break; end; {Переход в режим справки}
if Lom=2 then begin avtor; break; end; {Переход в режим игры}
if Lom=3 then begin Game15;break; end; {Переход в режим игры}
if Lom=4 then begin result;break; end; {Переход в режим игры}
end
else Lom:=Lom+1;
end;
end;
until Lom=5 {До тех пор пока не нажат пункт EXIT}
end.
Приложение 2 Результаты работы.
Для демонстрации результата работы программы, возьмем основной раздел ИГРА.
При запуске программы появляется табло, заполненное случайными неповторяющееся цифрами от 1 до 15 и один пустой элемент (Рисунок 8).
Рисунок 8 - Основное табло со случайными числами
Далее пользователю предлагается сделать ход. К примеры переместить цифру на пустое место. Для этого необходимо нажать клавишу (вверх) на клавиатуре. В результате цифра один переместится вверх, а пустая клетка перемещается на место единицы (Рисунок 9).
Рисунок 9 - Первый ход
В дальнейшем перемещая по одной клетки, при помощи курсора, расклад будет выполнен. Весь процесс до победы может занять очень много ходов, поэтому перейдем к предпоследнему моменту.
К примеру, игрок долго играл и у него выпал следующий расклад (Рисунок 10).
Рисунок 10 - очередной ход.
Теперь пользователю необходимо сделать один, последний ход, а именно переместить клетку с цифрой 15 на пустой элемент. В результате расклад будет выполнен (Рисунок 11).
В случае если игрок разложил требуемый расклад за наименьшее количество ходов, чем игроки, игравшие ранее, то пользователю предлагается ввести имя и в дальнейшем его имя и результаты будет отображаться в разделе Результаты (Рисунок 11).
Рисунок 11 - конец игры
|