На этом шаге мы приведем полный текст программы.
Полный текст программы "Сапер" приведен ниже.
Модуль главной формы:
#pragma once #include "Form2.h" namespace Saper { using namespace System; using namespace System::ComponentModel; using namespace System::Collections; using namespace System::Windows::Forms; using namespace System::Data; using namespace System::Drawing; /// <summary> /// Сводка для Form1 /// </summary> public ref class Form1 : public System::Windows::Forms::Form { public: Form1(void) { InitializeComponent(); // //TODO: добавьте код конструктора // // клеткам границы игрового поля запишем число -3. // Это значение используется процедурой open() // для завершения рекурсивного процесса открытия // соседних пустых клеток for(int row = 0; row <= MR+1; row++) { Pole[row,0] = -3; Pole[row,MC+1] = -3; } for(int col = 0; col <= MC+1; col++) { Pole[0,col] = -3; Pole[MR+1,col] = -3; } // устанавливаем размер формы в соответствии // с размером игрового поля this->ClientSize = System::Drawing::Size(W*MC + 1, H*MR + menuStrip1->Height + 1); newGame(); // новая игра // графическая поверхность g = panel1->CreateGraphics(); } . . . . . } #pragma endregion private: static int MR = 10, // кол-во клеток по вертикали MC = 10, // кол-во клеток по горизонтали NM = 10, // кол-во мин W = 40, // ширина клетки H = 40; // высота клетки // игровое (минное) поле static array<int,2>^ Pole = gcnew array<int,2>(MR + 2,MC + 2); // значение элемента массива: // 0..8 - количество мин в соседних клетках // 9 - в клетке мина // 100..109 - клетка открыта // 200..209 - в клетку поставлен флаг int nMin; // кол-во найденных мин int nFlag; // кол-во поставленных флагов // статус игры int status; // 0 - начало игры, // 1 - игра, // 2 - результат // графическая поверхность формы System::Drawing::Graphics^ g; // новая игра void newGame() { int row, col; // индексы клетки int n = 0; // количество поставленных мин int k; // количество мин в соседних клетках // очистить поле for (row = 1; row <= MR; row++) for (col = 1; col <= MC; col++) Pole[row,col] = 0; // генератор случайных чисел Random^ rnd = gcnew Random(); // расставим мины do { row = rnd->Next(MR) + 1; col = rnd->Next(MC) + 1; if (Pole[row,col] != 9) { Pole[row,col] = 9; n++; } } while (n != NM); // для каждой клетки вычислим количество // мин в соседних клетках for (row = 1; row <= MR; row++) for (col = 1; col <= MC; col++) if (Pole[row,col] != 9) { k = 0; if (Pole[row-1,col-1] == 9) k++; if (Pole[row-1,col] == 9) k++; if (Pole[row-1,col+1] == 9) k++; if (Pole[row,col-1] == 9) k++; if (Pole[row,col+1] == 9) k++; if (Pole[row+1,col-1] == 9) k++; if (Pole[row+1,col] == 9) k++; if (Pole[row+1,col+1] == 9) k++; Pole[row,col] = k; } status = 0; // начало игры nMin = 0; // нет обнаруженных мин nFlag = 0; // нет поставленных флагов } // рисует поле void showPole(Graphics^ g, int status) { for (int row = 1; row <= MR; row++) for (int col = 1; col <= MC; col++) this->Kletka(g, row, col, status); } // рисует клетку void Kletka(Graphics^ g, int row, int col, int status) { int x, y; // координаты левого верхнего угла клетки x = (col - 1) * W + 1; y = (row-1)* H + 1; // не открытые клетки - серые if (Pole[row,col] < 100) g->FillRectangle(SystemBrushes::ControlLight, x-1, y-1, W, H); // открытые или помеченные клетки if (Pole[row,col] >= 100) { // открываем клетку, открытые - белые if (Pole[row,col] != 109) g->FillRectangle(Brushes::White, x-1, y-1, W, H); else // на этой мине подорвались! g->FillRectangle(Brushes::Red, x-1, y-1, W, H); // если в соседних клетках есть мины, // указываем их количество if ((Pole[row,col] >= 101) && (Pole[row,col] <= 108)) g->DrawString((Pole[row,col]-100).ToString(), gcnew System::Drawing::Font("Tahoma", 10, System::Drawing::FontStyle::Regular), Brushes::Blue, (float)x+3, (float)y+2); } // в клетке поставлен флаг if (Pole[row,col] >= 200) this->flag(g, x, y); // рисуем границу клетки g->DrawRectangle(Pens::Black, x-1, y-1, W, H); // если игра завершена (status = 2), показываем мины if ((status == 2) && ((Pole[row,col] % 10) == 9)) this->mina(g, x, y); } // щелчок в клетке игрового поля private: System::Void panel1_MouseClick(System::Object^ sender, System::Windows::Forms::MouseEventArgs^ e) { if (status == 2) // игра завершена return; if (status == 0) // первый щелчок status = 1; // Преобразуем координаты мыши в индексы клетки поля, // в которой был сделан щелчок; // (e.X, e.Y) - координаты точки формы, // в которой была нажата кнопка мыши int row, col; row = e->Y/H + 1; col = e->X/W + 1; // координаты области вывода int x = (col-1)* W + 1, y = (row-1)* H + 1; // щелчок левой кнопки мыши if (e->Button == System::Windows::Forms::MouseButtons::Left) { // открыта клетка, в которой есть мина if (Pole[row,col] == 9) { Pole[row,col] += 100; // игра закончена status = 2; // перерисовать форму this->panel1->Invalidate(); } else if (Pole[row,col] < 9) // открыть клетку this->open(row,col); } // щелчок правой кнопки мыши if (e->Button == System::Windows::Forms::MouseButtons::Right) { // в клетке нет флага, ставим его if (Pole[row,col] <= 9) { nFlag += 1; if (Pole[row,col] == 9) nMin += 1; Pole[row,col] += 200; if ((nMin == NM) && (nFlag == NM)) { // игра закончена status = 2; // перерисовываем все игровое поле this->panel1->Invalidate(); } else // перерисовываем только клетку this->Kletka(g, row, col, status); } else // В клетке был поставлен флаг, // повторный щелчок правой кнопки мыши // убирает его и закрывает клетку if (Pole[row,col] >= 200) { nFlag -= 1; Pole[row,col] -= 200; // перерисовываем клетку this->Kletka(g, row, col, status); } } } // открывает текущую и все соседние с ней клетки, // в которых нет мин void open(int row, int col) { // координаты области вывода int x = (col-1)* W + 1, y = (row-1)* H + 1; if (Pole[row,col] == 0) { Pole[row,col] = 100; // отобразить содержимое клетки this->Kletka(g, row, col, status); // открыть примыкающие клетки // слева, справа, сверху, снизу this->open(row, col-1); this->open(row-1, col); this->open(row, col+1); this->open(row+1, col); //примыкающие диагонально this->open(row-1,col-1); this->open(row-1,col+1); this->open(row+1,col-1); this->open(row+1,col+1); } else if ((Pole[row,col] < 100) && (Pole[row,col] != -3)) { Pole[row,col] += 100; // отобразить содержимое клетки this->Kletka(g, row, col, status); } } // рисует флаг void flag(Graphics^ g, int x, int y) { array<Point>^ p = gcnew array<Point>(3); array<Point>^ m = gcnew array<Point>(5); //Point[] m = new Point[5]; // флажок p[0].X = x+4; p[0].Y = y+4; p[1].X = x+30; p[1].Y = y+12; p[2].X = x+4; p[2].Y = y+20; g->FillPolygon(Brushes::Red, p); // древко g->DrawLine(Pens::Black, x+4, y+4, x+4, y+35); // буква M на флажке m[0].X = x+8; m[0].Y = y+14; m[1].X = x+8; m[1].Y = y+8; m[2].X = x+10; m[2].Y = y+10; m[3].X = x+12; m[3].Y = y+8; m[4].X = x+12; m[4].Y = y+14; g->DrawLines(Pens::White, m); } // рисует мину void mina(Graphics^ g, int x, int y) { // корпус g->FillRectangle(Brushes::Green, x+16, y+26, 8, 4); g->FillRectangle(Brushes::Green, x+8, y+30, 24, 4); g->DrawPie(Pens::Black, x+6, y+28, 28, 16, 0, -180); g->FillPie(Brushes::Green, x+6, y+28, 28, 16, 0, -180); // полоса на корпусе g->DrawLine(Pens::Black, x+12, y+32, x+28, y+32); // вертикальный "ус" g->DrawLine(Pens::Black, x+20, y+22, x+20, y+26); // боковые "усы" g->DrawLine(Pens::Black, x+8, y+30, x+6, y+28); g->DrawLine(Pens::Black, x+32, y+30, x+34, y+28); } // обработка события Paint private: System::Void panel1_Paint(System::Object^ sender, System::Windows::Forms::PaintEventArgs^ e) { showPole(g, status); } // команда Новая игра private: System::Void новаяИграToolStripMenuItem_Click(System::Object^ sender, System::EventArgs^ e) { newGame(); showPole(g, status); } // Выбор в меню Справка команды Правила private: System::Void правилаToolStripMenuItem_Click(System::Object^ sender, System::EventArgs^ e) { Help::ShowHelp(this, /*helpProvider1->HelpNamespace*/ "saper.chm", "saper_02.htm"); } // Выбор в меню Справка команды О программе private: System::Void оПрограммеСаперToolStripMenuItem_Click(System::Object^ sender, System::EventArgs^ e) { Form2^ frm = gcnew Form2(); frm->ShowDialog(); } }; }
Модуль формы О программе (Form2.h):
// щелчок на URL-ссылке private: System::Void linkLabel1_Click(System::Object^ sender, System::EventArgs^ e) { String^ webRef = linkLabel1->Text; System::Diagnostics::Process::Start(webRef); }
Со следующего шага мы начнем рассматривать создание установщика.