Игровое поле состоит из клеток, в каждой из которых может быть мина.
Задача игрока — найти все мины и пометить их флажками. Используя кнопки мыши, игрок может открыть клетку или поставить в нее флажок, указав тем самым, что в клетке находится мина. Клетка открывается щелчком левой кнопки мыши, флажок ставится щелчком правой.
Если в клетке, которую открыл игрок, есть мина, то происходит взрыв (сапер ошибся, а он, как известно, ошибается только один раз) и игра заканчивается.
Если в клетке мины нет, то в этой клетке появляется число, соответствующее количеству мин, находящихся в соседних клетках. Анализируя информацию о количестве мин в клетках, соседних с уже открытыми, игрок может обнаружить и пометить флажками все мины. Ограничений на количество клеток, помеченных флажками, нет. Однако для завершения игры (выигрыша) флажки должны быть установлены только в тех клетках, в которых есть мины.
Ошибочно установленный флажок можно убрать, щелкнув правой кнопкой мыши в клетке, в которой он находится.
Представление данных
В программе игровое поле представлено массивом N+2 на М+2, где NxM размер игрового поля. Элементы массива с номерами строк от 1 до N и номерами столбцов от 1 до М соответствуют клеткам игрового поля (рис. 15.9), первые и последние столбцы и строки соответствуют границе игрового поля.
Рис. 15.9. Клетке игрового поля соответствует элемент массива
В начале игры каждый элемент массива, соответствующий клеткам игрового поля, может содержать число от 0 до 9. Ноль соответствует пустой клетке, рядом с которой нет мин. Клеткам, в которых нет мин, но рядом с которыми мины есть, соответствуют числа от 1 до 8. Элементы массива, соответствующие клеткам, в которых находятся мины, имеют значение 9.
Элементы массива, соответствующие границе поля, содержат -3. В качестве примера на рис. 15.10 изображен массив, соответствующий состоянию поля в начале игры.
Рис. 15.10. Массив в начале игры
В процессе игры состояние игрового поля меняется (игрок открывает клетки и ставит флажки) и, соответственно, меняются значения элементов массива. Если игрок поставил в клетку флажок, то значение соответствующего элемента массива увеличивается на 100. Например, если флажок поставлен правильно в клетку, в которой есть мина, то значение соответствующего элемента массива станет 109. Если флажок поставлен ошибочно, например, в пустую клетку, элемент массива будет содержать число 100. Если игрок открыл клетку, то значение элемента массива увеличивается на 200. Такой способ кодирования позволяет сохранить информацию о исходном состоянии клетки.
Форма приложения
Главная (стартовая) форма игры Сапер 2002 приведена на рис:
Следует обратить внимание, что размер формы не соответствует размеру игрового поля. Нужный размер формы будет установлен во время работы программы. Делает это процедура обработки события OnFormActivate, которая на основе информации о размере игрового поля (количестве клеток по вертикали и горизонтали) и клеток устанавливает значение свойств ciientHeight и ciientwidth, определяющих размер клиентской области главного окна программы.
Основное окно программы содержит компонент MainMenu1, который представляет собой главное меню программы. Значок компонента MainMenu находится на вкладке Standard:
Значок компонента MainMenu можно поместить в любое место формы, так как во время работы программы он не виден. Пункты меню появляются в верхней части формы в результате настройки меню. Для настройки меню используется редактор меню, который запускается двойным щелчком левой кнопкой мыши на значке компонента или выбором из контекстного меню компонента команды Menu Designer.
В начале работы над новым меню, сразу после добавления компонента к форме, в окне редактора находится один-единственный прямоугольник — заготовка пункта меню. Чтобы превратить эту заготовку в меню, нужно в окне Object Inspector в поле Caption ввести название меню.
Если перед какой-либо буквой в названии меню ввести знак s, то во время работы программы можно будет активизировать этот пункт меню путем нажатия комбинации клавиши <Alt> и клавиши, соответствующей символу, перед которым стоит знак &. В названии меню эта буква будет подчеркнута.
Чтобы добавить в главное меню элемент, необходимо в окне редактора меню выбрать последний (пустой) элемент меню и ввести название нового пункта. Чтобы добавить в меню команду, необходимо выбрать пункт меню, в который нужно добавить команду, переместить указатель активного элемента меню в конец списка команд меню и ввести название команды.
На рис. 15.13 приведено окно редактора меню, в котором находится меню программы Сапер 2002. После того как будет сформирована структура меню, нужно, используя окно Object Inspector, выполнить настройку элементов меню (выбрать настраиваемый пункт меню можно в окне формы приложения или из списка объектов в верхней части окна Object Inspector). Каждый элемент меню (пункты и команды) — это объект типа TMenuitem. Свойства объектов TMenuitem (табл. 15.7) определяют вид меню во время работы программы.
Рис. 15.13. Структура меню программы Сапер 2002
Таблица 15.7. Свойства объекта TMenuItem
Свойство |
Определяет |
Name |
Имя элемента меню. Используется для доступа к свойствам |
Caption |
Название меню или команды |
Bitmap |
Значок, который отображается слева от названия элемента меню |
Enabled |
Признак доступности элемента меню. Если значение свойства равно False,то элемент меню недоступен, при этом название меню отображается серым цветом |
При выборе во время работы программы элемента меню происходит событие click. Чтобы создать процедуру обработки этого события, нужно в окне формы выбрать пункт меню и щелкнуть левой кнопкой мыши — Delphi создаст шаблон процедуры обработки этого события. В качестве примера ниже приведена процедура обработки события, которое возникает в результате выбора из меню ? команды Справка, нз — это имя элемента меню, соответствующего этой команде.
В начале игры нужно расставить мины, затем для каждой клетки поля подсчитать, сколько мин находится в соседних клетках. Процедура HewGame (ее текст приведен в листинге 15.3) решает эту задачу.
Листинг 15.3. Процедура NewGame
После того как процедура NewGame расставит мины, процедура ShowPole (ее текст приведен в листинге 15.4) выводит изображение игрового поля.
Листинг 15.4. Процедура ShowPole
Процедура ShowPole выводит изображение поля последовательно, клетка за клеткой. Вывод изображения отдельной клетки выполняет процедура Kletka, ее текст приведен в листинге 15.5. Процедура Kletka используется для вывода изображения поля в начале игры, во время игры и в ее конце. В начале игры (значение параметра status = 0) процедура выводит только контур клетки, во время игры — количество мин в соседних клетках или флажок, а в конце отображает исходное состояние клетки и действия пользователя. Информацию о фазе игры процедура Kletka получает через параметр status.
Листинг 15.5. Процедура Kletka
Во время игры программа воспринимает нажатия кнопок мыши и, в соответствии с правилами игры, открывает клетки или ставит в клетки флажки. Основную работу выполняет процедура обработки события onmousedown (ее текст приведен в листинге 15.6). Сначала процедура преобразует координаты точки, в которой игрок нажал кнопку мыши, в координаты клетки игрового поля. Затем делает необходимые изменения в массиве Pole и, если нажата правая кнопка, рисует в клетке флажок. Если нажата левая кнопка в клетке, в которой нет мины, то эта клетка открывается, на экран выводится ее содержимое. Если нажата левая кнопка в клетке, в которой есть мина, то вызывается процедура ShowPole, которая показывает все мины, в том числе и те, которые игрок не успел найти.
Листинг 15.6. Обработка события onmousedown на поверхности игрового поля
При выборе из меню ? команды Справка появляется справочная информация — правила игры (рис. 15.14).
Рис. 15.14. Окно справочной информации
Процесс создания СНМ-файла подробно описан в гл. 14. Процедура, обеспечивающая вывод справочной информации, приведена в листинге 15.7.
Листинг 15.7. Вывод справочной информации
Рис. 15.15. Окно О программе
Чтобы программа во время своей работы могла вывести на экран окно, отличное от главного (стартового), нужно создать это окно. Делается это выбором из меню File команды New form. В результате выполнения команды New form в проект добавляется новая форма и соответствующий ей модуль. Вид формы AboutForm после добавления необходимых компонентовприведен на рис. 15.16, значения ее свойств — в табл. 15.8.
Таблица 15.8. Значения свойств формы О программе
Свойство |
Определяет |
Name |
AboutForm |
Caption |
О программе |
BorderStyle |
BsSingle |
BorderIcons.biSystemMenu |
False |
BorderIcons.biMinimize |
False |
BorderIcons.biMaximize | False |
Вывод окна О программе выполняет процедура обработки события click, которое происходит в результате выбора из меню ? команды О программе. Непосредственно вывод окна выполняет метод ShowModal, который выводит окно как модальный диалог.
Листинг 15.8. Вывод окна О программе