Смекни!
smekni.com

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()

{