Рефераты. Генерирование псевдослучайных чисел на примере создания игры "Сапер"

Чтобы изменить способ расстановки мин на поле, в меню Игра нужно выбрать команду Способ расстановки мин, а далее:

ѕ Random

ѕ Линейный конгруэнтный метод

ѕ Алгоритм Блюма, Блюма и Шуба.

Чтобы найти инструкцию по игре, нужно выбрать в меню Справка, а для ознакомления с информацией о приложении выбрать

О программе

Заключение

В ходе выполнения курсовой работы были рассмотрены и проанализированы основные методы генерирования псевдослучайных чисел: линейный конгруэнтный метод, метод Фибоначчи с запаздываниями, алгоритм Блюма, Блюма и Шуба, Вихрь Мерсенна.

Для реализации в курсовой работе были выбраны: метод, основанный на использовании системного класса Random, линейный конгруэнтный метод и алгоритм Блюма, Блюма и Шуба в связи с их достаточно простым математическим представлением и возможностью получения любого числа, располагая только значением стартового.

Выдвинуты требования к функциональности приложения, исходя из специфики игры «Сапер» и сформулированы необходимые характеристики того языка программирования, с помощью которого предполагалось выполнить поставленную задачи, проанализированы преимущества и недостатки разных языков и сделан выбор в пользу языка С#.

В конструкторской части были использованы новые визуальные компоненты. На основе имеющихся и полученных знаний об основных структурах языка С# реализованы алгоритм игры и графический интерфейс.

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

Задание на курсовую работу было выполнено полностью.

Литература

1. Кнут Д. Искусство программирования, т. 2. Получисленные методы -М.: «Вильямс», 2007. -- С. 832.

2. Зубинский А. В поисках случайности. - Компьютерное Обозрение,

29 (2003)

3. Шилдг Г. Полный справочник по С#/Пер. с англ. -- М. : Издательский дом "Вильямc", 2004. -- 752 с.

4. Ватсон К. С#. - М.: Издательство "Лори", 2005

5. Рихтер Дж. Программирование на платформе Microsoft .NET Framework. - М.: Издательско-торговый дом “Русская Редакция”, 2003.-464 с.

6. Фролов А. В. Фролов Г. В. Язык С#. Самоучитель. - М: Издательство «ДИАЛОГ-МИФИ», 2003. - 560 с.

Приложение 1

Код программы

public partial class Form1 : 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 -в клетку поставлен флаг*/

private void newGame(int r)/*метод, запускающий новую игру;

значение формального параметра r указывает на способ расстановки мин

1-используя системный класс Random,

2-используя линейный конгруэнтный метод,

3-используя алгоритм Блюма, Блюма и Шуба*/

{

this.ClientSize = new Size(W * MC + 1, H * MR + 1+25);/*устанавливаем размер формы в соответствии

с размером игрового поля*/

int row, col;//индексы клетки

int k;//кол-во мин в соседних клетках

Pole = new int[MR + 2, MC + 2];//инициализация массива минного поля

/*неотражаемым элементам массива минного поля присваиваем значение -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;

}

}

//метод расстановки мин

int random = r;

if (random == 1)

{

this.Rand();//вызов метода Rand()

}

if (random == 2)

{

this.Lin();//вызов метода Lin()

}

if (random == 3)

{

this.BBS();//вызов метода BBS()

}

//для каждой клетки вычисляем кол-во мин в соседних клетках

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;//нет поставленных флагов

}

}

}

//способы расстановки мин

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()//метод, основанный на использовании линейного конгруэнтного метода

{

int n = 0;

int row, 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(Graphics g, int row, int col, int status)

}

}

}

private void kletka(Graphics g, int row, int col, int status)//метод,выводящий содержимое клетки

{

//координаты области вывода

int x = (col - 1) * W + 1, y = (row - 1) * H + 1 + 25;

//неоткрытые клетки - серые

if (Pole[row, col] < 100)

{

g.FillRectangle(SystemBrushes.ControlLight, x - 1, y - 1, x + W, y + H);

}

//открытые или помеченные клетки

if (Pole[row, col] >= 100)

{

//открываем клетку, открытые-белые

if (Pole[row, col] != 109)

g.FillRectangle(Brushes.White, x - 1, y - 1, x + W, y + H);

//подрыв на мине, клетка красная

else

g.FillRectangle(Brushes.Red, x - 1, y - 1, x + W, y + H);

//если рядом с клеткой есть мины, подписываем их кол-во

if ((Pole[row, col] >= 101) && (Pole[row, col] <= 108))

g.DrawString((Pole[row, col] - 100).ToString(), new Font("Tahoma", 20, FontStyle.Bold), Brushes.Blue, x + 3, y + 2);

}

// в клетке флаг

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)//метод,открывающий текущую и все соседние клетки, в которых нет мин

{

//координаты области вывода

int x = (col - 1) * W + 1, y = (row - 1) * H + 1 + 25;

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

}

else

if ((Pole[row, col] < 100) && (Pole[row, col] != -3))

{

Pole[row, col] += 100;

//отобразить содержимое клетки

this.Invalidate(new Rectangle(x, y, W, H));

}

}

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

}

public Form1()//конструктор главной формы

{

InitializeComponent();

//присваиваем начальные значения полям

MR = 10;

MC = 10;

NM = 10;

W = 40;

H = 40;

this.newGame(1);//вызов метода newGame(int r)

}

private void Form1_Paint(object sender, PaintEventArgs e)//обработчик события Paint

{

this.showPole(e.Graphics, status);//вызов метода showPole(Graphics g, int status)

}

private void справкаToolStripMenuItem_Click(object sender, EventArgs e)//щелчок на пункте меню Справка

{

Help.ShowHelp(this, this.helpProvider1.HelpNamespace);//вызов файла справки

}

private void Сапер_MouseDown(object sender, MouseEventArgs e)//нажатие кнопки мыши на игровом поле

{

//если игра завершена, ничего не происходит

if (status == 2)

return;

//первый щелчок

if (status == 0)

status = 1;

//преобразуем координаты мыши в индексы клетки, в которой был сделан щелчок

int row = (int)((e.Y - 25)/ H) + 1, col = (int)(e.X / W) + 1;

//координаты области вывода

int x = (col - 1) * W + 1, y = (row - 1) * H + 1 + 25;

//щелчок левой кнопки мыши

if (e.Button == MouseButtons.Left)

{

//открыта клетка, в которой есть мина

if (Pole[row, col] == 9)

{

Pole[row, col] += 100;

status = 2;//игра закончена

this.Invalidate();//перерисовать форму

}

else

{

if (Pole[row, col] < 9)

this.open(row, col);

}

}

//щелчок правой кнопки мыши

if (e.Button == 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.Invalidate();//перерисовать форму

}

else

this.Invalidate(new Rectangle(x, y, W, H));//перерисовать клетку

}

else

{

//в клетке был флаг, убираем его

if (Pole[row, col] >= 200)

{

nFlag -= 1;

Pole[row, col] -= 200;

this.Invalidate(new Rectangle(x, y, W, H));//перерисовать клетку

}

}

}

}

//обработчики щелчков на пунктах меню, в которых указывается размер поля и кол-во мин

private void минToolStripMenuItem_Click(object sender, EventArgs e)

{

MR = 10;

MC = 10;

NM = 10;

W = 40;

H = 40;

this.newGame(1);

this.Invalidate();

}

private void минToolStripMenuItem1_Click(object sender, EventArgs e)

{

MR = 10;

MC = 10;

NM = 15;

W = 40;

H = 40;

this.newGame(1);

this.Invalidate();

}

private void минToolStripMenuItem2_Click(object sender, EventArgs e)

{

MR = 10;

MC = 10;

NM = 20;

W = 40;

H = 40;

this.newGame(1);

this.Invalidate();

}

private void минToolStripMenuItem3_Click(object sender, EventArgs e)

{

MR = 20;

MC = 20;

NM = 20;

W = 30;

H = 30;

this.newGame(1);

this.Invalidate();

}

private void минToolStripMenuItem4_Click(object sender, EventArgs e)

{

MR = 20;

MC = 20;

NM = 40;

W = 30;

H = 30;

this.newGame(1);

this.Invalidate();

}

private void минToolStripMenuItem5_Click(object sender, EventArgs e)

{

MR = 20;

MC = 20;

NM = 60;

W = 30;

H = 30;

this.newGame(1);

this.Invalidate();

}

private void оПрограммеToolStripMenuItem_Click(object sender, EventArgs e)//щелчок на пункте меню О программе

{

AboutBox1 saper = new AboutBox1();//создание экземпляра формы О программе

saper.ShowDialog();//появление формы О программе

}

private void особыеToolStripMenuItem_Click(object sender, EventArgs e)//щелчок на пункте меню Особые

{

Form2 settings = new Form2();//создание экземпляра формы Настройки

settings.ShowDialog();//появление формы Настройки

//присваиваем значения полям на основе введенных пользователем на форме Настройки

MR = settings.MR;

MC = settings.MC;

NM = settings.NM;

W = 30;

H = 30;

this.newGame(1);

this.Invalidate();

}

private void выходToolStripMenuItem_Click(object sender, EventArgs e)//щелчок на пункте меню Выход

{

this.Close();

}

private void новаяИграToolStripMenuItem1_Click(object sender, EventArgs e)//щелчок на пункте меню Новая игра

{

this.newGame(1);

this.Invalidate();

}

//обработчики щелчков на пунктах меню, в которых указывается способ расстановки мин

private void randomToolStripMenuItem_Click(object sender, EventArgs e)

{

this.newGame(1);

this.Invalidate();

}

private void линейныйКонгруентныйМеоToolStripMenuItem_Click(object sender, EventArgs e)

{

this.newGame(2);

this.Invalidate();

}

private void алгоритмToolStripMenuItem_Click(object sender, EventArgs e)

{

this.newGame(3);

this.Invalidate();

}

}

public partial class Form2 : Form //форма настроек игрового поля

{

public int MR,MC,NM;

public Form2()//конструктор формы настроек поля

{

InitializeComponent();

}

private void button1_Click(object sender, EventArgs e)//нажатие кнопки ОК

{

// не все текстовые поля заполнены, выводится предупреждение

if (((textBox1.Text == "") || (textBox2.Text == "")) || (textBox3.Text == ""))

{

MessageBox.Show("Заполните все поля!");

}

// все текстовые поля заполнены, задаются кол-ва клеток и мин

else

{

MR = Convert.ToInt32(textBox1.Text);

MC = Convert.ToInt32(textBox2.Text);

NM = Convert.ToInt32(textBox3.Text);

this.Close();

}

}

}

partial class AboutBox1 : Form //форма «О программе»

{

public AboutBox1()//конструктор формы «О программе»

{

InitializeComponent();

// Initialize the AboutBox to display the product information from the assembly information.

// Change assembly information settings for your application through either:

// - Project->Properties->Application->Assembly Information

// - AssemblyInfo.cs

//задается текст компонентов формы О программе

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";

}

}

Страницы: 1, 2, 3, 4, 5



2012 © Все права защищены
При использовании материалов активная ссылка на источник обязательна.