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"
classMyField // класс поле, класс-контейнер
{
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); // перерисовка поля
voidDeInit(); // удаление поля
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);
// Генерируем, где расспалагаются бомбы
inttmp = 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()
{