Сапер

13



1



МИНИСТЕРСТВО ОБРАЗОВАНИЯ И НАУКИ УКРАИНЫ

ХАРЬКОВСКИЙ НАЦИОНАЛЬНЫЙ УНИВЕРСИТЕТ

РАДИОЭЛЕКТРОНИКИ



Кафедра искусственного интеллекта



Пояснительная записка



К курсовой работе по дисциплине: 



"Объектно-ориентированное программирование"



Тема: 

"Сапер"





Выполнил: 

ст. гр. 

Проверил: 

Комиссия: 

Работа защищена с оценкой: 















Харьков 2007


РЕФЕРАТ



Пояснительная записка к курсовой работе содержит: 46 стр., 5 рисунков

Предмет исследования – современные методы разработки программ таких, как объектно-ориентированное программирование и визуальное проектирование, а также структурное и модульное программирование. 

Цель курсовой работы – систематизация, углубление и активное применение знаний по системному программированию, закрепление знаний, полученных в лекционном курсе, а также на практических и лабораторных занятиях. 

Метод исследования – изучение литературы, составление и отладка программ на компьютере. 

Данная программа используется для интересного проведения времени за игрой, которая требует развитого логического мышления. Разработан проект "Сапер" соответствующий условию задания и имеющий удобный интерфейс. 

Программа разработана в среде Visual studio 2005. 



КЛЮЧЕВЫЕ СЛОВА: VISUAL, ФУНКЦИЯ, ПРОЕКТ, ПРОГРАММА, САПЕР, БОМБА, ЯЧЕЙКА


СОДЕРЖАНИЕ



	ВВЕДЕНИЕ	4

	1. АНАЛИЗ ПРЕДМЕТНОЙ ОБЛАСТИ	6

	2. ПОСТАНОВКА ЗАДАЧИ	6

	3 ПРОЕКТИРОВАНИЕ СИСТЕМЫ	9

	4. ПРОГРАММНАЯ РЕАЛИЗАЦИЯ	11

	ВЫВОДЫ	11

	ПЕРЕЧЕНЬ ССЫЛОК	12

	ПРИЛОЖЕНИя	13






ВВЕДЕНИЕ



C++ - универсальный язык программирования, задуманный так, чтобы сделать программирование более приятным для серьезного программиста. За исключением второстепенных деталей C++ является надмножеством языка программирования C. Помимо возможностей, которые дает C, C++ предоставляет гибкие и эффективные средства определения новых типов. Используя определения новых типов, точно отвечающих концепциям приложения, программист может разделять разрабатываемую программу на легко поддающиеся контролю части. Такой метод построения программ часто называют абстракцией данных. Информация о типах содержится в некоторых объектах типов, определенных пользователем. Такие объекты просты и надежны в использовании в тех ситуациях, когда их тип нельзя установить на стадии компиляции. Программирование с применением таких объектов часто называют объектно-ориентированным. При правильном использовании этот метод дает более короткие, проще понимаемые и легче контролируемые программы.

Ключевым понятием C++ является класс. Класс - это тип, определяемый пользователем. Классы обеспечивают скрытие данных, гарантированную инициализацию данных, неявное преобразование типов для типов, определенных пользователем, динамическое задание типа, контролируемое пользователем управление памятью и механизмы перегрузки операций. C++ предоставляет гораздо лучшие, чем в C, средства выражения модульности программы и проверки типов. В языке есть также усовершенствования, не связанные непосредственно с классами, включающие в себя символические константы, inline - подстановку функций, параметры функции по умолчанию, перегруженные имена функций, операции управления свободной памятью и ссылочный тип. В C++ сохранены возможности языка C по работе с основными объектами аппаратного обеспечения (биты, байты, слова, адреса и т.п.). Это позволяет весьма эффективно реализовывать типы, определяемые пользователем.

C++ и его стандартные библиотеки спроектированы так, чтобы обеспечивать переносимость. Имеющаяся на текущий момент реализация языка будет идти в большинстве систем, поддерживающих C. Из C++ программ можно использовать C библиотеки, и с C++ можно использовать большую часть инструментальных средств, поддерживающих программирование на C. 






1. АНАЛИЗ ПРЕДМЕТНОЙ ОБЛАСТИ



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

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

Игра считается проигранной, если вы открыли ячейку с бомбой. 

Игра считается выигранной, если на игровом поле все ячейки с бомбами отмечены и все остальные ячейки – открыты. 



2. ПОСТАНОВКА ЗАДАЧИ



Алгоритм программы включает в себя: 

случайную расстановку бомб по полю (функция Rand()) 

int tmp = GetBombsCount(); 

int tmp_cs = 0; 

int tmp_rs = 0; 

while(tmp! = 0) 

{

tmp_cs = rand()% GetCols(); 

tmp_rs = rand()% GetRows(); 

if (field [tmp_cs] [tmp_rs]. GetPointer() == NULL) 

{

tmp--; 

field [tmp_cs] [tmp_rs]. SetPointer(new CMyCellBomb(tmp_cs, tmp_rs, CLOSED)); 

}

else

continue; 

}

подсчет для каждой ячейки количества бомб вокруг нее

int value = 0; 

if (CheckCell(i, j - 1)) 

if (GetCellByIndex(i, j - 1) ! = NULL && GetCellByIndex(i, j - 1) - >isBomb()) 

value++; 

if (CheckCell(i - 1, j - 1)) 

if (GetCellByIndex(i - 1, j - 1) ! = NULL && GetCellByIndex(i - 1, j - 1) - >isBomb()) 

value++; 

if (CheckCell(i - 1, j)) 

if (GetCellByIndex(i - 1, j) ! = NULL && GetCellByIndex(i - 1, j) - >isBomb()) 

value++; 

if (CheckCell(i - 1, j + 1)) 

if (GetCellByIndex(i - 1, j + 1) ! = NULL && GetCellByIndex(i - 1, j + 1) - >isBomb()) 

value++; 

if (CheckCell(i, j + 1)) 

if (GetCellByIndex(i, j + 1) ! = NULL && GetCellByIndex(i, j + 1) - >isBomb()) 

value++; 

if (CheckCell(i + 1, j + 1)) 

if (GetCellByIndex(i + 1, j + 1) ! = NULL && GetCellByIndex(i + 1, j + 1) - >isBomb()) 

value++; 

if (CheckCell(i + 1, j)) 

if (GetCellByIndex(i + 1, j) ! = NULL && GetCellByIndex(i + 1, j) - >isBomb()) 

value++; 

if (CheckCell(i + 1, j - 1)) 

if (GetCellByIndex(i + 1, j - 1) ! = NULL && GetCellByIndex(i + 1, j - 1) - >isBomb()) 

value++; 

return value; 

возможность регулирования размеров поля, количества бомб

метод раскрытия пустых клеток (без бомб и цифр) 

if (! CheckCell(i, j)) 

return; 

if (GetCellByIndex(i, j) == NULL) 

return; 

if (GetCellByIndex(i, j) - >isBomb()) 

return; 

else

if (countItter! = 0 && (GetCellByIndex(i, j) - >GetState() == OPENED ||

GetCellByIndex(i, j) - >GetState() == BLOCK)) 

return; 

GetCellByIndex(i, j) - >SetState(OPENED); 

countItter++; 

// Обходим все соседние ячейки что бы их открыть

if (((CMyCellWob *) GetCellByIndex(i, j)) - >GetValue() == 0) 

{

OpenNullValues(i, j - 1); 

OpenNullValues(i - 1, j - 1); 

OpenNullValues(i - 1, j); 

OpenNullValues(i - 1, j + 1); 

OpenNullValues(i, j + 1); 

OpenNullValues(i + 1, j + 1); 

OpenNullValues(i + 1, j); 

OpenNullValues(i + 1, j - 1); 

}



3 ПРОЕКТИРОВАНИЕ СИСТЕМЫ



CmyCell – базовый абстрактный класс, хранит положение и состояние ячейки, выполняет необходимые ячейке действия, виртуальные функции предопределяются далее в производных классах. 

GetX() – взятие положения по X

GetY() – взятие положения по Y 

GetState() – взятие состояния ячейки

SetX() – установка положения по X

SetY() – установка положения по Y

SetState() – установка состояния ячейки

HitToPoint() – попадание по ячейке

DrawClosedCell() – прорисовка закрытой ячейки

DrawBlockedCell() – прорисовка заблокированной ячейки

Draw() – прорисовка ячеек

Click() – щелчок по ячейке

IsBomb() – проверяет на наличие в ячейке бомбы 

CmyCellBomb – класс, ячейка с бомбой, наследуется от базового класса – ячейки. Переопределяет функции Рисовать, Кликать, проверку на занятость ячейки бомбой. 

CMyCellWOB – класс, ячейка без бомбы, наследуется от ячейки. 

SetValue() – устанавливает количество бомб вокруг ячейки

GetValue() – взятие кол-ва бомб вокруг ячейки

CPMyCell – "умный" указатель на класс ячейки. Включает в себя указательно класс CmyCell. 

CmyField – класс поля, наследуется от класса CPMyCell, генерирует расположение бомб, обрабатывает нажатие события, рисует, осуществляет все действия, что нужны для самой игры. 

GetCols() – взятие количества столбцов

GetRows() – взятие количества строк

GetBombsCount() – взятие количества бомб

GetFindBombsCount() – взятие количества найденных бомб

SetBombsCount() – установка количества бомб

SetFindBombsCount() – определение количества найденных бомб

GetCellByIndex() – нахождение ячейки по индексу

SetCellByIndex() – установка ячейки по индексу

Init() – инициализация итерации

ReInit() – повторная инициализация

DeInit() – завершение инициализации

OpenAll() – открытие ячеек

TestOnWin() – проверка на выигрыш

CalcValueForCell() – подсчет количества бомб вокруг ячейки

CheckCell() – проверка на наличие ячейки

OpenNullValues() – открытие пустых ячеек

IncFindBombs() – увеличение количества найденных бомб

DecFindBombs() - уменьшение найденных бомб



4. ПРОГРАММНАЯ РЕАЛИЗАЦИЯ



Интерфейс программы был создан с помощью стандартной библиотеки MFC. 

При запуске программы, вы можете установить количество бомб, количество строк и столбцов. После этого нажимаете на кнопку Начать. 

См. Приложение3. (Рис.1) 

Далее вы щелкаете на ячейку, чтобы открыть ее, где предположительно нет бомбы.

См. Приложение 3. (Рис.2) 

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

См. Приложение 3. (Рис.3) 

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

См. Приложение 3. (Рис.4,5) 



ВЫВОДЫ



В ходе выполнения данного курсового проекта были разработана программа на языке высокого уровня Visual C++. А также изучены возможности данного языка. 

Систематизированы и закреплены практические навыки использования ЭВМ, программного обеспечения, существующих средств обслуживания системных программистов, а также теоретические знания по основным разделам курса "Объектно-ориентированное программирование". Основное внимание уделено изучению современных операционных систем, способов проектирования приложений, объектно-ориентированному и системному программированию. 

При выполнении курсового проекта произведено знакомство с реферативными журналами и другими информационными источниками по объектно-ориентированному и системному программированию с целью анализа состояния решаемой задачи. 

Получены практические навыки работы в среде Microsoft Visual Studio. 



ПЕРЕЧЕНЬ ССЫЛОК



1. Бондаренко М.Ф., Бритик В.И., Свинар М.К. Конспект лекций. Часть I "Алгоритмические языки и программирование". "Компания СМИТ" – Харьков, 2004. -221 с. 

2. Павловская Т.А. С/С++ программирование на языке высокого уровня. "Питер" – Санкт Петербург, 2002. -460 с. 

3. Ричард С. Линкер, Том Арчер. Программирование для Windows 98. Библия разработчика. “Диалектика ” – Москва, 1999. -864 с.: ил. - Парал. тит. англ. Уч. пос. 

4. Джесс Либерти. С++ за 21 день. ”Вильямс” – Москва, 2000. -816 с.: ил. - Парал. тит. англ. 





ПРИЛОЖЕНИя

Приложение 1

ДИАГРАММА КЛАССОВ







ПРИЛОЖЕНИЕ 2. 

ТЕКСТ ПРОГРАММЫ

Mycell. h

#ifndef MYCELL_H_

#define MYCELL_H_

// defines... 

// задаем константы

#define CLOSED 0

#define OPENED 1

#define BLOCK 2

#define SIZE 20 

#define WITH_BOMB 0

#define WITHOUT_BOMB 1

// events

#define REDRAW 0x00000001

#define GAMEOVER 0x00000010

#define OPEN_NULL_VALUES 0x00000100

#define WINNER 0x00001000

class CMyCell // базовый класс для ячейки

{

public: 

CMyCell(int x = 0, int y = 0, int state = CLOSED); // координаты ячейки, начальное значение - закрытая ячейка

CMyCell(const CMyCell & copy); 

~CMyCell(); 

// задаем координаты ячейки

int GetX() const; 

int GetY() const; 

int GetState() const; 

// устанавливаем значение координат ячейки

void SetX(int x); 

void SetY(int y); 

void SetState(int state); 

// Рисует закрытую ячейку

void DrawClosedCell(CDC * dc); 

// Рисует заблокированую ячейку 

void DrawBlockedCell(CDC * dc); 

// Попадает ли точка, указанная в параметре, в область этой ячейки 

bool HitToPoint(const CPoint & point); 

// Рисует ячейку 

virtual void Draw(CDC * dc) = 0; 

// Выполняет действия при щелчке на эту ячейку

virtual int Click(CDC * dc) = 0; 

// Возвращает, есть ли тут бомба. 

// Необходимо для инициализации поля 

virtual bool isBomb() const = 0; 

// частные переменные в классе

private: 

int cellX; 

int cellY; 

int cellState; 

}; 

// Класс - указатель(умный указатель) на класс CMyCell

class CPMyCell

{

public: 

CPMyCell(); 

CPMyCell(CMyCell * pMyCell); 

void SetPointer(CMyCell * pMyCell); 

CMyCell * GetPointer() const; 

void Destroy(); 

operator CMyCell*(); 

CMyCell * operator->(); 

private: 

CMyCell * pCell; 

}; 

#endif

Mycell. cpp

// mycell. cpp

// Реализация класса CMyCell, т.е. класса ячейка

#include "stdafx. h"

#include "mycell. h"

CMyCell:: CMyCell(int x, int y, int state) 

: cellX(x), cellY(y), cellState(state) // доступ к переменным

{

// cellX = x; 

// cellY = y; 

// cellState = state; 

}

// // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // /

CMyCell:: CMyCell(const CMyCell & copy) 

: cellX(copy. GetX()), cellY(copy. GetY()), cellState(copy. GetState()) // копирующий уонструктор

{

}

// // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // /

CMyCell:: ~CMyCell() // деструктор

{

}

int CMyCell:: GetX() const

{

return cellX; // возвращает значение x

}

// // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // /

int CMyCell:: GetY() const

{

return cellY; // возвращает значение у

}

// // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // /

int CMyCell:: GetState() const

{

return cellState; // возвращает значение позиции

}

// // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // /

void CMyCell:: SetX(int x) // проверка на то, чтоб координата х была больше нуля

{

if (x >= 0) 

cellX = x; 

else

cellX = 0; // error

}

// // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // /

void CMyCell:: SetY(int y) // проверка на то, чтоб координата у была больше нуля

{

if (y >= 0) 

cellY = y; 

else

cellY = 0; // error

}

// // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // /

void CMyCell:: SetState(int state) // проверка на то, чтоб значение позиции было больше нуля

{

if (state >= 0) 

cellState = state; 

else

cellState = 0; // error

}

// // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // /

bool CMyCell:: HitToPoint(const CPoint & point) // создание ячейки

// проверка положения ячейки

{ if ((point. x > 10 + GetY() * (SIZE + 2)) && (point. x < 10 + GetY() * (SIZE + 2) + SIZE) &&

(point. y > 10 + GetX() * (SIZE + 2)) && (point. y < 10 + GetX() * (SIZE + 2) + SIZE)) 

return true; 

return false; 

}

// // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // /

void CMyCell:: DrawClosedCell(CDC * dc) // прорисовка закрытой ячейки

{

CPen pen(PS_SOLID, 1, RGB(0, 0, 0)); 

CBrush brush(RGB(204, 204, 204)); 

CPen * oldPen = dc->SelectObject(&pen); 

CBrush * oldBrush = dc->SelectObject(&brush); 

dc->Rectangle(10 + GetY() * (SIZE + 2), 10 + GetX() * (SIZE + 2),

10 + GetY() * (SIZE + 2) + SIZE, 10 + GetX() * (SIZE + 2) + SIZE); 

dc->SelectObject(oldBrush); 

dc->SelectObject(oldPen); 

}

// // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // /

void CMyCell:: DrawBlockedCell(CDC * dc) // прорисовка заблокированной ячейки

{

CPen pen(PS_SOLID, 1, RGB(0, 0, 0)); 

CBrush brush(RGB(204, 204, 204)); 

// CPen penBlock(PS_SOLID, 4, RGB(0, 0, 0)); 

CPen * oldPen = dc->SelectObject(&pen); 

CBrush * oldBrush = dc->SelectObject(&brush); 

dc->Rectangle(10 + GetY() * (SIZE + 2), 10 + GetX() * (SIZE + 2),

10 + GetY() * (SIZE + 2) + SIZE, 10 + GetX() * (SIZE + 2) + SIZE); 

// CPen * oldBlockPen = dc->SelectObject(&penBlock); 

dc->TextOutA(10 + GetY() * (SIZE + 2) + 6, 10 + GetX() * (SIZE + 2) + 3, "B", 1); // обозначение флажка

// dc->SelectObject(oldBlockPen); 

dc->SelectObject(oldBrush); // указатель на обьект ячейки

dc->SelectObject(oldPen); 

}

// // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // /

// Реализация класса CPMyCell // // // // // // // // // // // // // // // // // /

// // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // /

CPMyCell:: CPMyCell() 

: pCell (NULL) // конструктор по умолчанию

{

}

// // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // /

CPMyCell:: CPMyCell(CMyCell * pMyCell) 

: pCell (pMyCell) 

{

}

// // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // /

void CPMyCell:: SetPointer(CMyCell * pMyCell) 

{

pCell = pMyCell; // конструктор копирования, установка указателя

}

// // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // /

CMyCell * CPMyCell:: GetPointer() const

{

return pCell; // взятие указателя

}

// // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // /

void CPMyCell:: Destroy() // удаление ячейки

{

if (pCell! = NULL) 

delete pCell; 

pCell = NULL; 

}

// // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // /

CPMyCell:: operator CMyCell *() 

{

return pCell; 

}

// // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // /

CMyCell * CPMyCell:: operator - >() 

{

return pCell; 

}

Mycellbomb. h

#ifndef MYCELL_BOMB_H_

#define MYCELL_BOMB_H_

#include "mycell. h"

class CMyCellBomb: public CMyCell // ячейка с бомбой

{

public: 

CMyCellBomb(int x = 0, int y = 0, int state = CLOSED); // задаем координаты ячейки с бомбо. изначальный вид - ячейка закрыта

CMyCellBomb(const CMyCellBomb & copy); // конструктор копирования

~CMyCellBomb(); 

// Рисует ячейку 

virtual void Draw(CDC * dc); 

// Выполняет действия при щелчке на эту ячейку 

virtual int Click(CDC * dc); 

// Возвращает значение, по которому определяется, есть ли тут бомба. 

// Необходимо для инициализации поля 

virtual bool isBomb() const; 

}; 

#endif

Mycellbomb. cpp

// mycellbomb. cpp

// Реализация класса CMyCellBomb, т.е. ячейки с бомбой

#include "stdafx. h"

#include "mycellbomb. h"

CMyCellBomb:: CMyCellBomb(int x, int y, int state) 

: CMyCell(x, y, state) // устанавливаем координаты ячейки, конструктор по умолчанию

{

}

// // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // /

CMyCellBomb:: CMyCellBomb(const CMyCellBomb & copy) 

: CMyCell(copy) // конструктор копирования

{

}

// // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // /

CMyCellBomb:: ~CMyCellBomb() // деструктор

{

}

// // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // /

void CMyCellBomb:: Draw(CDC * dc) // рисуем бомбы

{

if (GetState() == CLOSED) // если закрыто, то рисуем закрытую ячейку

CMyCell:: DrawClosedCell(dc); 

else if (GetState() == BLOCK) // если стоит флажок, то рисуем флажок

CMyCell:: DrawBlockedCell(dc); 

else

// рисуем бомбы

{

CPen pen(PS_SOLID, 1, RGB(0, 0, 0)); 

CBrush brush(RGB(255, 0, 0)); 

CBrush brushCircle(RGB(0, 0, 0)); 

CPen * oldPen = dc->SelectObject(&pen); 

CBrush * oldBrush = dc->SelectObject(&brush); 

dc->Rectangle(10 + GetY() * (SIZE + 2), 10 + GetX() * (SIZE + 2),

10 + GetY() * (SIZE + 2) + SIZE, 10 + GetX() * (SIZE + 2) + SIZE); 

CBrush * oldBrushCircle = dc->SelectObject(&brushCircle); 

dc->Ellipse(10 + GetY() * (SIZE + 2) + 4, 10 + GetX() * (SIZE + 2) + 4,

10 + GetY() * (SIZE + 2) + SIZE - 4, 10 + GetX() * (SIZE + 2) + SIZE - 4); 

dc->SelectObject(oldBrushCircle); 

dc->SelectObject(oldBrush); 

dc->SelectObject(oldPen); 

}

}

// // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // /

int CMyCellBomb:: Click(CDC * dc) // проверка на щелчок

{

if (GetState() == BLOCK) // если стоит флажок, то ячейка не откроется при нажатии

return 0; 

SetState(OPENED); // открытие ячейки

Draw(dc); 

return REDRAW | GAMEOVER; // т. к. в ячейке находится бомба, а вы ее открываете, то следовательно вы проиграли

}

// // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // /

bool CMyCellBomb:: isBomb() const // есть ли это бомба

{

return true; 

}

Mycellwob. h

#ifndef MYCELL_WOB_H_

#define MYCELL_WOB_H_

#include "mycell. h"

class CMyCellWob: public CMyCell // ячейка без бомбы

{

public: 

CMyCellWob(int x = 0, int y = 0, int state = CLOSED, int val = 0); // задаем координаты ячейки и значение. начальное положение - закрытая ячейка

CMyCellWob(const CMyCellWob & copy); // копирующий конструктор

~CMyCellWob(); // деструктор

int GetValue() const; // передаем значения

void SetValue(int val); 

// Рисует ячейку 

virtual void Draw(CDC * dc); 

// Выполняет действия при щелчке на эту ячейку 

virtual int Click(CDC * dc); 

// Возвращает значение, по которому определяется, есть ли тут бомба. 

// Необходимо для инициализации поля

virtual bool isBomb() const; 

private: 

int value; 

}; 

#endif

Mycellwob. cpp

// mycellbomb. cpp

// Реализация класса CMyCellBomb, т.е. ячейки с бомбой

#include "stdafx. h"

#include "mycellbomb. h"

// // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // /

CMyCellBomb:: CMyCellBomb(int x, int y, int state) 

: CMyCell(x, y, state) // устанавливаем координаты ячейки, конструктор по умолчанию

{

}

// // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // /

CMyCellBomb:: CMyCellBomb(const CMyCellBomb & copy) 

: CMyCell(copy) // конструктор копирования

{

}

// // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // /

CMyCellBomb:: ~CMyCellBomb() // деструктор

{

}

// // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // /

void CMyCellBomb:: Draw(CDC * dc) // рисуем бомбы

{

if (GetState() == CLOSED) // если закрыто, то рисуем закрытую ячейку

CMyCell:: DrawClosedCell(dc); 

else if (GetState() == BLOCK) // если стоит флажок, то рисуем флажок

CMyCell:: DrawBlockedCell(dc); 

else

// рисуем бомбы

{

CPen pen(PS_SOLID, 1, RGB(0, 0, 0)); 

CBrush brush(RGB(255, 0, 0)); 

CBrush brushCircle(RGB(0, 0, 0)); 

CPen * oldPen = dc->SelectObject(&pen); 

CBrush * oldBrush = dc->SelectObject(&brush); 

dc->Rectangle(10 + GetY() * (SIZE + 2), 10 + GetX() * (SIZE + 2),

10 + GetY() * (SIZE + 2) + SIZE, 10 + GetX() * (SIZE + 2) + SIZE); 

CBrush * oldBrushCircle = dc->SelectObject(&brushCircle); 

dc->Ellipse(10 + GetY() * (SIZE + 2) + 4, 10 + GetX() * (SIZE + 2) + 4,

10 + GetY() * (SIZE + 2) + SIZE - 4, 10 + GetX() * (SIZE + 2) + SIZE - 4); 

dc->SelectObject(oldBrushCircle); 

dc->SelectObject(oldBrush); 

dc->SelectObject(oldPen); 

}

}

// // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // /

int CMyCellBomb:: Click(CDC * dc) // проверка на щелчок

{

if (GetState() == BLOCK) // если стоит флажок, то ячейка не откроется при нажатии

return 0; 

SetState(OPENED); // открытие ячейки

Draw(dc); 

return REDRAW | GAMEOVER; // т. к. в ячейке находится бомба, а вы ее открываете, то следовательно вы проиграли

}

// // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // /

bool CMyCellBomb:: isBomb() const // есть ли это бомба

{

return true; 

}

Myfield. h

#ifndef MYFIELD_H_

#define MYFIELD_H_

#include "mycell. h"

class MyField // класс поле, класс-контейнер

{

public: 

MyField(); 

~MyField(); // деструктор

int GetCols() const; // значение колонок

int GetRows() const; // значение строк

int GetBombsCount() const; // количество бомб

int GetFindBombsCount() const; // количество найденных бомб вокруг ячейки

// устанавливаем значения

void SetCols(int c); 

void SetRows(int r); 

void SetBombsCount(int kol); 

void SetFindBombsCount(int kol); 

// установка ячеек по индексу

CMyCell * GetCellByIndex(int i, int j); 

CPMyCell * GetPCellByIndex(int i, int j); 

void SetCellByIndex(int i, int j, CMyCell * cell); 

void Init(int cs, int rs, int kb); // инициализация

void ReInit(int cs, int rs, int kb); // перерисовка поля

void DeInit(); // удаление поля

void Draw(CDC * dc); 

int Click(CDC * dc, const CPoint & point); 

void Block(CDC * dc, const CPoint & point); 

void OpenAll(); 

bool TestOnWin(); // тест на выигрыш

private: 

int CalcValueForCell(int i, int j); // подсчитываем цифры для ячейки

bool CheckCell(int i, int j); // проверяем. есть ли это ячейка

void OpenNullValues(int i, int j); // открываем пустую ячейку

void IncFindBombs(); // увеличиваем на еденицу количество бомб

void DecFindBombs(); // уменьшаем на еденицу количество бомб

private: 

// вводим переменные

int cols; 

int rows; 

int kolBombs; 

int kolFindBombs; 

CPMyCell ** field; 

private: 

int countItter; 

}; 

#endif

Myfield. cpp

// myfield. cpp

// Класс для работы с полем обьектов CMyCell

#include "stdafx. h"

#include "mycell. h"

#include "mycellbomb. h"

#include "mycellwob. h"

#include "myfield. h"

#include <stdlib. h>

#include <time. h>

// // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // /

MyField:: MyField() 

: cols(10), rows(10), kolBombs(10), field(NULL) // вводим значения

{

countItter = 0; 

srand(time(0)); // задает новое значение для генерации случайных чисел

}

// // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // /

MyField:: ~MyField() // деструктор

{

DeInit(); // удаление поля

}

// // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // /

int MyField:: GetCols() const // доступ к колонкам

{

return cols; 

}

// // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // /

int MyField:: GetRows() const // доступ к строкам

{

return rows; 

}

// // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // /

int MyField:: GetBombsCount() const // доступ к количеству бомб

{

return kolBombs; 

}

// // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // /

int MyField:: GetFindBombsCount() const // доступ к значению количества найденных бомб вокруг ячейки

{

return kolFindBombs; 

}

// // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // /

void MyField:: SetCols(int c) // проверка на то, что колонки больше нуля

{

if (c >= 0) 

cols = c; 

else 

cols = 0; // error

}

// // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // /

void MyField:: SetRows(int r) // проверка на то, что строки больше нуля

{

if (r >= 0) 

rows = r; 

else

rows = 0; // error

}

// // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // /

void MyField:: SetBombsCount(int kol) // ограничиваем количество бомб

{

int maxVal = GetCols() * GetRows() - GetCols() - GetRows(); // условие количества

if (kol > 0 && kol <= maxVal) 

kolBombs = kol; 

else if (kol <= 0) 

kolBombs = 10; // error

else if (kol > maxVal) 

kolBombs = maxVal; 

}

// // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // /

void MyField:: SetFindBombsCount(int kol) 

{

kolFindBombs = kol; 

}

// // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // /

CMyCell * MyField:: GetCellByIndex(int i, int j) 

{

if (field == NULL) // если щелчок просто по полю, то ничего не происходит

return NULL; // error

if (i >= 0 && i < GetCols() && j >= 0 && j < GetRows()) // чтоб ячейка не выходила за рамки поля

return field [i] [j] ; // расширение-сужение поля

// error

return NULL; 

}

// // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // /

CPMyCell * MyField:: GetPCellByIndex(int i, int j) // массив указателей

{

if (field == NULL) 

return NULL; // error

if (i >= 0 && i < GetCols() && j >= 0 && j < GetRows()) 

return &field [i] [j] ; 

// error

return NULL; 

}

// // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // /

void MyField:: SetCellByIndex(int i, int j, CMyCell * cell) // установка ячейки по индексу

{

if (field == NULL) // если поле пустое

return; // error

if (i >= 0 && i < GetCols() && j >= 0 && j < GetRows()) 

field [i] [j]. SetPointer(cell); 

}

// // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // /

void MyField:: Init(int cs, int rs, int kb) // задаем значения

{

if (field! = NULL) // поле не пустое

return; // error

if (cs * rs <= kb) 

return; // error

SetCols(cs); 

SetRows(rs); 

SetBombsCount(kb); 

if (cols == 0 || rows == 0) 

return; // error

// Создаем поле

field = new CPMyCell* [GetCols()] ; // создание двумерного массива в виде строк и столбцов

for (int i = 0; i < GetCols(); i++) 

field [i] = new CPMyCell [GetRows()] ; 

// Конструктор это делает по умолчанию сам, но если вдруг разкоментировать

// for (int i = 0; i < GetCols() * GetRows(); i++) 

// field [i] ->SetPointer(NULL); 

// Генерируем, где расспалагаются бомбы

int tmp = GetBombsCount(); // временные переменные

int tmp_cs = 0; 

int tmp_rs = 0; 

while(tmp! = 0) 

{ // выставляем случайно бомбы

tmp_cs = rand()% GetCols(); 

tmp_rs = rand()% GetRows(); 

if (field [tmp_cs] [tmp_rs]. GetPointer() == NULL) // если нет бомбы

{

tmp--; // уменьшаем количество бомб на еденицу

field [tmp_cs] [tmp_rs]. SetPointer(new CMyCellBomb(tmp_cs, tmp_rs, CLOSED)); 

}

else

continue; 

}

// Генерируем остальные ячейки

for (int i = 0; i < GetCols(); i++) 

for (int j = 0; j < GetRows(); j++) 

if (field [i] [j]. GetPointer() == NULL) // Значит не занятая бомбой

field [i] [j]. SetPointer(new CMyCellWob(i, j, CLOSED, CalcValueForCell(i, j))); 

SetFindBombsCount(0); 

}

// // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // /

void MyField:: ReInit(int cs, int rs, int kb) // перерисовка поля

{

DeInit(); // очистка поля

Init(cs, rs, kb); // задаем поле

}

// // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // /

void MyField:: DeInit() // очистка поля

{

if (field == NULL) 

return; 

for (int i = 0; i < GetCols(); i++) 

for (int j = 0; j < GetRows(); j++) 

if (field [i] [j]. GetPointer() ! = NULL) 

field [i] [j]. Destroy(); 

for (int i = 0; i < GetCols(); i++) // удаление массива

if (field [i] ! = NULL) 

delete [] field [i] ; 

if (field! = NULL) 

delete [] field; 

field = NULL; 

}

// // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // /

void MyField:: Draw(CDC * dc) // рисуем поле

{

if (field == NULL) 

return; // error

for (int i = 0; i < GetCols(); i++) 

for (int j = 0; j < GetRows(); j++) 

if (field [i] [j] ! = NULL) 

field [i] [j] ->Draw(dc); 

}

// // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // /

int MyField:: Click(CDC * dc, const CPoint & point) // проверка, попала ли мышь по ячейке

{

if (field == NULL) 

return 0; // error

for (int i = 0; i < GetCols(); i++) 

{

for (int j = 0; j < GetRows(); j++) 

{

if (field [i] [j] ->HitToPoint(point)) 

{

int res = field [i] [j] ->Click(dc); // если попала по ячейке, то открываем ее

if (res & OPEN_NULL_VALUES) 

{

this->countItter = 0; 

OpenNullValues(i, j); 

}

if (TestOnWin()) // тест на выигрыш

{

OpenAll(); 

res |= WINNER; 

}

if (res & GAMEOVER) 

OpenAll(); 

return res; 

}

}

}

return 0; 

}

// // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // /

void MyField:: Block(CDC * dc, const CPoint & point) // возможность ставить флажки по всему полю

{

if (field == NULL) 

return; // error

for (int i = 0; i < GetCols(); i++) 

{

for (int j = 0; j < GetRows(); j++) 

{

if (field [i] [j] ->HitToPoint(point)) 

{

if (field [i] [j] ->GetState() == OPENED) 

return; 

if (field [i] [j] ->GetState() == CLOSED) 

{

IncFindBombs(); 

field [i] [j] ->SetState(BLOCK); // проверка на флажок

return; 

}

if (field [i] [j] ->GetState() == BLOCK) // правая кнопка убирает флажок

{

DecFindBombs(); 

field [i] [j] ->SetState(CLOSED); 

return; 

}

}

}

}

}

// // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // /

int MyField:: CalcValueForCell(int i, int j) 

{

int value = 0; 

// Обходим все соседние ячейки в поисках бомб 

if (CheckCell(i, j - 1)) 

if (GetCellByIndex(i, j - 1) ! = NULL && GetCellByIndex(i, j - 1) - >isBomb()) 

value++; 

if (CheckCell(i - 1, j - 1)) 

if (GetCellByIndex(i - 1, j - 1) ! = NULL && GetCellByIndex(i - 1, j - 1) - >isBomb()) 

value++; 

if (CheckCell(i - 1, j)) 

if (GetCellByIndex(i - 1, j) ! = NULL && GetCellByIndex(i - 1, j) - >isBomb()) 

value++; 

if (CheckCell(i - 1, j + 1)) 

if (GetCellByIndex(i - 1, j + 1) ! = NULL && GetCellByIndex(i - 1, j + 1) - >isBomb()) 

value++; 

if (CheckCell(i, j + 1)) 

if (GetCellByIndex(i, j + 1) ! = NULL && GetCellByIndex(i, j + 1) - >isBomb()) 

value++; 

if (CheckCell(i + 1, j + 1)) 

if (GetCellByIndex(i + 1, j + 1) ! = NULL && GetCellByIndex(i + 1, j + 1) - >isBomb()) 

value++; 

if (CheckCell(i + 1, j)) 

if (GetCellByIndex(i + 1, j) ! = NULL && GetCellByIndex(i + 1, j) - >isBomb()) 

value++; 

if (CheckCell(i + 1, j - 1)) 

if (GetCellByIndex(i + 1, j - 1) ! = NULL && GetCellByIndex(i + 1, j - 1) - >isBomb()) 

value++; 

return value; 

}

// // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // /

bool MyField:: CheckCell(int i, int j) 

{

if (i >= 0 && j >= 0 && i < GetCols() && j < GetRows()) 

return true; 

return false; 

}

// // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // /

void MyField:: OpenAll() // открытие ячеек

{

if (field == NULL) 

return; // error

// передаем значение номера строки и столбца

for (int i = 0; i < GetCols(); i++) 

for (int j = 0; j < GetRows(); j++) 

field [i] [j] ->SetState(OPENED); 

}

// // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // /

void MyField:: OpenNullValues(int i, int j) // пустые ячейки, а вокруг цифры

{

if (! CheckCell(i, j)) 

return; 

if (GetCellByIndex(i, j) == NULL) 

return; 

if (GetCellByIndex(i, j) - >isBomb()) 

return; 

else

if (countItter! = 0 && (GetCellByIndex(i, j) - >GetState() == OPENED ||

GetCellByIndex(i, j) - >GetState() == BLOCK)) // не может открыть ячейку, если она уже открыта либо стоит с флажком

return; 

GetCellByIndex(i, j) - >SetState(OPENED); 

countItter++; 

// Обходим все соседние ячейки чтобы их открыть

if (((CMyCellWob *) GetCellByIndex(i, j)) - >GetValue() == 0) 

{

OpenNullValues(i, j - 1); 

OpenNullValues(i - 1, j - 1); 

OpenNullValues(i - 1, j); 

OpenNullValues(i - 1, j + 1); 

OpenNullValues(i, j + 1); 

OpenNullValues(i + 1, j + 1); 

OpenNullValues(i + 1, j); 

OpenNullValues(i + 1, j - 1); 

}

}

// // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // /

void MyField:: IncFindBombs() 

{

kolFindBombs++; // увеличиваем количество найденных бомб на еденицу

}

// // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // /

void MyField:: DecFindBombs() 

{

kolFindBombs--; // уменьшаем количество найденных бомб на еденицу

}

// // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // /

bool MyField:: TestOnWin() // тест на выигрыш

{

for (int i = 0; i < GetCols(); i++) 

{

for (int j = 0; j < GetRows(); j++) 

{

if (! field [i] [j] ->isBomb() && 

(field [i] [j] ->GetState() == CLOSED || 

field [i] [j] ->GetState() == BLOCK)) 

return false; 

}

}

return true; 

}

// // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // /

SaperDlg. h

// saperDlg. h: header file

// 

#pragma once

#include "myfield. h"

// CsaperDlg dialog

class CsaperDlg: public CDialog

{

// Construction

public: 

CsaperDlg(CWnd* pParent = NULL);  // standard constructor

// Dialog Data

enum { IDD = IDD_SAPER_DIALOG }; 

protected: 

virtual void DoDataExchange(CDataExchange* pDX);  // DDX/DDV support

private: // внутренние переменные и функции класса

MyField field; 

bool isInitAll; 

bool begin; 

bool isFirstClick; 

void SetPosition(); 

void ShowFindBombs(); 

// Implementation

protected: 

HICON m_hIcon; 

CFont fontFindBombs; 

CString nameOfPowered; 

// Generated message map functions

virtual BOOL OnInitDialog(); 

afx_msg void OnPaint(); 

afx_msg HCURSOR OnQueryDragIcon(); 

DECLARE_MESSAGE_MAP() 

public: 

afx_msg void OnLButtonDown(UINT nFlags, CPoint point); // функция для щелчка левой кнопкой мыши

public: 

afx_msg void OnRButtonDown(UINT nFlags, CPoint point); // функция для щелчка правой кнопкой мыши

public: 

int bombsCount; // счетчик бомб

public: 

int height; // высота

public: 

int width; // ширина

public: 

afx_msg void OnBnClickedButtonExit(); // функция выхода из игры

public: 

afx_msg void OnBnClickedButtonStart(); // функция для начала игры

}; 

SaperDlg. cpp

// saperDlg. cpp: implementation file

// 

#include "stdafx. h"

#include "saper. h"

#include "saperDlg. h"

#ifdef _DEBUG

#define new DEBUG_NEW

#endif

#include "myfield. h"

#include "mycell. h"

// CsaperDlg dialog

CsaperDlg:: CsaperDlg(CWnd* pParent /*=NULL*/) 

: CDialog(CsaperDlg:: IDD, pParent), isInitAll(false), begin (false), isFirstClick(true) 

, bombsCount(0) 

, height(0) 

, width(0) 

{

m_hIcon = AfxGetApp() - >LoadIcon(IDR_MAINFRAME); 

// шрифт

fontFindBombs. CreateFontA(

50,

0,

0,

0,

400,

FALSE,

FALSE,

0,

ANSI_CHARSET,

OUT_DEFAULT_PRECIS,

CLIP_DEFAULT_PRECIS,

DEFAULT_QUALITY,

DEFAULT_PITCH | FF_MODERN,

"Courier"); 

nameOfPowered = "Разработчик: Гаврюшенко Мария Александровна\r\nГруппа: КН-06-4"; 

}

void CsaperDlg:: DoDataExchange(CDataExchange* pDX) 

{

CDialog:: DoDataExchange(pDX); 

DDX_Text(pDX, IDC_EDIT_BOMBS_COUNT, bombsCount); 

DDV_MinMaxInt(pDX, bombsCount, 1, 4096); 

DDX_Text(pDX, IDC_EDIT_HEIGHT, height); 

DDV_MinMaxInt(pDX, height, 10, 40); 

DDX_Text(pDX, IDC_EDIT_WIDTH, width); 

DDV_MinMaxInt(pDX, width, 10, 50); 

}

BEGIN_MESSAGE_MAP(CsaperDlg, CDialog) 

ON_WM_PAINT() 

ON_WM_QUERYDRAGICON() 

// }}AFX_MSG_MAP

ON_WM_LBUTTONDOWN() 

// ON_WM_MOUSEMOVE() 

ON_WM_RBUTTONDOWN() 

ON_BN_CLICKED(IDC_BUTTON_EXIT, &CsaperDlg:: OnBnClickedButtonExit) 

ON_BN_CLICKED(IDC_BUTTON_START, &CsaperDlg:: OnBnClickedButtonStart) 

END_MESSAGE_MAP() 

// CsaperDlg message handlers

BOOL CsaperDlg:: OnInitDialog() 

{

CDialog:: OnInitDialog(); 

// Set the icon for this dialog. The framework does this automatically

// when the application's main window is not a dialog

SetIcon(m_hIcon, TRUE);  // Set big icon

SetIcon(m_hIcon, FALSE);  // Set small icon

// значения, которые находятся в окне

CRect rect; // задаем значения переменным

GetWindowRect(&rect); 

field. Init(10, 10, 15); // поле

height = field. GetCols(); // высота

width = field. GetRows(); // ширина

bombsCount = field. GetBombsCount(); // счетчик бомб

SetPosition(); // устанавливаем позицию

isInitAll = true; 

begin = true; 

isFirstClick = true; 

UpdateData(FALSE); 

return TRUE; // return TRUE unless you set the focus to a control

}

// If you add a minimize button to your dialog, you will need the code below

// to draw the icon. For MFC applications using the document/view model,

// this is automatically done for you by the framework. 

void CsaperDlg:: OnPaint() 

{

if (IsIconic()) 

{

CPaintDC dc(this); // device context for painting

SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc. GetSafeHdc()), 0); 

// Center icon in client rectangle

// установка иконки

int cxIcon = GetSystemMetrics(SM_CXICON); 

int cyIcon = GetSystemMetrics(SM_CYICON); 

CRect rect; 

GetClientRect(&rect); 

int x = (rect. Width() - cxIcon + 1) / 2; 

int y = (rect. Height() - cyIcon + 1) / 2; 

// Draw the icon

dc. DrawIcon(x, y, m_hIcon); 

}

else

{

CDialog:: OnPaint(); 

CDC * dc = GetDC(); 

if (isInitAll) 

{

// рисуем бомбу

CBrush brush; 

brush. CreateSolidBrush(RGB(255, 255, 255)); 

CBrush * oldBrush = dc->SelectObject(&brush); 

dc->Rectangle(8, 8, field. GetRows() * (SIZE + 2) + 10,

field. GetCols() * (SIZE + 2) + 10); 

dc->SelectObject(oldBrush); 

field. Draw(dc); 

}

}

}

// The system calls this function to obtain the cursor to display while the user drags

// the minimized window. 

HCURSOR CsaperDlg:: OnQueryDragIcon() 

{

return static_cast<HCURSOR>(m_hIcon); 

}

void CsaperDlg:: OnLButtonDown(UINT nFlags, CPoint point) 

{

if (! begin) 

return; 

if (point. x < 10 || point. x > (field. GetRows() * (SIZE + 2) + 3) ||

point. y < 10 || point. y > (field. GetCols() * (SIZE + 2) + 3)) 

return; 

CDC * dc = GetDC(); 

int result; 

result = field. Click(dc, point); 

// если при первом щелчке вы проиграли, то поле перерисовуется

if (isFirstClick) 

{

while (result & GAMEOVER) 

{

field. ReInit(field. GetCols(), field. GetRows(), field. GetBombsCount()); 

result = field. Click(dc, point); 

}

}

ShowFindBombs(); // показывает найденные бомбы

if (result & REDRAW) // перерисовуем поле

{

field. Draw(dc); 

CRect rect; 

GetWindowRect(&rect); 

InvalidateRect(rect, TRUE); 

}

if (result & GAMEOVER) // если вы проиграли

{

begin = false; 

MessageBox("Вы проиграли!!!: '(", "Конец игры", MB_OK); 

}

if (result & WINNER) // если вы выиграли

{

begin = false; 

MessageBox("Вы выграли!!!:)))", "Конец игры", MB_OK); 

}

isFirstClick = false; 

CDialog:: OnLButtonDown(nFlags, point); 

}

void CsaperDlg:: OnRButtonDown(UINT nFlags, CPoint point) 

{

if (! begin) 

return; 

if (point. x < 10 || point. x > (field. GetRows() * (SIZE + 2) + 3) ||

point. y < 10 || point. y > (field. GetCols() * (SIZE + 2) + 3)) 

return; 

CDC * dc = GetDC(); 

field. Block(dc, point); 

field. Draw(dc); 

ShowFindBombs(); 

CRect rect; 

GetWindowRect(&rect); 

InvalidateRect(rect, TRUE); 

CDialog:: OnRButtonDown(nFlags, point); 

}

void CsaperDlg:: OnBnClickedButtonExit() 

{

// Выход

OnOK(); 

}

void CsaperDlg:: OnBnClickedButtonStart() 

{

// Begin

isInitAll = false; 

begin = false; 

UpdateData(TRUE); 

CDC * dc = GetDC(); 

field. ReInit(height, width, bombsCount); // перерисовка

height = field. GetCols(); 

width = field. GetRows(); 

bombsCount = field. GetBombsCount(); 

SetPosition(); 

field. Draw(dc); 

CRect rect; 

GetWindowRect(&rect); 

InvalidateRect(rect, TRUE); 

isInitAll = true; 

begin = true; 

isFirstClick = true; 

UpdateData(FALSE); 

}

void CsaperDlg:: SetPosition() 

{

CRect rect; 

GetWindowRect(&rect); 

// движение окна

MoveWindow(rect. left, rect. top, field. GetRows() * (SIZE + 2) + 230, 

field. GetCols() * (SIZE + 2) + 80, TRUE); 

ShowFindBombs(); 

// создание кнопок в окне

GetDlgItem(IDC_STATIC_BOMBS_COUNT) - >SetWindowTextA("Количество бомб: "); 

GetDlgItem(IDC_STATIC_BOMBS_COUNT) - >MoveWindow(field. GetRows() * (SIZE + 2) + 30,

70, 130, 15, TRUE); 

GetDlgItem(IDC_EDIT_BOMBS_COUNT) - >MoveWindow(field. GetRows() * (SIZE + 2) + 160,

67, 50, 20, TRUE); 

GetDlgItem(IDC_STATIC_HEIGHT) - >SetWindowTextA("Высота: "); 

GetDlgItem(IDC_STATIC_HEIGHT) - >MoveWindow(field. GetRows() * (SIZE + 2) + 30,

100, 130, 15, TRUE); 

GetDlgItem(IDC_EDIT_HEIGHT) - >MoveWindow(field. GetRows() * (SIZE + 2) + 160,

97, 50, 20, TRUE); 

GetDlgItem(IDC_STATIC_WIDTH) - >SetWindowTextA("Ширина: "); 

GetDlgItem(IDC_STATIC_WIDTH) - >MoveWindow(field. GetRows() * (SIZE + 2) + 30,

130, 130, 15, TRUE); 

GetDlgItem(IDC_EDIT_WIDTH) - >MoveWindow(field. GetRows() * (SIZE + 2) + 160,

127, 50, 20, TRUE); 

GetDlgItem(IDC_BUTTON_START) - >SetWindowTextA("Начать"); 

GetDlgItem(IDC_BUTTON_START) - >MoveWindow(field. GetRows() * (SIZE + 2) + 70,

170, 100, 20, TRUE); 

GetDlgItem(IDC_BUTTON_EXIT) - >SetWindowTextA("Выход"); 

GetDlgItem(IDC_BUTTON_EXIT) - >MoveWindow(field. GetRows() * (SIZE + 2) + 70,

200, 100, 20, TRUE); 

GetWindowRect(&rect); 

GetDlgItem(IDC_STATIC_POWEREDBY) - >SetWindowTextA(nameOfPowered); 

GetDlgItem(IDC_STATIC_POWEREDBY) - >MoveWindow(rect. Width() / 2 - 180,

rect. Height() - 65, 350, 50, FALSE); 



}

void CsaperDlg:: ShowFindBombs() // показать найденные бомбы

{

char *pNum = NULL; 

char num [5] ; 

pNum = itoa(field. GetBombsCount() - field. GetFindBombsCount(), num, 10); // перевод цифрового значения в строчный

GetDlgItem(IDC_STATIC_FIND_BOMBS_COUNT) - >SetFont(&fontFindBombs, TRUE); 

GetDlgItem(IDC_STATIC_FIND_BOMBS_COUNT) - >SetWindowTextA(pNum); 

GetDlgItem(IDC_STATIC_FIND_BOMBS_COUNT) - >MoveWindow(field. GetRows() * (SIZE + 2) + 70,

10, 100, 50, TRUE); 

}

ПРИЛОЖЕНИЕ 3. 

ИНТЕРФЕЙС ПРОГРАММЫ





РИС.1





РИС.2





РИС.3

РИС.4

РИС.5