МИНИСТЕРСТВО ОБРАЗОВАНИЯ И НАУКИ
РОССИЙСКОЙ ФЕДЕРАЦИИ
ФЕДЕРАЛЬНОЕ АГЕНСТВО ПО ОБРАЗОВАНИЮ
КУРГАНСКИЙ ГОСУДАРСТВЕННЫЙ УНИВЕРСИТЕТ
Кафедра автоматизации производственных процессов
Курсовая работа
Расчетно-пояснительная записка.
Дисциплина: Программирование и основы алгоритмизации
«Разработка игры «Крестики-нолики»
Студент: Иванов П. С.
Группа: Т-2144
Руководитель: Скобелев И. В.
Комиссия__________________
Оценка____________________
Дата защиты_______________
Курган, 2006
Введение
Стремительное развитие компьютерной техники в последние годы, появление мощнейших графических ускорителей и центральных процессоров способствовало не менее бурному развитию индустрии компьютерных игр. Выдающиеся разработки этой отрасли – это сложнейшие программы, как правило, с очень высокими требованиями к аппаратной части компьютера. Однако для возможности отдохнуть в перерыве от выполнения какой-либо работы оператору компьютера не всегда требуется новейшая компьютерная игра, а зачастую использовать её не позволяет маломощное оборудование офисного компьютера. Именно этой цели – отдыху от монотонной работы служит разработанная в рамках данного курсового проекта программа.
1. Техническое задание
Игровое поле представлено 25 клетками, как показано на рис.1.
Рис. 1. Игровое поле после запуска игры
Игра рассчитана на 2-х игроков, которые по очереди наводят указатель мыши на соответствующую клетку игрового поля и щелчком левой кнопки мыши ставят в ней крестик или нолик. Первый ход совершает пользователь, играющий крестиками. Победа присуждается игроку, который выстроит в линию последовательность четырех значков Х или О - по горизонтали, вертикали или диагонали, о чем выводится соответствующее сообщение. Также имеется возможность сохранять и загружать начатые игры (файлы сохранений имеют свой значок и расширение *.xvo). Начало новой игры - команда меню File->New (или значок
, сохранение игры - File -> SaveAs… или File -> Save (или значок , открытие сохраненной игры - File -> Open…(или значок ), распечатка начатой игры File -> Print … (или значок ).2. Блок-схема алгоритма
3. Описание работы программного продукта
В данном пункте следует привести описание работы программы с приведением необходимого кода, рассказать об основных и вспомогательных функциях, о назначении массивов и методов, структуре алгоритма программы.
Структура программы строится на пяти классах, каждый из которых создан на основе своего базового класса, взятого из MFC, это классы:
· CXvsOv1App относится к работе самой программы;
· CXvsOv1Doc занимается обработкой рабочих документов;
· CXvsOv1View осуществляет отображение документов в рабочем окне;
· CMainFrame обслуживает работу базового окна программы;
· CAboutDlg обеспечивает работу диалогового окна About (О программе).
В программе данные хранятся в объекте document, а за их отображение отвечает объект view. Фактическим же местом вывода отображаемых данных является окно просмотра. Для SDI-программ данное окно перекрывает видимую клиентскую часть базового окна, которое появляется после компановки подготовленной в AppWizard программы. То, что выглядит как клиентская часть окна - светлая область, обрамленная сверху панелью инструментов, а снизу строкой состояния, - фактически является окном просмотра.
Используемые в программе данные хранится в виде массива полей длиной 1 байт, каждый из которых описывает текущее состояние отдельной клетки игрового поля; этот массив представляет собой элемент данных (data member) класса document. В любой момент класс view может запросить у класса document сведения по каждой клетке и отобразить их на экране. Кроме того, он добавляет в класс document сведения о крестиках и ноликах, когда пользователь щелкает по пустой клетке.
Клетки, образующие игровое поле, задаются матрицей CRect-элементов размерностью 5х5.
Блок инициализации переменной m_rect выглядит так:
CXvsOv1View::CXvsOv1View()
{
for (int i=0; i<5; i++) {
for (int j=0; j<5; j++) {
int x = (i * 70) + 10;
int y = - (j * 70) - 10;
m_rect[i][j].SetRect (x, y, x + 60, y - 60);
m_rect[i][j].NormalizeRect();
}
}}
Для отображения игры на экране используется система координат с единицей измерения, равной 0,01 дюйм. Точка (0,0) - начало координат - находится в верхнем левом углу окна; ось X направлена вправо, ось Y - вверх. Именно по этой причине Y-координаты клеток, назначаемые конструктором, имеют отрицательные значения, а не положительные. Если бы были указаны положительные значения Y, клетки оказались бы за пределами видимой части окна.
Прорисовка игрового поля осуществляется в методе OnDraw. Когда Windows-программа производит вывод на экран, принтер или любое другое устройство вывода, она это делает с использованием так называемого контекста устройства (device context - DC) - некоторой структуры данных, содержащей важные сведения о характеристиках конкретного выводного устройства и о параметрах, применяемых для вывода в данной программе. Поскольку спецификация Graphics Device Interface (интерфейс графических устройств - GDI) системы Windows позволяет получить аппаратно-независимую модель вывода, одна и та же функция будет работать с любым выводным устройством, для которого имеется соответствующий Windows-драйвер.
Вызов функции CDC::SetMapMode присваивает схеме соответствия для контекста устройства значение MM_LOENGLISH, предписывающее, что единицей измерения служит 0,01 дюйм (имеется в виду логический дюйм). Размер логического дюйма определяется некоторым принятым количеством пикселов, необходимым дл отображения реального дюйма на конкретном выводном устройстве. Например, при выводе на принтер один логический дюйм равняется одному физическому (реальному). При выводе на экран размер логического дюйма, как правило, колеблется от 1 до 1,5 физических.
Вложенный цикл for сначала перерисовывает квадраты, а затем, если от функций CXvsOv1Doc::GetSquare получено ненулевое значение, обращается к функции DrawX или DrawO (о функциях класса Doc и функциях DrawX или DrawO будет сказано позднее). Итак, метод OnDraw выглядит следующим образом (функция GetSquare, речь о которой пойдет ниже, осуществляет здесь повторную прорисовку окна после сворачивания):
void CXvsOv1View::OnDraw(CDC* pDC)
{
CXvsOv1Doc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
//
// Задать режим отображения MM_LOENGLISH,
// в котором за единицу измерения толщины принимается 0,01 дюйма:
//
pDC->SetMapMode (MM_LOENGLISH);
//
// Прорисовать игровое поле:
//
for (int i=0; i<5; i++){
for (int j=0; j<5; j++){
//цикл сначала перерисовывает квадраты, а затем, если от функций
//CXvsOv1Doc::GetSquare получено ненулевое значение, обращается к функции DrawX или DrawO
pDC->Rectangle (m_rect [i][j]);
BYTE bVal = pDoc->GetSquare (i,j);
if (bVal == 1) // Проставить Х
DrawX (pDC, &m_rect[i][j]);
else if (bVal == 2) // Проставить О
Draw0 (pDC, &m_rect[i][j]);
}
}
}
Далее следует рассказать о блоке, отвечающем за рисование крестиков и ноликов после щелчков мыши на клетках поля.
Kогда игрок щелкает левой клавишей и указатель мыши находится в пределах клиентской области окна, оно получает сообщение WM_LBUTTONDOWN. Для отслеживания подобных событий используется принадлежащая классу view функция OnLButtonDown. В начале модуля XvsOv1View находится карта сообщений - особая таблица, в которой устанавливаются соответствия между сообщениями и их обработчиками); с ее помощью будет обеспечиваться вызов функции OnLButtonDown при приеме View-модулем сообщения WM_LBUTTONDOWN. В составе функции OnLButtonDown также присутствует блок преобразования координат поля в размерность MM_LOENGLISH:
CClientDC dc (this);dc.SetMapMode (MM_LOENGLISH);dc.DPtoLP (&point);
Итак, функция OnLButtonDown при щелчке на клетке игрового поля обращается к функции GetSquare класса document, чтобы выяснить, оставлен ли в ней значок Х или О. Если GetSquare передает в качестве результата 0, значит клетка пуста, и OnLButtonDown вызывает функцию IsItXsTurn, чтобы получить информацию о том, какой значок нужно вставить - Х или О. Далее с помощью функций AddX или AddO класса document в клетку заносится крестик или нолик. Затем выполняется функция DrawX или DrawO класса view. В конце выполняется функция VinControl(). (Обо всех этих функциях будет сказано ниже). Функция OnLButtonDown выглядит следующим образом:
void CXvsOv1View::OnLButtonDown(UINT nFlags, CPoint point)
{
//
// Получаем указатель на класс document:
CXvsOv1Doc* pDoc = GetDocument ();
//
//Берется контекст устройства для клиентской области окна, в качестве схемы
// соответствия для контекста задается MM_LOENGLISH
CClientDC dc (this);
dc.SetMapMode (MM_LOENGLISH); //Конвертация CPoint-компонентов в MM_LOENGLISH
dc.DPtoLP (&point);
//
// Проверяем попадание указателя мыши
// на клетку игрового поля.
// Если да, рисуем Х или О.
//
BOOL bQuit = FALSE;
for (int i=0; i<5 && !bQuit; i++) {
for (int j=0; j<5 && !bQuit; j++) {
if (m_rect[i][j].PtInRect (point)) {
//Если после преобразования функция PtInRect передает ненулевое RETURN-значение,
//следовательно курсор находится внутри клетки. В этом случае переменные i и j
//содержит индексы, указывающие положение данной клетки.
//Если координаты, переданные аргументом CPoint, лежат за пределами всех
//имеющихся клеток, то вложенный цикл for заканчтвается
if (pDoc->GetSquare (i, j) == 0) {
if (pDoc->IsItXsTurn ()) {
pDoc->AddX (i, j);
DrawX (&dc, &m_rect[i][j]);
} else {
pDoc->AddO (i, j);
Draw0 (&dc, &m_rect[i][j]);