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

Государственное образовательное учреждение

высшего профессионального образования

«Московский государственный технический университет

им. Н. Э. Баумана»

Калужский филиал

кафедра

«Системы автоматизированного проектирования»

Пояснительная записка

к курсовой работе

по дисциплине:

«Программирование на языке высокого уровня»

на тему:

«Генерирование псевдослучайных чисел на примере созданияигры “Сапер”»

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Калуга 2007


Содержание

Введение3

1.Исследовательская часть4

1.1.Генерированиепсевдослучайных чисел 

1.2.Целесообразностьвыбора языка 

2.Конструкторская часть  

2.1.Структура проекта.

2.2. Программнаяреализация основных элементов C#.

2.2.1.Классы      

2.2.2.Члены класса  

3.Технологическая часть  

3.1.Системныетребования  

3.2.Запуск и процессигры.

Заключение  

Литература  

Приложение  

/>Введение

Тема моей курсовой работы«игра “Тетрис”». В ходе выполнения работы были поставлены следующие цели:

¾       изучить основныеподходы при создании Windowsприложений;

¾       приобрести навыкиработы с 2D графикой в Windows приложениях в С#;

¾       исследоватьметоды генерации псевдослучайных чисел.

Задачей курсовой работыявляется разработка игры «Сапер» с расположением мин на основе несколькихметодов генерации случайных чисел.

Даная тема являетсяактуальной, так как в ходе разработки игры есть возможность изучить процесссоздания Windows приложений и работу с 2D графикой, а «генерация случайныхчисел — слишком важное дело, чтобы оставлять её на волю случая» (Джон фонНейман).


1.Исследовательская часть

1.1.Генерированиепсевдослучайных чисел

Для расстановки мин наигровом поле в игре «Сапер» необходимо случайным образом задать координатыклетки с миной. Для этого в программе используются различные методыгенерирования таких координат.

Генераторпсевдослучайных чисел (ГПСЧ)— алгоритм, генерирующий последовательность чисел, элементы которой почтинезависимы друг от друга и подчиняются заданному распределению.[1]

Современнаяинформатика широко использует псевдослучайные числа в самых разных приложениях— от метода Монте-Карло до криптографии. Генераторы псевдослучайных чиселшироко используются в имитационном моделировании.

Термин ГПСЧчасто используется для описания ГПСБ (PRBG) — генераторов псевдослучайных бит,а так же различных поточных шифров. Предназначение ГПСЧ — генерацияпоследовательностей чисел, которые невозможно отличить от случайных. Никакойдетерминированный алгоритм не может генерировать полностью случайные числа, атолько лишь аппроксимировать некоторые свойства случайных чисел.

Самые простыеаппаратные ГСЧ (АГСЧ) основаны на тех свойствах элементов электронных схем, скоторыми так долго и упорно боролись инженеры — схемотехники. Это свойство — собственные шумы электронного прибора.

В отдельныйподкласс АГСЧ стоит вынести разработки, в которых вместо дискретногоэлектронного компонента применяется куда более сложный источник естественнойслучайности. Например, помещенная в специальный футляр при полном отсутствиисвета ПЗС-матрица камеры приводится управляющей программой в наихудший режим,при котором шумовые характеристики максимальны и картина чистого, природногохаоса пригодна к дальнейшей обработке.

Второмуобширному классу АГСЧ лучше всего подойдет название «функциональный».Здесь в качестве «источника энтропии» используются фундаментальныефункциональные свойства электронных приборов, например счетчиковГейгера-Мюллера. Неприятной особенностью подобных устройств являетсянеобходимость применения радиоизотопных источников.

Третий классАГСЧ– это «фундаментальный» класс. Наиболее яркий представитель«фундаментальных» АГСЧ — оптический квантовый генератор случайныхчисел". Также существует устройство, в котором фундаментальные физическиепринципы, наносекундная синхронизация и самая современная электроника подчиненырешению самой утилитарной задачи — получению случайных чисел, обновляющихся 100тыс. раз в секунду.

Четвертыйкласс АГСЧ можно условно назвать «паразитнымперсонально-компьютерным». К их свойствам относятся прежде всего тепловыешумы и флуктуации в подсистеме аналогового ввода/вывода звукового адаптера.

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

Большинствопростых арифметических генераторов хотя и обладают большой скоростью, нострадают от многих серьёзных недостатков:

¾       Слишком короткийпериод/периоды

¾       Последовательныезначения не являются независимыми

¾       Некоторые биты«менее случайны», чем другие

¾       Неравномерноеодномерное распределение

¾       Обратимость

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

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

Данный алгоритм былпредложен Д. Х. Лемером в 1948 году. Применяется в простых случаях и необладает криптографической стойкостью. Используется в качестве стандартногогенератора многими компиляторами.

Этот алгоритм заключаетсяв итеративном применении формулы (1):

/>       (1)

где a > 0, c > 0, M > 0 — некоторые целочисленныеконстанты. Получаемая последовательность зависит от выбора стартового числа X0и при разных его значениях получаются различные последовательности случайныхчисел. В то же время, многие свойства последовательности Xjопределяются выбором коэффициентов в формуле и не зависят от выбора стартовогочисла. Ясно, что последовательность чисел, генерируемая таким алгоритмом,периодична с периодом, не превышающим m. При этом длина периода равна m тогда итолько тогда, когда:

1.        НОД (c, m) = 1(то есть c и m взаимно просты);

2.        a — 1 кратно p для всех простых p —делителей m;

3.        a — 1 кратно 4, если m кратно 4.

При реализации выгодновыбирать m = 2e, где e — число бит в машинном слове, поскольку этопозволяет избавиться от относительно медленной операции приведения по модулю.

Формула (2) для вычисленияnчлена последовательности, зная только 0-й

/>    (2)


Метод Фибоначчи с запаздываниями.

Особенности распределенияслучайных чисел, генерируемых линейным конгруэнтным алгоритмом, делаетневозможным их использование в статистических алгоритмах, требующих высокогоразрешения.[2]

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

Наибольшую популярностьфибоначчиевы датчики получили в связи с тем, что скорость выполненияарифметических операций с вещественными числами сравнялась со скоростьюцелочисленной арифметики, а фибоначчиевы датчики естественно реализуются ввещественной арифметике.

Один из широкораспространённых фибоначчиевых датчиков основан на следующей итеративнойформуле (3):

X(k) = \left\{\begin{matrix} X(k-a)-X(k-b), & \mbox{if } X(k-a)\geq X(k-b); \\X(k-a)-X(k-b)+1, & \mbox{if } X(k-a) < X(k-b);\end{matrix}\right. (3)

где X(k) — вещественныечисла из диапазона [0, 1),

a, b — целыеположительные числа, называемые лагами.

Для работы фибоначчиевудатчику требуется знать max(a, b) предыдущих сгенерированных случайных чисел.При программной реализации для хранения сгенерированных случайных чиселиспользуется конечная циклическая очередь на базе массива. Для стартафибоначчиевому датчику требуется max(a, b) случайных чисел, которые могут бытьсгенерированы простым конгруэнтным датчиком.

Рекомендуются следующиезначения: a = 55, b = 24; a = 17, b = 5;

a = 97, b = 33.

Алгоритм Блюма, Блюма и Шуба (Blum Blum Shub, BBS)

Предложен в 1986 годуЛенор и Мануэлем Блюм и Майклом Шубом.

BBS заключается вприменении формулы (4):

xn+1 = (xn)2modM    (4)

где M=p*q являетсяпроизведением двух больших простых p и q.

На каждом шаге алгоритмавыходные данные получаются из xn путём взятия либо бита чётности,либо одного или больше наименее значимых бит xn.

Два простых числа, p и q,должны быть оба сравнимы с 3 по модулю 4 и НОД(φ(p-1), φ(q-1))должен быть мал.

Интересной особенностьюэтого алгоритма является то, что для получения xn необязательновычислять все n — 1 предыдущих чисел, если известно начальное состояниегенератора x0и числа p и q. n-ное значение может быть вычислено«напрямую» используя формулу (5):

xn = x0(2 ^n) mod ((p-1)(q-1)) mod M  (5)

Вихрь Мерсенна (Mersenne twister)

Разработан в 1997японскими учёными Макото Мацумото и Такудзи Нисимура. Он обеспечивает быструюгенерацию высококачественных псевдослучайных чисел, так как изначально былразработан с учётом ошибок, найденных в других алгоритмах.

Существуют по меньшеймере два общих варианта алгоритма, различающихся только размеромиспользующегося простого числа Мерсенна. Новейший и наиболее распространённыйназывается Mersenne Twister MT 19937.

MT 19937 имеет следующиеожидаемые свойства:

1.        Он был разработанс целью иметь огромный период, размером 219937 − 1.

2.        Он имеет высокийпорядок пространственного эквираспространения.

3.        Он значительнобыстрее, чем все остальные генераторы, за исключением статистически-дефектныхгенераторов.

4.        Он статистическислучаен во всех выходных битах.

Генерирование случайных чисел с помощью класса Randomв С#.

Чтобысгенерировать последовательность псевдослучайных чисел, используется классRandom. Начало такой последовательности определяется некоторым начальнымчислом, которое автоматически предоставляется классом Random или задается явнымобразом.

Вклассе Random определены следующие два конструктора:

public Random()

public Random(int seed)

Спомощью первой версии конструктора создается объект класса Random, который длявычисления начального числа последовательности случайных чисел используетсистемное время. При использовании второй версии конструктора начальное числозадается в параметре seed.

КлассRandom (сокращено)

//Конструкторы

Random()

Random(int а);

//Методы экземпляра

int Next () ;

int Next(int макс_значение) ;

int Next(int мин_значение, int макс_значение) ;

doubleNextDouble() ;

Конструкторывозвращают случайные объекты, которые образуют последовательностьпсевдослучайных чисел. Методы Next возвращают следующее число впоследовательности, возможно, между заданными значениями. NextDouble возвращаетчисло в диапазоне от 0.0 до 1.0.

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

¾       более простоематематическое представление, а следовательно и программная реализация;

¾       возможностьполучения любого числа, располагая только значением стартового.

 1.2.Целесообразность выбора языка

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

1.        Возможностьсоздания Windows приложений.

2.        Созданиемаксимально возможного удобства в работе

3.        Поддержка другихязыков программирования и платформ

4.        Большоеколичество библиотек

5.        Простота изученияязыка на основе имеющихся знаний.

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

Сформулировав требования,нужно перейти к анализу существующих языков программирования.

Сотни имеющихся языковмогут быть подразделены на три общих типа: машинные, ассемблерные и языкивысокого уровня.

Машинные языки неудобныдля восприятия человеком. Машинные языки являются машинно-зависимыми,т.е. конкретный машинный язык может быть использован только с определённымтипом компьютера.

Для преобразованияпрограмм были разработаны программы-трансляторы, называемые ассемблерами.С появлением языков ассемблера использование компьютеров значительнорасширилось, однако всё ещё требовалось написание большого количестваинструкций даже для реализации решений простейших задач.

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

На практикепрограммисту-одиночке или небольшой рабочей группе придется использоватькакие-то мощные средства, вроде визуальных систем программирования (VisualBasic, C++Builder, С#, Delphi) или же универсальную среду разработки типаBorland C++ в сочетании с библиотекой классов, такой, как OWL или MFC. [3]

Бурное развитие вычислительнойтехники, потребность в эффективных средствах разработки программногообеспечения привели к появлению систем программирования, ориентированных на такназываемую «быструю разработку», среди которых можно выделить BorlandDelphi ,  Microsoft Visual Basic. С появлением Visual Basic программирование вWindows не становится более эффективным, но оно становится более простым (вбольшинстве случаев).

Если говорить о созданиипрограмм с интерфейсом Windows, то нельзя, конечно, не обойти вниманиемвизуальные средства программирования C++Builder. Несколько лет назад рядовомупрограммисту оставалось только мечтать о создании собственных программ,работающих в среде Windows, т. к. единственным средством разработки был BorlandC++ for Windows, явно ориентированный на профессионалов, обладающих серьезнымизнаниями и опытом. C++ Builder буквально навязывает программисту свойсобственный стиль программирования, при котором, даже при особом желании,перейти с C++ Builder на что-то другое уже не предоставляется возможным. С++ неподдерживает других языков программирования.

Delphi — это средабыстрой разработки, в которой в качестве языка программирования используетсяязык Delphi. Язык Delphi — строго типизированный объектно-ориентированный язык,в основе которого лежит хорошо знакомый программистам Object Pascal. BorlandDelphi 7 Studio позволяет создавать самые различные программы: от простейшиходнооконных приложений до программ управления распределенными базами. Delphi-не поддерживает других языков программирования, но способен поддерживатьразличные платформы.

Однако,при всем этом выбор падает на язык С#, входящий в VisualStudio .Net, так как он имеет ряд преимуществ, которые упрощаютпроцесс создания приложений.

C# создавался Microsoft, как основной язык для .NETFramework. Microsoft спроектировала C# таким образом, что бы С, С++ иJava-программисты смогли легко перейти на него. C# имеет корни в языках С, С++и Java, поэтому такой переход не должен вызвать затруднений.

Синтаксис у C# не такой сложный как у С++, поэтому егоизучение намного легче. Большинство операций, которые вы можете делать на С++,можно сделать и на C#, за исключением операций доступа к низкоуровневымфункциям (это все-таки можно сделать с помощью неуправляемого кода).

С# — первый язык, поддерживаемый версиями .NETFramework для других платформ.

C#имеет схожий с C стиль синтаксиса (для управляющих конструкций, блоков кода,описания сигнатуры методов и др.), много общего с Java (отсутствиемножественного наследования и шаблонов, наличие сборщика мусора) и Delphi(ориентированность на создание компонент), в то же время имеет и свой колорит.

C#объектно-ориентированный язык, как и вся платформа .NET[7].

ВC# представлена концепция пространств имен, аналогичная пакетам в Java. Этопозволяет иерархически структурировать систему типов, делая код намного болеепонятным и позволяя избежать проблем с именованием. Реализация структур кактипов, работа с которыми идет по значению, вместе с возможностью использоватьне только вложенные массивы (как в Java), но и многомерные позволяетоптимизировать производительность приложений.

Ввидуочень удобного объектно-ориентированного дизайна, C# является хорошим выборомдля быстрого конструирования различных компонентов.

Платформа .Net содержит множество важных служб:

1.     .Net предоставляет средства дляисполнения инструкций, содержащихся в программе, написанной на C#. Эта часть .Net называется средой исполнения.

2.        .Net помогает реализовать так называемуюсреду, безопасную к несоответствию типов данных.

3.        .Net освобождает программиста отутомительного и нередко приводящего к ошибкам процесса управления компьютернойпамятью, которая используется программой.

4.        .Net предоставляет безопасную средуисполнения.

5.        В состав .Net входят библиотека, содержащая массуготовых программных компонентов, которые можно использовать в собственныхпрограммах. Она экономит немало времени, так как  программист можетвоспользоваться готовыми фрагментами кода. Фактически, он повторно используеткод, созданный и тщательно  проверенный профессиональными программистами Microsoft.

6.        В .Net упрощена подготовка программы кисполнению.

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

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


2.Конструкторская часть2.1.Структура проекта.

Данный проект состоит изфайлов

Ниже представленоописание основных файлов:

¾       Form1.cs – файл, в котором содержится код, отвечающий за работуглавной формы программы;

¾       Form1.resx – файл, в котором содержится информация о графическомпредставлении главной формы «Сапер»;

¾       Form2.cs — файл, в котором содержится код, отвечающий за работу формынастроек игрового поля;

¾       Form2.resx – файл, в котором содержится информация о графическомпредставлении формы настроек игрового поля;

¾       AboutBox1.cs — файл, в котором содержится код, отвечающий за работу формы«О программе»;

¾       AboutBox1.resx – файл, в котором содержится информация о графическомпредставлении формы «О программе»;

¾       Справка.htm – HTML-страница, в которой содержится справка по игре;

¾       Мина.jpg –изображение мины на форме «О программе»

¾       Сапер.exe — закомпилированный файл программы, находящийся впапке debug, которая находится в папке bin

2.2. Программная реализация основных элементов C#.

Для его запусканеобходимо кликнуть кнопку Пуск, выбрать в пункте Все программы  \MicrosoftVisual Studio .NET 2005\MicrosoftVisualStudio.NET2005. Далее в запустившемся приложениикликнуть кнопку Open Project и используя проводник, выбрать файл Сапер.sln. Программа откроет приложение. Для изменения внешнеговида программы необходимо воспользоваться ярлыком Design. Можно добавить новые элементыформы, перетащив их из окна Toolbox.В моей работе это HelpProvider и MenuStrip при конструировании главнойформы, Label, TextBox и Buttonпри создании формы настроек игрового поля. Свойства компонентов можно изменить,зайдя в меню ViewPropertiesWindows или в кодепрограммы:

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

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 можно найти все события и дваждыщелкнув на одно из них, написать обработчик.


/>2.2.1.Классы

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

public partial class Form1: Form //главная форма программы

    {

………

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

       {

           InitializeComponent();

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

           MR = 10;

           MC = 10;

            NM = 10;

            W = 40;

            H = 40;

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

        }

………

    }

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

    {

………

publicForm2()//конструктор формы Настройки

       {

            InitializeComponent();

        }

………

    }

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

    {

………

publicAboutBox1()//конструктор формы О программе

       {

           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 Studio2005 для среды .NET Framework»;

        }

………

    }/>/>

2.2.2.Члены класса

Поля

Полем называется член-переменная,содержащий некоторое значение. В ООП поля иногда называют данными объекта.

Для классов

public partial class Form1: Form

public partial class Form2: Form

полями являются следующиепеременные:

privateint

           MR,//кол-во клеток по вертикали

           MC,//кол-во клеток по горизонтали

           NM,//кол-во мин

           W,//ширина клетки поля

           H;//высота клетки поля

privateint

           nMin,//кол-вонайденных мин

           nFlag;//кол-вопоставленных флагов

privateint status;/*отражает различные этапы работы программы:

                    0-начало игры,

                    1-игра,

                    2-конец игры*/

privateint[,] Pole;/*элемент массива задает клетку поля и принимает значения

                     0-8 -кол-во мин в соседних клетках,

                     9 -в клетке мина,

                      100-109-клетка открыта,

                     200-209 -в клетку поставлен флаг*/

Следует отметить, чтопеременная Pole хранит в себе ссылку на двумерный массив. Массивы в C# разделяются на дватипа: одномерные и многомерные.

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

Инициализация

Pole = new int[MR +2, MC + 2];

происходит в методе

privatevoid newGame(int r)

       {

        }

который будет рассмотрендалее.

Доступ к элементампроизводится с помощью оператора [ ], в котором индексы указываются череззапятую. Присвоение значений элементам присваивается в методе:

privatevoid newGame(int r)

       {

…………

           /*неотражаемым элементам массива минного поля присваиваем

             значение -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.

Методы, используемые вразработанном приложении и обеспечивающие процесс игры:

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

       {

…………

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

           int random = r;

           if (random ==1)

            {

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

            }

            if (random == 2)

            {

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

            }

            if (random == 3)

            {

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

            }

……………

       }

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

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

       }

privatevoid 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) modm

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

       }

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

…………

       }

privatevoid 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(objectsender, EventArgs e) //щелчок на пункте меню Новая игра

       {

           this.newGame(1);

           this.Invalidate();

       }

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

private void минToolStripMenuItem_Click(objectsender, EventArgs e)

        {

        }

private void минToolStripMenuItem1_Click(objectsender, EventArgs e)

        {

        }

private void минToolStripMenuItem2_Click(objectsender, EventArgs e)

        {

        }

private void минToolStripMenuItem3_Click(objectsender, EventArgs e)

        {

        }

private void минToolStripMenuItem4_Click(objectsender, EventArgs e)

        {

        }

private void минToolStripMenuItem5_Click(objectsender, EventArgs e)

        {

        }

private void особыеToolStripMenuItem_Click(objectsender, 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(objectsender, EventArgs e)

        {

        }

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

        {

        }

private void выходToolStripMenuItem_Click(objectsender, EventArgs e)

//щелчок на пункте менюВыход

       {

           this.Close();

        }

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

        {

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

        }

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

       {

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

О программе

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

       }

Отдельноговнимания заслуживает событие Paint, которое сообщаетпрограмме о необходимости отобразить информацию в окне. Paint информирует программу о том, что вся клиентская область илиее часть недействительна(invalid) и требуетперерисовки. Когда форма только что создана, вся клиентская областьнедействительна, так как программа еще ничего в ней не показывала. В программепроисходит первое событие Paint, сообщающее о необходимости показатьчто-нибудь в клиентской области. Когда окна перемещаются по экрану, так что ониперекрывают друг друга, Windows не запоминает вид клиентской области, закрытойдругим окном. Потом, когда клиентская область снова открывается, программадолжна восстановить ее вид. Поэтому в ней и происходит событие Paint. Когда окно программы после свертывания возвращается внормальное состояние, в ней также происходит событие Paint.

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

Paint

        {

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

        }


3.Технологическая часть

3.1.Системные требования

Для запуска игры оптимальныследующие системные требования:

1.        Процессор Pentium 3.

2.        Частотапроцессора 800 Мгц.

3.        256 Мб ОЗУ.

4.        Видеоадаптер Radeon 9600 и аналогичные.

5.        Visual Studio 2003 или 2005.

6.        Операционнаясистема Windows 2000 и более поздние версии

3.2.Запуски процесс игры.

Для запуска игрынеобходимо выполнить следующие действия:

1.Вставьте диск «Курсоваяработа Темерева К., гр. САПР-31. Игра “Сапер”» в дисковод.

2.

— нажмите кнопку Пуск

— двойным щелчком левойкнопки мыши откройте Мой компьютер

— двойным щелчкомоткройте

3.На экране появится окно(см. рис.3.1)

4.Если на компьютере неустановлена платформа .NET нужнооткрыть папку Microsoft .NET Framework 3.0 и двойным щелчком запуститьустановочный файл dotnetfx3.exe

5.Запуск игрыосуществляется двойным щелчком на файле

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

Чтобыначать игру в меню Игранужно выбрать команду Новая игра (рис.3.2).

Игрок имеет возможностьоткрыть любую ячейку, щелкнув ее левой кнопкой мыши. Если открываемая ячейкасодержит мину, игра завершается.

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

Чтобы пометить ячейку, вкоторой по мнению игрока находится мина, нужно щелкнуть ее правой кнопкой мыши.

Чтобы настроить игровоеполе в меню Игра следует выбрать команду Игровое поле (рис.3.2), адалее:

¾       выбрать размерполя10 * 10 или20 *20, затем количество мин10, 15, 20, 40,60

или выбратькоманду Особые и задать размер поля, указав количество клеток погоризонтали и вертикали, а также ввести число мин. (рис.3.3)

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

¾       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(), newFont(«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(newRectangle(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(objectsender, EventArgs e)//щелчок на пункте меню Справка

        {

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

        }

        private void Сапер_MouseDown(objectsender, 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(objectsender, EventArgs e)

        {

            MR = 10;

            MC = 10;

            NM = 10;

            W = 40;

            H = 40;

            this.newGame(1);

            this.Invalidate();

        }

        private void минToolStripMenuItem1_Click(objectsender, EventArgs e)

        {

            MR = 10;

            MC = 10;

            NM = 15;

            W = 40;

            H = 40;

            this.newGame(1);

            this.Invalidate();

        }

        private void минToolStripMenuItem2_Click(objectsender, EventArgs e)

        {

            MR = 10;

            MC = 10;

            NM = 20;

            W = 40;

            H = 40;

            this.newGame(1);

            this.Invalidate();

        }

        private void минToolStripMenuItem3_Click(objectsender, EventArgs e)

        {

            MR = 20;

            MC = 20;

            NM = 20;

            W = 30;

            H = 30;

            this.newGame(1);

            this.Invalidate();

        }

        private void минToolStripMenuItem4_Click(objectsender, EventArgs e)

        {

            MR = 20;

            MC = 20;

            NM = 40;

            W = 30;

            H = 30;

            this.newGame(1);

            this.Invalidate();

        }

        private void минToolStripMenuItem5_Click(objectsender, 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(objectsender, 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(objectsender, EventArgs e)//щелчок на пункте меню Выход

        {

            this.Close();

        }

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

       {

           this.newGame(1);

            this.Invalidate();

       }

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

       private voidrandomToolStripMenuItem_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(objectsender, 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 productinformation from the assembly information.

            //  Change assembly information settings for your applicationthrough either:

            //  — Project->Properties->Application->AssemblyInformation

            //  — 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 Studio2005 для платформы .NET Framework»;

        }

    }

еще рефераты
Еще работы по информатике, программированию