Разработка игровой программы 'Сапер'

  • Вид работы:
    Курсовая работа (т)
  • Предмет:
    Информационное обеспечение, программирование
  • Язык:
    Русский
    ,
    Формат файла:
    MS Word
    668,82 Кб
  • Опубликовано:
    2012-09-23
Вы можете узнать стоимость помощи в написании студенческой работы.
Помощь в написании работы, которую точно примут!

Разработка игровой программы 'Сапер'

Введение

Целью данной курсовой работы была разработка игровой программы «Сапёр» на языке С (С++) средствами WinAPI. Жанр данной игры - головоломка.

История игры «Сапёр» уходит в далекие 50-е года 20-го столетия. В то время это была, конечно же, не компьютерная игра, т.к. персональные компьютеры появились гораздо позже, а игра в большой картонной коробке.

С эрой появления персональных компьютеров игра «Сапёр» обрела свою еще большую популярность.

С появлением операционной системы Windows «Сапёр» приобрел свою самую большую популярность. Теперь в нее стали играть во всем мире.

Проанализировав различные версии игры «Сапёр», было решено создать аналог версии Minesweeper for Windows, так как она являлась самой популярной и распространённой в мире.

1. Анализ задания и постановка задачи

Теоретические основы игры смотрите в пункте 2.2.

После анализа задания на курсовой проект были поставлены следующие задачи:

необходимость реализовать графический интерфейс;

необходимость подсчета времени, затраченного игроком на решение головоломки, а так же вести учет, непомеченных игроком мин;

возможность сохранения / загрузки игры;

возможность выбора игроком трех уровней сложности, а так же «Особый» уровень, где игрок может сам выбрать параметры игрового поля и количества мин;

необходимость ведения статистики игр;

возможность возврата игроком на три хода назад (особенность данного проекта);

Поддерживаемые операционные системы Windows Seven/Vista/XP.

2. Теоретическая часть

2.1 Основные сведения о WinAPI

WinAPI (Windows Application Programming Interfaces) - это интерфейс для программирования приложений, для операционных систем Windows и Windows NT. Для создания программ, с использованием WinAPI, существует Platform SDK от Microsoft, который содержит документацию, утилиты, набор библиотек, и другие полезные инструменты. Основные инструменты Windows API - это функции и сообщения, для возможности связи между приложениями. Отправка сообщений осуществляется с помощью функций SendMessage и PostMessage. Для приема используются таблицы MESSAGE_MAP.

Через Windows API доступно очень много технологий, таких как: Bluetooth, COM, HTTP, ICS и ICF, Microsoft.NET Passport, Microsoft Agent, OLE DB, OpenGL, Windows Installer, Windows System Information, Windows User Interface, Telephony Application Programming Interface и много других.

Существует 4 версии WinAPI:

Win16 - первая версия Windows API для 16-разрядных версий Windows. Изначально назывался просто Windows API, затем стал называться Win16 для отличия от Win32.

Win32s - подмножество Win32, устанавливаемое на семейство 16-разрядных систем Windows 3.x, и реализующее ограниченный набор функций Win32 API для этих систем.

Win32 - 32-разрядный API для современных версий Windows. Самая популярная ныне версия. Базовые функции этого API реализованы в динамически подключаемых библиотеках kernel32.dll и advapi32.dll; базовые модули графического интерфейса пользователя - в user32.dll и gdi32.dll. Win32 появился вместе с Windows NT и затем был перенесён в несколько ограниченном виде в системы серии Windows 9x. В современных версиях Windows, происходящих от Windows NT, работу Win32 GUI обеспечивают два модуля: csrss.exe (процесс исполнения клиент-сервер), работающий в пользовательском режиме, и win32k.sys в режиме ядра. Работу же системных Win32 API обеспечивает ядро - ntoskrnl.exe.

Win64 - 64-разрядная версия Win32, содержащая дополнительные функции для использования на 64-разрядных компьютерах. Win64 API можно найти только в 64-разрядных версиях Windows XP, Windows Server 2003, Windows Vista, Windows Server 2008, Windows Server 2008 R2 и Windows 7.

2.2 Теоретические основы игры

Игра представляет собой плоское игровое поле, разделённое на смежные ячейки (квадраты), некоторые из которых «заминированы»; количество «заминированных» ячеек известно и равно количеству непомеченных «мин». Размерность игрового поля обычно может изменяться от 9 до 24 ячеек в ширину и от 9 до 30 в длину (в зависимости от вида и типа аналога игры и, конечно, выбранного уровня сложности).

Рис. 1 - Игровое поле игры «Сапёр» при запуске игры на уровне сложности «Новичок»

В аналогичной игре «Сапер» (Microsoft Corporation) есть три уровня сложности: «Легко» («Новичок»), «Средне» («Любитель») и «Трудно» («Мастер»). С повышением уровня сложности увеличивается количество клеток-ячеек игрового поля и, соответственно, количество «мин», скрывающихся на нём. Также для данной игры предусмотрен ещё один уровень сложности - «Особый», дающий возможность игроку самому выбрать размерность игрового поля и количество «мин» для него. Количество «мин» при уровне сложности «Особый» может быть выбрано в некотором ограниченном диапазоне в силу ограниченности размеров игрового поля.

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

Главная цель игры - открыть все «не заминированные» клетки, ни разу не попав на «мину». Используя числа в открытых клетках, игрок пытается рассчитать расположение мин, однако иногда даже в середине и в конце игры некоторые ячейки всё же приходится открывать наугад. Ячейки, над которыми игрок на данный момент сомневается, может пометить, чтобы случайно не открыть их, ячейка-клетка будет помечена вопросительным знаком «?». Открыв клетку с «миной», игрок проигрывает, игра заканчивается, и, в зависимости от выбора игрока, можно начать игру заново с другой расстановкой «мин» или покинуть игру.

3. Проектирование программы

Для хранения информации об игровом поле решено использовать 2 массива типа BYTE.

В первом массиве решено хранить информацию о текущем состоянии клетки-ячейки. Так как она может находиться в одном из четырех состояний: клетка-ячейка не открыта, клетка-ячейка открыта, клетка-ячейка помечена «флагом» и клетка-ячейка помечена вопросом, и такая клетка будет иметь значение 0, 1, 2 или 3 соответственно в зависимости от состояния данной клетки.

Во втором массиве будет храниться информация о количестве «мин» в смежных ячейках, т.е. числа от 0 и до 8 (максимальное количество смежных ячеек). Числом 9 будет помечена клетка, в которой будет находиться «мина».

Для хранения размерности поля и количества бомб также решено использовать глобальные переменные типа BYTE.

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

Взаимодействие пользователя с игрой в основном предполагается посредством указателя типа мышь. Поэтому вполне логично использование в качестве клетки-ячейки объект «Кнопка» с размещенным на нем изображением определенного числа или «мины» при открытии этой клетки.

Расстановка «мин» происходит случайным образом в самом начале игры при помощи функции srand(). На «Легком» уровне сложности количество «мин» равняется 10, при «Среднем» - 40, «Сложном» - 99.

Как упоминалось ранее ширина и высота, а также количество «мин» при уровне сложности «Особый» выбираются самим игроком. Минимальное количество «мин» решено принять за 10, максимальное количестве «мин», для разной размерности игрового поля, решено рассчитывать по формуле: H*W - (H+W), где H примем за высоту игрового поля, W - за ширина для данного поля в клетках.

Сохранение игры будет производится в файл «save.sap» и будет подразумевать сохранение таких параметров как ширина, высота поля, состояние всех клеток-ячеек, расстановка «мин», значение таймера. Запрос на сохранение будет производиться при закрытии программы и только в том случае, если сделан хотя бы один новый шаг (открытие ячейки) и текущая игра не была пройдена. Запрос на загрузку будет производиться при открытии программы, если до этого было произведено сохранение игры.

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

Для обеспечения работы с игровым приложением будут созданы следующие файлы:

global.h - файл в котором содержаться основные глобальные переменные и структуры используемые в программе.

functions.h - файл в котором содержаться основные функции используемые в программе такие как:

создание игрового поля (create_field())

удаление игрового поля ()

новая игра (new_game())

функция нажатия кнопки (OpenButtField())

функция открытия всех бомб (OpenALLBomb())

функция сохранение игры (SaveGame())

функция загрузка игры (LoadGame())

функция сохранения статистики (SaveStat())

функция загрузки статистики (LoadStat())

функция обнуления статистики (NullStat())

функция изменения статистики при выигрыше (StatWin())

функция изменения статистики при проигрыше (StatLoss())

функция открытия всех пустых ячеек (рекурсия) (OpenNULLButt())

функция расстановки чисел идентификаторов количества бомб на ячейках (setField())

функция добавления в список текущего хода (AddList())

функция удаления из списка хода, если размер списка превышен (DelList())

функция извлечения хода из списка (Repak())

resource.h - файл в котором хранятся ресурсы программы

stdafx.h - файл хранящий в себе все используемые программой библиотеки

saper.h - файл, содержащий описание всех обработчиков сообщений используемых в программе (обработчик сообщений загрузки / сохранения, статистики, основного окна).


4. Реализация программы

4.1 Реализация логической структуры, используемой в игре

Для объявления глобальных переменных и структуры был создан файл global.h. Содержимое этого файла:

typedef struct {all;win;winCurr;lossCurr;winMax;lossMax;BestTime[10];

структура, используемая для хранения статистики; поля данной структуры:

all - количество сыгранных игр;

win - количество побед;

winCurr - текущее количество выигранных подряд игр;

lossCurr - текущее количество проигранных подряд игр;

winMax - максимальное количество выигранных подряд игр;

lossMax - максимальное количество проигранных подряд игр;

BestTime - массив с лучшими результатами;

typedef struct {*Head;

} LIST;

LIST *list;

Структура для двухсвязного списка, используемого для хранения состояний игрового поля после каждого, сделанного игроком хода.

typedef struct _Element {_Element *Next,*Prev;** Array1;**Array2;**Array3;fieldHeight;fieldWidth;

BYTE bombCount;countNotBomb;bombCountForFlag;

} Element;

Структура, используемая для хранения состояния игрового поля и количества непомеченных «мин».

Глобальные переменные:

HWND hWnd - дескриптор основного окна;

BYTE field [MAX_HEIGHT] [MAX_WIDTH] - матрица, содержащая информацию о клетках-ячейках игрового поля (числа от 0 до 9);

BYTE fieldMark [MAX_HEIGHT] [MAX_WIDTH] - матрица, содержащая информацию о состоянии ячеек игрового поля, т.е. числа 0, 1, 2 или 3 (не открыто, открыто, помечено флагом, помечено вопросом);

HWND butt [MAX_HEIGHT] [MAX_WIDTH] - матрица дескрипторов кнопок, являющихся ячейками игрового поля;

HWND hGrBox - дескриптор объекта GroupBox;

bool flagEOG - флаг окончания игры;

BYTE fieldHeight, fieldWidth - высота и ширина игрового поля соответственно;

BYTE bombCount - количество «мин»;

BYTE countNotBomb - количество ячеек, свободных от «мин»

BYTE timeCount - количество секунд;

BYTE bombCountForFlag - количество «мин» не помеченных флагом;

stat easy, medium, hard - структуры, хранящие статистическую информацию для каждого из уровней сложности;

static int TimerFlag=0; - флаг таймера;

Прототипы функций:CALLBACK  WndProcButt (HWND, UINT, WPARAM, LPARAM) - оконная процедура для кнопки;CALLBACK  WndProcGB (HWND, UINT, WPARAM, LPARAM) - оконная процедура для GroupBox;

В файле functions.h находятся основной функционал программы.

Далее будут описаны прототипы функций, реализующие логическую часть игры:create_field() - создание игрового поля (предварительное матрицы field и fieldMark обнуляются, и производится расстановка «мин»);

void setField() - расстановка чисел идентификаторов количества «мин»; функция будет использована только после того как будут расстановлены «мины»;

bool fieldIsClose() - проверка на «открытость» поля. Данная функция используется при сохранении игры, т.е. она проверяет, была ли открыта хотя бы одна ячейка;

void SaveGame() - сохранение игры в файл «save.sap». Сохранение всех свойств и состояний игрового поля и запись их в файл;

void LoadGame() - загрузка игры из файла «save.sap»;

void NullStat() - обнуление статистики. Вызывается в том случае, обнуление статистики производится непосредственно самим пользователем или в том случае, когда файл со статистикой повреждён или отсутствует;

void SaveStat() - сохранение статистики в файл «stat.sap»;

void LoadStat() - загрузка статистики из файла «stat.sap»;

void StatWin() - запись в статистику при выигрыше;

void StatLoss() запись в статистику при проигрыше;

LIST * AddList (LIST *list, BYTE **, BYTE **, HWND **, BYTE, BYTE, BYTE, BYTE, BYTE) - функция добавления состояния поля, размеров поля и количества непомеченных «мин» в ячейку двухсвязного списка;* DelList (LIST *list) - функция удаления ранее записанного состояния игрового поля, в случае если превышен размер списка, счетчик больше 3;

LIST *Repak (LIST *list, BYTE ***Array1, BYTE ***Array2, HWND ***Array3, BYTE *fieldHeight, BYTE *fieldWidth, BYTE *bombCount, BYTE *countNotBomb, BYTE *bombCountForFlag) - функция извлекает последний, записанный в список ход, срабатывает после нажатия клавиши Backspace.

4.2 Реализация графической части приложения

В приложении используются, кроме кнопок-ячеек, следующие компоненты:

таймер с интервалом в 1 секунду - для подсчета продолжительности игры;

счётчик не помеченых «мин».

стандартное меню - для начала новой игры, настройки игры, просмотра статистики, выхода;

Размер основного окна строго зависит от количества клеток-ячеек, поэтому во время игры изменить его размеры окна невозможно. В нижней области окна располагается находится таймер и счётчик не помеченых «мин». Для избежания ежесекундной перерисовки экрана из-за перерисовки чисел таймера, решено поместить счетчик «мин» и таймер в отдельный обьект (GroupBox), в котором перерисовка будет выполняться отдельно от всей игровой области.

Для отображения статистики игры и для настройки сложности, а также для запроса на сохранения и загрузки игры были созданы ресурсы типа Dialog.

В любой момент игры игрок может отменить сделанный им ход, это возможно в том случае если до этого было изменено состояние поля (открыта хотя бы одна ячейка), ход будет отменен при нажатии клавиши Backspace. Если же до нажатия клавиши Backspace не было произведено ни единого хода то игровое окно просто перерисуется, не меняя своего состояния. В игре можно будет вернуться только на три хода. При нажатии клавиши Backspace (в том случае если список состояния ходов не будет пуст) запустится функция DestroyButtField(), из последней записанной ячейки списка будут извлечены все данные о состоянии игрового поля, его размеры и количество непомеченных «мин». После извлеченные данные присвоятся глобальным переменным отвечающим за параметры игрового поля. По новым значением будет перестроено игровое поле.

Далее будут приведены прототипы используемых функций из модуля functions.h и их описания:

void DestroyButtField() - функция удаления всего поля-кнопок

void new_game() - новая игра. Предусматривает установку флага таймера в значение 0, флага завершения игры в значение false, вызов функции DestroyButtField(), удаляющую все ячейки-кнопки. После создаётся область GroupBox и для его устанавливается адрес оконной процедуры. Далее идет создание кнопок, являющихся игровыми клетками-ячейками, для них также устанавливается адрес оконной процедуры. Затем вызывается функция create_field(), описанная выше, отвечающая за информационную часть игрового процесса. Значению таймера при этом присваивается 0, до совершения игроком первого хода.

void OpenNULLButt (int I, int J) - рекурсивное открытие области ячеек, в смежных с которыми «мин». Остановка рекурсии происходит в том случае, когда происходит открытие кнопки с некоторым числом от 1 до 8. I, J - координаты кнопки в матрице.OpenALLBomb() - открытие всех «мин». Вызывается автоматически в случае проигрыша.OpenButtField (int wmID) - открытие ячейки, вызывается при нажатии на кнопку. При этом если это первое нажатие мыши то автоматически запускается таймер. В случае открытия ячейки с числом, символизирующим некоторое количество «мин» в смежных с данной клеткой ячейках, на эту кнопку помещается картинка с соответствующим числом. Если открывается ячейка с числом 0, то вызывается функция openNULLButt (int I, int J), описанная ранее. При этом состояние поля, а также количество непомеченных мин заносится в ячейку списка. Когда открывается ячейка с «миной», происходит открытие всех «мин» с помощью функции OpenALLBomb() и выводится сообщение о проигрыше.

Программирование с использованием WinAPI - событийное программирование. Процедура обработки сообщений, посылаемых главному окну программы извне и от дочерних окон осуществляет процедура WndProc, в которой и реализован весь интерфейс программы и организовано взаимодействие пользователя с программой.

Оконные процедуры, описаные в модуле saper:

LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) - окнная процедура главного окна.

INT_PTR CALLBACK Difficulty (HWND, UINT, WPARAM, LPARAM) - оконная процедура для окна-диалога «Сложность».

INT_PTR CALLBACK SaveGameDlg (HWND, UINT, WPARAM, LPARAM) - оконная процедура для окна-диалога «Сохранение игры».

INT_PTR CALLBACK LoadGameDlg (HWND, UINT, WPARAM, LPARAM) - оконная процедура для окна-диалога «Загрузка игры».

INT_PTR CALLBACK Stat (HWND, UINT, WPARAM, LPARAM) - оконная процедура для окна-диалога «Статистика».

5. Методика и результаты тестирования

5.1 Методика тестирования

Тестирование проходило по следующим позициям:

проверка корректности записи / чтения файла игры;

проверка на корректность поведения интерфейса программы;

проверка на корректность работы логической части игры.

5.2 Проверка корректности записи / чтения файла игры


5.3 Проверка на корректность поведения интерфейса программы

Проблема мерцания игрового поля за счет ежесекундной перерисовки таймера была решена путем созднания обьекта GroupBox и поместить в него таймер и счетчик непомеченных «мин», в котором перерисовка проходила отдельно.

После выполнения вышеуказанных действий программа стала работать стабильно, мерцаний больше не появлялось.

5.4 Проверка на корректность работы логической части игры

Корректность работы логической структуры игры была неоднократно проверена при отладке и тестировании графической версии игры. Все ходы фиксировались верно, ложных срабатываний выявлено не было. Результаты тестирования представлены на скриншотах ниже.

Рис. 5.1 - Запуск приложения

Рис. 5.2 - Игровой процесс


Рис. 5.3 - Просмотр статистики

Рис. 5.4 - Выбор уровня сложности

Рис. 5.5 - Вывод сообщения о проигрыше

Рис. 5.6 - Сообщение о выйгранной игре

Рис. 5.7 - Запрос на сохранение текущей игры

Рис. 5.8 - Запрос на загрузку ранее сохранённой игры

Проверка функции отмены хода

Рис. 5.9.1 - Игровое поле до отмены хода

Рис. 5.9.2 - Игровое поле после отмены 2-х ходов

Заключение

игра сапер программа графический

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

В ходе выполнения курсовой работы были преобретены навыки разработки приложений на WinAPI. Была изучена схема связи между приложениями через сообщения. Также был изучен принцип работы основных функций.

Все поставленные ранее задачи по курсовому проекту были успешно выполнены.

Написаная программа соответстввует заявленным требованиям задания на курсовую работу и успешно прошла тестирование.

Список литературы

1) Win32 API. Эффективная разработка приложений, Юрий Щупак, «Питер», 2007

2)      Технология программирования на C++. Win32 API-приложения, Н.А. Литвиненко, «БХВ-Петербург», 2010

3) К.Г. Финагенов. Win32. Основы программирования.

Похожие работы на - Разработка игровой программы 'Сапер'

 

Не нашли материал для своей работы?
Поможем написать уникальную работу
Без плагиата!