//задается текст компонентов формы О программе
this.Text = String.Format("Опрограмме");
this.labelProductName.Text = "Cапер";
this.labelVersion.Text = String.Format("Версия {0}", AssemblyVersion);
this.labelCopyright.Text = "АвторТемеревКирилл";
this.labelCompanyName.Text = "КФМГТУим.Н.Э.Баумана, группаСАПР-31";
this.textBoxDescription.Text ="Программасозданав Microsoft Visual Studio
Щелкнув значок Молния в меню Properties можно найти все события и дважды щелкнув на одно из них, написать обработчик.
Следует отметить, что любая форма, являющаяся основным элементом пользовательского интерфейса и основой для построения приложения, одновременно и класс, поэтому удается создавать экземпляры форм и порождать одни формы от других. В рассматриваемой программе присутствуют следующие классы, соответствующие формам Windows приложения.
public partial class Form1 : Form //главнаяформапрограммы
{
………
public Form1() //конструктор главной формы
{
InitializeComponent();
//присваиваем начальные значения полям
MR = 10;
MC = 10;
NM = 10;
W = 40;
H = 40;
this.newGame(1);//вызовметода newGame(int r)
}
………
}
public partial class Form2 : Form //форманастроекигровогополя
{
………
public Form2()//конструктор формы Настройки
{
InitializeComponent();
}
………
}
partial class AboutBox1 : Form //форма «Опрограмме»
{
………
public AboutBox1()//конструктор формы О программе
{
InitializeComponent();
//задается текст компонентов формы О программе
this.Text = String.Format("Опрограмме");
this.labelProductName.Text = "Cапер";
this.labelVersion.Text = String.Format ("Версия {0}", AssemblyVersion);
this.labelCopyright.Text = "АвторТемеревКирилл";
this.labelCompanyName.Text = "КФМГТУим.Н.Э.Баумана, группаСАПР-31";
this.textBoxDescription.Text ="Программасозданав Microsoft Visual Studio 2005 длясреды .NET Framework";
}
………
2.2.2.Члены класса
Поля
Полем называется член-переменная, содержащий некоторое значение. В ООП поля иногда называют данными объекта.
Для классов
publicpartialclassForm1 : Form
publicpartialclassForm2 : Form
полями являются следующие переменные:
private int
MR,//кол-во клеток по вертикали
MC,//кол-во клеток по горизонтали
NM,//кол-во мин
W,//ширина клетки поля
H;//высота клетки поля
private int
nMin,//кол-во найденных мин
nFlag;//кол-во поставленных флагов
private int status;/*отражает различные этапы работы программы:
0-начало игры,
1-игра,
2-конец игры*/
private int[,] Pole;/*элемент массива задает клетку поля и принимает значения
0-8 -кол-во мин в соседних клетках,
9 -в клетке мина,
100-109 -клетка открыта,
200-209 -в клетку поставлен флаг*/
Следует отметить, что переменная Pole хранит в себе ссылку на двумерный массив. Массивы в C# разделяются на два типа: одномерные и многомерные.
Элементы многомерных массивов идентифицируются набором индексов - "координат" в многомерном пространстве. Каждое измерение имеет свою размерность, не зависящую от других.
Инициализация
Pole = newint[MR + 2, MC + 2];
происходит в методе
privatevoidnewGame(intr)
{
}
который будет рассмотрен далее.
Доступ к элементам производится с помощью оператора [ ], в котором индексы указываются через запятую. Присвоение значений элементам присваивается в методе:
privatevoidnewGame(intr)
{
…………
/*неотражаемым элементам массива минного поля присваиваем
значение -3 для завершения процесса открытия клеток*/
for (row = 0; row <= MR + 1; row++)
{
Pole[row, 0] = -3;
Pole[row, MC + 1] = -3;
}
for (col = 0; col <= MC + 1; col++)
{
Pole[0, col] = -3;
Pole[MR + 1, col] = -3;
}
//обнуление элементов массива минного поля
for (row = 1; row <= MR; row++)
{
for (col = 1; col <= MC; col++)
{
Pole[row, col] = 0;
}
}
………
}
а также в других методах.
Методы
Методом называется реальный код, воздействующий на данные объекта (или поля). При объявлении методов используется конструкция вида:
<модиф_дост><тип_возвр_знач><идент_метода>(<формальн_парам>opt)
{
<тело_метода>
}
Метод в процессе своей работы может не только изменять поля объекта, но и вычислять некоторые дополнительные значения. Если возвращать значения не нужно, то в качестве типа возвращаемого значения указывается void.
Методы, используемые в разработанном приложении и обеспечивающие процесс игры:
private void newGame(int r)//метод, запускающий новую игру
{
…………
//выбор метода расстановки мин
intrandom = r;
if (random == 1)
{
this.Rand();//вызовметода Rand()
}
if (random == 2)
{
this.Lin();//вызовметода Lin()
}
if (random == 3)
{
this.BBS();//вызовметода BBS()
}
……………
}
//способы расстановки мин
private void Rand()//метод, основанный на использовании класса Random
{
int n = 0;//кол-во поставленных мин
int row, col;
Random rnd = new 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);
}
private void Lin()//метод, основанный на использовании линейного
конгруэнтного метода
{
intn = 0;
introw, col;
double a = Convert.ToInt64(Math.Exp((double)5 * Math.Log(7))),
m = Convert.ToInt64(Math.Exp((double)31 * Math.Log(2))) - 1;
int x = 27011989, c = 19;
//расстановка мин
do
{
//для нахождения пвевдослучайного числа Х используется
формула x(k+1)=(a * x(k) + c) mod m
x = (int)((a * x + c) % m);
//находится пвевдослучайный индекс клетки на [0,MR]
row =Convert.ToInt32( Math.Ceiling((double) MR * x / (m-1)));
x = (int)((a * x + c) % m);
//находится пвевдослучайный индекс клетки на [0,MС]
col = Convert.ToInt32(Math.Ceiling((double)MC * x / (m-1)));
if (Pole[row, col] != 9)
{
Pole[row, col] = 9;
n++;
}
}
while (n != NM);
}
private void BBS()//метод, основанный на использовании алгоритма Блюма, Блюма
иШуба
{
int n = 0;
int row, col;
int x = 2701;
int p=2047,q=8191;
int M = p * q;
//расстановка мин
do
{
//для нахождения пвевдослучайного числа Х используется
формула x(k+1)=(x(k)^2) mod m
x = Math.Abs((int)((x * x) % M));
//находится пвевдослучайный индекс клетки на [0,MR]
row = Convert.ToInt32(Math.Ceiling((double)MR * x / (M-1)));
x = Math.Abs((int)((x * x) % M));
//находится пвевдослучайный индекс клетки на [0,MС]
col = Convert.ToInt32(Math.Ceiling((double)MC * x / (M-1)));
if (Pole[row, col] != 9)
{
Pole[row, col] = 9;
n++;
}
}
while (n != NM);
}
private 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);//вызовметода kletka()
}
}
}
private void kletka(Graphics g, int row, int col, int status)
//метод,выводящий содержимое клетки
{
…………
// в клетке флаг
if (Pole[row, col] >= 200)
this.flag(g, x, y);
//отрисовываемграницыклетки
g.DrawRectangle(Pens.Black, x - 1, y - 1, x + W, y + H);
// если игра завершена (status=2),показываем мины
if ((status == 2) && ((Pole[row, col] % 10) == 9))
this.mina(g, x, y);
…………
}
private void open(int row, int col)//метод,открывающий текущую и все соседние
клетки, в которых нет мин
{
…………
//рекурсивный процесс открытия всей пустых соседих клеток
if (Pole[row, col] == 0)
{
Pole[row, col] = 100;
//отобразитьсодержимоеклетки
this.Invalidate(new Rectangle(x, y, W, H));
//открыть примыкающие клетки слева, справа, сверху, снизу
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);
}
…………
}
а также два метода, основанных на работе с графикой:
private 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);
}
private void flag(Graphics g, int x, int y)//метод,рисующийфлаг
{
Point[] p = new Point[3];
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[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);
}
События
Событие вызывает исполнение некоторого фрагмента кода. События — неотъемлемая часть программирования для Microsoft Windows. Например, события возникают при движении мыши, щелчке или изменении размеров окна. Важнейшую роль играет обработчики событий— методы, исполняемые при генерации событий:
private void Сапер_MouseDown(object sender, MouseEventArgs e)//нажатиекнопки
мышинаигровомполе
{
}
private void новаяИграToolStripMenuItem1_Click(object sender, EventArgs e) //щелчокнапунктеменюНовая игра
{
this.newGame(1);
this.Invalidate();
}
//обработчики щелчков на пунктах меню, в которых указывается размер поля и кол-во мин
private void минToolStripMenuItem_Click(object sender, EventArgs e)
{
}
private void минToolStripMenuItem1_Click(object sender, EventArgs e)
{
}
private void минToolStripMenuItem2_Click(object sender, EventArgs e)
{
}
private void минToolStripMenuItem3_Click(object sender, EventArgs e)
{
}
private void минToolStripMenuItem4_Click(object sender, EventArgs e)
{
}
private void минToolStripMenuItem5_Click(object sender, EventArgs e)
{
}
private void особыеToolStripMenuItem_Click(object sender, EventArgs e) //щелчокнапунктеменюОсобые
{
Настройки settings = new Настройки();//создание экземпляра формы
Настройки
settings.ShowDialog();//появление формы Настройки
//присваиваем значения полям на основе введенных пользователем на
форме Настройки
MR = settings.MR;
MC = settings.MC;
NM = settings.NM;
W = 30;
H = 30;
this.newGame(1);
this.Invalidate();
}
//обработчики щелчков на пунктах меню, в которых указывается способ расстановки мин
private void randomToolStripMenuItem_Click(object sender, EventArgs e)
{
}
private void инейныйКонгруэнтныйМеоToolStripMenuItem_Click(object sender, EventArgs e)