Разработка программы для игры Тетрис

3





МИНИСТЕРСТВО ОБРАЗОВАНИЯ И НАУКИ РОССИЙСКОЙ ФЕДЕРАЦИИ

ФЕДЕРАЛЬНОЕ АГЕНТСТВО ПО ОБРАЗОВАНИЮ

БРЯНСКИЙ ГОСУДАРСТВЕННЫЙ ТЕХНИЧЕСКИЙ

УНИВЕРСИТЕТ

Кафедра "Компьютерные технологии и системы"

Дисциплина "Языки и системы программирования"













КУРСОВАЯ РАБОТА

Разработка программы для игры "Тетрис"









Руководитель

к. т. н., доц.

Студент гр.08-ПРО













БРЯНСК 2010


Оглавление

	

	Задание на курсовую работу

	Введение

	1. Конструкторский раздел

	1.1 Обоснование необходимости разработки

	1.2 Обоснование и описание метода алгоритма

	1.2.1 Математическая часть алгоритма

	1.2.2 Графическая часть алгоритма

	2. Технологический раздел

	2.1 Выбор языка и среды программирования

	2.2 Блок-схема программы

	2.3 Вводимые и выводимые данные

	2.4 Разработка и отладка текста программы

	2.5 Разработка интерфейса пользователя

	2.6 Тестирование программы

	3. Руководство пользователя

	3.1 Программно-аппаратные требования

	3.2 Порядок работы с программой

	Заключение

	Список использованной литературы

	Приложения

	


Задание на курсовую работу 

	

По дисциплине "Языки и системы программирования"

	Студент Шора Р.В. Группа 08-ПРО

	Тема: Разработка программы для игры "Тетрис"

	Техническое задание.

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

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

	Руководитель к. т. н., доц. Рощин С.М.


Введение

	

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

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

	История игры Тетрис начинается в июне 1985 года. Тетрис был изобретен Алексеем Пажитновым, а затем был интегрирован на ПК IBM Вадимом Герасимовым. После чего ига Тетрис начала распространяться по всей Москве, а затем уже и по всему миру. Сначала она была доставлена в Венгрию, где венгерские программисты интегрировали Тетрис для Apple II и Commodore 64.

	Игра была замечена в мире, и несколько представителей крупных компаний, обращались к автору Тетриса, чтобы купить права на распространение игры. Алексей подписывает контракт с Mirrorsoft UK и Spectrum Holobyte, предоставляя им права на компьютерным версии Тетрис. После того, как первые копии Тетриса для домашних компьютеров были преданны, игра приобрела популярность среди населения и стала самой продаваемой компьютерной игрой в Англии и США в 1988 году.

	Существует множество способов реализации данной программы. Их можно разделить по функциональности:

		математическое описание движений фигур;

		графическое отображение движений фигур;

	В математической части рассматриваются основные принципы и законы движений фигур. Это самая важная часть программы. От неё зависит правильная работоспособность программы. Для её реализации можно использовать различные алгоритмы. Например описать движение фигуры двумя линейными функциями. Одна будет отвечать за расположение фигуры по горизонтали, другая по вертикале. Меняя за определенные промежутки времени значения переменных этих функций, будет меняться положение фигуры на плоскости. Третья функция будет отвечать за очистку полностью заполненных горизонталей. Основными недостатками этого способа является объявление большого числа переменных, отвечающих за описание уже упавших фигур, и создание большого числа дополнительных функций, отвечающих за поворот фигур вокруг своей оси.

	Другой способ математического описания движения фигур и заполнения поля тетриса - создание двумерной матрицы n*k. Через определенный промежуток времени будет изменяться значения, соответствующие положению фигур на плоскости и уже упавшим фигурам. Т.е. значение матрицы расположенное на n-ой строке и в k-ом столбце, будет соответствовать части фигуры расположенной на n-ой горизонтали и k-ой вертикали.

	Приведенные выше способы не являются единственными. Они лишь наиболее популярны в реализации программы "Тетрис" среди программистов.

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

	Ещё один способ графического отображения фигур и поля тетриса - использование готовых элементов языка программирования. Наиболее часто для этих целей используют таблицы. Изменяя цвет ячеек таблицы через определенные промежутки времени можно отобразить на экране движение фигур и заполненные области поля. Также возможно использование таких элементов, как кнопки, области для надписей (Label). Изменяя их цвет, также можно отобразить движение фигур и заполненные области. Но у такого способа есть огромный минус - объявление большого числа таких элементов.

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

	При разработки программы для игры Тетрис был использовал объектно-ориентированный язык программирования Visual C#. Математическая часть программы была создана с помощью двумерной матрицы. Графическое отображение было реализовано с помощью графических возможностей языка Visual C#.


1. Конструкторский раздел



1.1 Обоснование необходимости разработки



	В разделе "Введение" данной курсовой работы была приведена краткая история игры "Тетрис". Как видно этой компьютерной игре более 25 лет. Все изученные мной примеры этой игры написаны на довольно старых языках программирования (например Basic, Pascal). В таких играх был достаточно недружественный интерфейс пользователя, слабое графической отображение (достаточно резкие цвета, минимальная цветовая палитра) (Рис.1).

	

	

	Рис. 1. Тетрис на Basic

	

	Основываясь на выше изложенных фактах было решено создать программу игры "Тетрис".

	

1.2 Обоснование и описание метода алгоритма

	

	При разработке программы игры "Тетрис" для описания математической части алгоритма был использован двумерный массив, размерностью 24*15. Для создания графической части программы использовались графические возможности языка C#.


1.2.1 Математическая часть алгоритма

	Массив - это индексированный набор объектов одного типа. В языке С# массивы несколько отличаются от массивов в C++ и других языках, поскольку они являются объектами, что наделяет их полезными методами и свойствами. В С# определен синтаксис объявления объектов типа Array. Однако фактически создается объект типа System. Array. Таким образом, С# предоставляет программисту идеальные условия: за простым синтаксисом в стиле С кроется объявление класса, дающее экземплярам массива доступ к методам и свойствам класса System. Array.

	В создании алгоритма использовался массив как математический аналог поля "Тетриса". Каждая ячейка массива соответствует определенной области поля игры. Каждая область поля игры может быть заполнена фигурой или быть пустой. Соответственно, каждая область поля может принимать два значения. Для этих целей можно использовать логические переменные. Каждая фигура имеет определенную форму и занимает несколько областей поля игры. Следовательно в массиве, ячейки, соответствующие заполненным областям поля, будут иметь логическое значение true. Для ячеек соответствующих пустым областям будет присвоено логическое значение false. Каждая горизонталь поля тетриса соответствует строке двумерного массива, а вертикаль - столбцу. Движение фигур производится через равные промежутки времени, т. е происходит повторение алгоритма через равные промежутки времени. Равные промежутки времени можно обеспечить с помощью обсчета ресурсоёмкого алгоритма (например вычисление ряда Фибоначчи) или использовать элемент языка С# таймер (который был использован в данной программе). Каждый тик таймера будет происходить повторение алгоритма движения фигуры. Это представлено как последовательное изменение значений в ячейках массива.

	Чтобы игра была работоспособной, необходимо каждой ячейки массива каждый тик таймера присваивать значения, соответствующие областям поля. Т.к. количество ячеек велико (их 360), удобно было использовать циклические конструкции. Это позволило сократить программный код и количество ошибок в нем. Для этих целей был использован оператор for (Листинг 1).

	Краткосрочной целью игры тетрис является полное заполнение фигурами горизонтали для последующей ее очистки и получении очков. Для этого необходимо было внести в программу функцию проверки заполнености горизонтали. Для массива это представляется как проверка ячеек каждой строки на одинаковость значений. данную задачу решает условная конструкция. В данной работе был использован оператор if (Листинг 1).

	Математическая часть алгоритма строится на минимальном числе элементов: двумерный массив, таймер, логическая переменная, циклическая конструкция и условная конструкция (Листинг 1). Синтаксис записи этих элементов в языке C# прост, что делает алгоритм достаточно простым.

	

1.2.2 Графическая часть алгоритма

	GDH+ - интерфейс графических устройств. Приложения с графикой, игры, Computer Aided Design/Computer Aided Manufacture (CAD/CAM - проектирование/производство с помощью компьютера), программы для рисования, для создания графиков и многие другие типы приложений требуют от разработчиков написания кода для работы с графикой. Использование создаваемых пользователем управляющих элементов также предполагает работу с графикой. Посредством своей библиотеки классов компания Microsoft сделала написание кода для работы с графикой как никогда простым.

	Возможности GDI +:

		Работу с отдельными частями рисунков

		Рисование изображения

		Вывод на печать

		Предварительный просмотр

		Пространство имен Drawing2D

		Пространство имен Imaging

	В классе Graphics инкапсулированы поверхности рисования GDI+. Есть три основных типа поверхностей рисования:

		Окна и управляющие элементы на экране

		Страницы, посылаемые на принтер

		Растровые изображения в памяти

	Игра тетрис требует изображение областей поля в виде в квадратов. Для этого была использована структура языка C# Rectangle (прямоугольник). Для ее описания необходимы координаты верхнего левого угла прямоугольника (что соответствует значениям вертикали и горизонтали поля игры), а также его размеры. Структура Region позволяет объединять разные изображения в одно.

	Для заполнения определенной области рисунка цветом возможно использование класса Brush. Класс Brush - это абстрактный класс. Для создания экземпляра класса Brush исользуются классы, производные от класса Brush, такие как SolidBrush, TextureBrush и LinearGradientBrush. Класс Brush находится в пространстве имен System. Drawing. Классы TextureBrush и LinearGradientBrush находятся в пространстве имен System. Drawing. Drawing2D. Вот что позволяет делать каждый из этих классов:

		SolidBrush заполняет фигуру сплошным цветом.

		TextureBrush позволяет заполнять фигуру рисунком, хранящемся в двоичном представлении. При создании такой кисти требуется также задавать обрамляющий прямоугольник и режим обрамления. Обрамляющий прямоугольник определяет, какую порцию рисунка мы должны использовать при рисовании, - использовать весь рисунок целиком совершенно необязательно. Для режима обрамления существует несколько возможностей, включая Tile (черепица) - TileFiipx, TileFiipY и TileFiipXY, позволяющих последовательно разбивать изображение на Отдельные квадраты. С помощью TextureBrush можно создавать очень интересные и весьма впечатляющие эффекты.

		LinearGradientBrush содержит кисть, которая позволяет рисовать плавный переход от одного цвета к другому, причем первый цвет переходит во второй под определенным углом. Углы при этом задаются в градусах. Угол, равный 0, означает, что переход от одного цвета к другому осуществляется слева направо. Угол, равный 90°, означает, что переход от одного цвета к другому осуществляется сверху вниз.

	Принцип построения изображения поля игры прост. С помощью циклической и условной конструкций проверяется ячейки массива на одинаковые логические значения. Т.к. каждой ячейки соответствует определенная минимальная область поля игры, то зная значение строки и столбца массива возможно построение структуры Rectangle. Объединяя структуры Rectangle одного типа, можно получить два типа Region. Закрашивая эти два Region разными видами "кистей" получаем изображение поля (Листинг 2).

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

	При разработки программы предполагалось использование среды Microsoft Visual C# 2008 Express Edition. Эта среда разработки программного обеспечения содержит набор шаблонов, которые часто используют при разработки программ. В программе я использовался ряд шаблонов:

		Button

		Label

		PictureBox

		TextBox

		ContextMenuStrip

		Timer

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

	Приведенные выше принципы и элементы стали основой алгоритма.


2. Технологический раздел



2.1 Выбор языка и среды программирования

	

	Для реализации данного курсовой работы был выбран язык программирования Visual C#. Язык основан на строгой компонентной архитектуре и реализует передовые механизмы обеспечения безопасности кода. Язык программирования C# объединил лучшие черты целого ряда предшественников, а именно ветви языков B - C - C++.

	От языка программирования C++ языком C# унаследованы следующие механизмы: "перегруженные" операторы, небезопасные арифметические операции с плавающей точкой, а также ряд других особенностей синтаксиса.

	Несмотря на весьма существенные различия между компонентной объектной моделью COM (основного стандарта Microsoft для компонентного проектирования и реализации программного обеспечения) и моделью Java Beans, базовым стандартом Sun Microsystems для компонент (зависимой от языка реализации), язык программирования C# имеет довольно много общего с языком Java.

	Перечислим наиболее характерные черты сходства языков программирования C# и Java. Прежде всего, оба языка относятся к категории объектно-ориентированных и предполагают единственность наследования. Другими важными особенностями, которые сближают языки программирования C# и Java, являются механизмы интерфейсов, обработки исключительных ситуаций, а также процессов или "нитей" (threads). "Сборка мусора" и пространства имен реализованы в этих двух языках сходным образом. Оба языка программирования характеризуются сильной (строгой) типизацией и динамической загрузкой кода при выполнении программы.

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

	К числу принципиально важных решений, которые реализованы корпорацией Microsoft в языке программирования C#, можно отнести следующие:

		компонентно-ориентированный подход к программированию (который характерен и для идеологии Microsoft.net в целом);

		свойства как средство инкапсуляции данных (характерно также в целом для ООП);

		обработка событий (имеются расширения, в том числе в части обработки исключений, в частности, оператор try);

		унифицированная система типизации (соответствует идеологии Microsoft.net в целом);

		делегаты (delegate - развитие указателя на функцию в языках C и C++);

		индексаторы (indexer - операторы индекса для обращения к элементам класса-контейнера);

		перегруженные операторы (развитие ООП);

		оператор foreach (обработка всех элементов классов-коллекций, аналог Visual Basic);

		механизмы boxing и unboxing для преобразования типов;

		атрибуты (средство оперирования метаданными в COM-модели);

		прямоугольные массивы (набор элементов с доступом по номеру индекса и одинаковым количеством столбцов и строк).

	Приведенные выше особенности языка C# повлияли на выбор языка программирования и соответственно среды.net для программы.


2.2 Блок-схема программы



	При создании программного алгоритма "Тетриса" на начальном этапе была разработана блок-схема игры. В ней было описана последовательность работы алгоритма игры (Рис.2).

	

 

Рис.2


При запуске приложения "Тетрис" происходит объявления двумерного массива, с последующим его заполнением пустыми значениями. Игра начинается при запуске таймера. Далее происходит выбор фигуры с помощью генератора случайных чисел. В соответствии с выбранной фигурой происходит заполнение первых двух строк массива. Затем происходит вход в цикл падения фигуры. Тело цикла представляет собой сдвиг фигуры на одну строку ниже и проверка на нажатие кнопок "Вправо", "Влево", "Поворот" (при нажатии этих кнопок происходит сдвиг фигуры вправо, влево и поворот вокруг своей оси соответственно). Условие окончания цикла - отсутствие свободного места под фигурой. После выхода из цикла начинается проверка полностью заполненных строк. Если такие имеются, то происходит их очистка и сдвиг всех строк, находящихся выше. Далее происходит новый выбор фигуры и повторение алгоритма. Если же заполненных строк нет, то происходит проверка на свободное место в третьей строке. Если третья строка свободна, то происходит выбор фигуры и выполнение алгоритма цикла. При заполненности третьей строки происходит остановка таймера и вывод результатов игры. Затем происходит выход из игры.

	

2.3 Вводимые и выводимые данные

	

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

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

	Выводимые данные в программе представлены в виде графического отображения окна игры (Рис.3)

	

	

	Рис.3

	

	Окно игры.

	Вводимыми данными представлены в виде программного кода, который необходимо выполнить при определенных действиях пользователя. А именно:

		нажатие клавиш Left, Right, Up, Space;

		работа пользователя со строкой меню.

	

2.4 Разработка и отладка текста программы

	

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

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

	Отладка - это процесс поиска и устранения ошибок. Ошибки в программе разделяют на две группы: синтаксические (ошибки в тексте) и алгоритмические. Синтаксические ошибки - наиболее легко устраняемые. Алгоритмические ошибки обнаружить труднее. Этап отладки можно считать законченным, если программа правильно работает на одном-двух наборах входных данных.

	

2.5 Разработка интерфейса пользователя

	

	Тетрис - это игра. Поэтому, при разработки интерфейса пользователя необходимо учесть ряд особенностей:

		Интерфейс должен быть интуитивно понятен простому пользователю компьютера.

		Цветовая схема не должна раздражать человека.

	Рассмотрим первый пункт.

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

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

	

2.6 Тестирование программы

	

	Тестирование программы - это этап, на котором проверяется, как ведет себя программа на как можно большем количестве входных наборов данных, в том числе и на заведомо неверных.

	Основные принципы организации тестирования:

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

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

		по тем же соображениям организация - разработчик программного обеспечения не должна “единолично ” его тестировать (должны существовать организации, специализирующиеся на тестировании программных средств);

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

		необходимо тщательно подбирать тест не только для правильных (предусмотренных) входных данных, но и для неправильных (непредусмотренных);

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

		следует сохранять использованные тесты (для повышения эффективности повторного тестирования программы после ее модификации или установки у заказчика);

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

		следует учитывать так называемый “принцип скопления ошибок”: вероятность наличия не обнаруженных ошибок в некоторой части программы прямо пропорциональна числу ошибок, уже обнаруженных в этой части;

		следует всегда помнить, что тестирование - творческий процесс, а не относиться к нему как к рутинному занятию.

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


3. Руководство пользователя



3.1 Программно-аппаратные требования



	Аппаратные требования:

	Необходимый объем ОЗУ 64 Мб и графическим адаптером, поддерживающим режим 800х600 и выше, глубина цвета 32 бит. Необходимое место на жестком диске 780 Кб. Клавиатура, мышь.

	Программные требования:

	Операционная система семейства Windows: 2000/XP (32/64) /Vista (32/64) /7 (32/64)

	

3.2 Порядок работы с программой



	Запускаем приложение Tetris. exe (Рис.4):

	

	

	Рис.4

	
Приложение Tetris. exe

	Для того чтобы начать игру необходимо нажать Меню - Новая игра. Для изменения сложности игры необходимо зайти в Меню - Сложность. Для временной остановки игры необходимо нажать Меню - Пауза или клавишу Space. Для продолжения игры нажать Меню - Продолжить (Рис.5).

	

	

	Рис.5

	

	Строка меню

	Управление фигурами осуществляется с помощью клавиш Left, Right, Up (подробнее Меню - Справка - Управление) (Рис.6).

	

	

	Рис.6

	

	Окно "Управление"

	Для выхода из программы необходимо нажать Меню - Выход). Так же можно посмотреть сведения о программном продукте и разработчике (Меню - Справка - О программе) (Рис.7).

	

	

	Рис.7

	

	Окно "О программе"


Заключение



	В данной курсовой работе была выполнена поставленная задача - создание программы по теме "Разработка программы для игры "Тетрис"". При помощи этой программы можно приятно провести время, совершенствовать координацию и развивать логическое мышление. Программа не занимает много места, не требовательна к установленному программному обеспечению.

	


Список использованной литературы



	Г. Шилдт C#: Учебный курс. - Спб.: Питер, 2003. - 512с

	Либерти, Д. Программирование на Си Шарп. - М.: Символ-плюс, 2005. - 684 с.

	Ватсон К. Си Шарп/К. Ватсон. - М.: Лори, 2005. - 862 с.

	Жарков В.А. Компьютерная графика, мультимедиа и игры на Visual C# 2005. - М.: Жарков пресс, 2005. - 812с.

	http://www.excode.ru/art6225p1.html


Приложения

	

Листинг 1

		private void Form1_Load (object sender, EventArgs e)

		{

		for (i = 0; i < 24; i++) // заполнение массива пустыми значениями

		{

		for (j = 0; j < 15; j++)

		{

		Tet [i, j] = false;

		Res = true;

		}

		}

		SF = false; // фигура не существует

		textBox2. Text = "0";

		}

		private void timer_Tick (object sender, EventArgs e)

		{

		if (SF == false)

		{

		Random a = new Random (); // выбор фигуры

		NumbeF = a. Next (0,6);

		SF = true;

		P = true; // появление фигуры на первой позиции

		}

		if (SF == true)

		{

		if (NumbeF == 0) // квадрат

		{

		if (P == true) // условие появления квадрата в первой позиции

		{

		Tet [0, 7] = true;

		Tet [0, 8] = true;

		Tet [1, 7] = true;

		Tet [1, 8] = true;

		P = false; // фигура не появляется на первой позиции

		i = 1;

		j = 7;

		}

		if (i < 23 && (Tet [i + 1, j] == false && Tet [i + 1, j + 1] == false)) // условие сдвига фигуры

		{

		Tet [i - 1, j] = false;

		Tet [i - 1, j + 1] = false;

		Tet [i + 1, j] = true;

		Tet [i + 1, j + 1] = true;

		i = i + 1;

		}

		else

		{

		SF = false; // фигура не существует

		}

		}

		if (NumbeF == 1) // сапожок

		{

		if (P == true) // условие появления сапожка в первой позиции

		{

		Tet [0, 7] = true;

		Tet [1, 7] = true;

		Tet [1, 8] = true;

		Tet [1, 9] = true;

		P = false;

		i = 1;

		j = 8;

		Razp = 0;

		}

		if (Razp == 0) // фигура сапожок в положение 0

		{

		if (i < 23 && Tet [i + 1, j - 1] == false && Tet [i + 1, j] == false && Tet [i + 1, j + 1] == false) // проверка свободного места под фигурой

		{

		Tet [i, j] = false;

		Tet [i, j + 1] = false;

		Tet [i - 1, j - 1] = false;

		Tet [i + 1, j - 1] = true;

		Tet [i + 1, j] = true;

		Tet [i + 1, j + 1] = true;

		i = i + 1;

		}

		else

		{

		SF = false;

		}

		}

		if (Razp == 1) // фигура сапожок в положение 1

		{

		if (i < 22 && Tet [i + 2, j - 1] == false && Tet [i + 2, j] == false) // проверка свободного места под фигурой

		{

		Tet [i - 1, j] = false;

		Tet [i + 1, j - 1] = false;

		Tet [i + 2, j - 1] = true;

		Tet [i + 2, j] = true;

		i = i + 1;

		}

		else

		{

		SF = false;

		}

		}

		if (Razp == 2) // фигура сапожок в положение 2

		{

		if (i < 22 && Tet [i + 1, j - 1] == false && Tet [i + 1, j] == false && Tet [i + 2, j + 1] == false) // проверка свободного места под фигурой

		{

		Tet [i, j] = false;

		Tet [i, j + 1] = false;

		Tet [i, j - 1] = false;

		Tet [i + 1, j - 1] = true;

		Tet [i + 1, j] = true;

		Tet [i + 2, j + 1] = true;

		i = i + 1;

		}

		else

		{

		SF = false;

		}

		}

		if (Razp == 3) // фигура сапожок в положение 3

		{

		if (i < 22 && Tet [i, j + 1] == false && Tet [i + 2, j] == false) // проверка свободного места под фигурой

		{

		Tet [i - 1, j] = false;

		Tet [i - 1, j + 1] = false;

		Tet [i, j + 1] = true;

		Tet [i + 2, j] = true;

		i = i + 1;

		}

		else

		{

		SF = false;

		}

		}

		}

	

Листинг 2

		SolidBrush Brush2 = new SolidBrush (System. Drawing. Color. LightCyan); // создание кисти

		SolidBrush Brush3 = new SolidBrush (System. Drawing. Color. Red);

		Font font = new Font ("Times New Roman", 30, FontStyle. Bold | FontStyle. Italic); // описание стиля надписи

		for (a = 2; a < 24; a++)

		{

		for (b = 0; b < 15; b++)

		{

		Graphics myGraphics = CreateGraphics (); // создание поверхности для рисования

		if (Tet [a, b] == true)

		{

		LinearGradientBrush Brush1 = new LinearGradientBrush (new Rectangle (20 * b,20 * a, 20, 20), Color. Aqua, Color. Blue, 45);

		Rectangle r1 = new Rectangle (20 * b,20 * (a - 1), 20, 20); // объединение заполненных ячеек в область

		myGraphics. FillRectangle (Brush1, r1); // закрашивание заполненной области

		}

		if (Tet [a, b] == false)

		{

		Rectangle r1 = new Rectangle (20 * b,20 * (a - 1), 20, 20); // объединение незаполненных ячеек в область

		myGraphics. FillRectangle (Brush2, r1); // закрашивание незаполненной области

		}

		}

		}

	

Листинг 3

		private void button2_KeyUp (object sender, KeyEventArgs e)

		{

		key = e. KeyCode. ToString ();

		if (key == "Right") // проверка нажатие клавиши "Вправо"

		{

		timer. Enabled = false;

		if (NumbeF == 0 && j < 13 && Tet [i - 1, j + 2] == false && Tet [i, +2] == false) // проверка свободного места справо

		{

		Tet [i, j + 2] = true;

		Tet [i - 1, j + 2] = true;

		Tet [i, j] = false;

		Tet [i - 1, j] = false;

		j = j + 1;

		}

		if (NumbeF == 1)

		{

		if (Razp == 0 && j < 13 && Tet [i, j + 2] == false && Tet [i - 1, j] == false) // проверка свободного места справо

		{

		Tet [i - 1, j] = true;

		Tet [i, j + 2] = true;

		Tet [i, j - 1] = false;

		Tet [i - 1, j - 1] = false;

		j = j + 1;

		}

		if (Razp == 1 && j < 14 && Tet [i - 1, j + 1] == false && Tet [i, j + 1] == false && Tet [i + 1, j + 1] == false) // проверка свободного места справо

		{

		Tet [i - 1, j] = false;

		Tet [i, j] = false;

		Tet [i + 1, j - 1] = false;

		Tet [i - 1, j + 1] = true;

		Tet [i, j + 1] = true;

		Tet [i + 1, j + 1] = true;

		j = j + 1;

		}

		if (Razp == 2 && j < 13 && Tet [i, j + 2] == false && Tet [i + 1, j + 2] == false) // проверка свободного места справо

		{

		Tet [i, j + 2] = true;

		Tet [i + 1, j + 2] = true;

		Tet [i, j - 1] = false;

		Tet [i + 1, j + 1] = false;

		j = j + 1;

		}

		if (Razp == 3 && j < 13 && Tet [i - 1, j + 2] == false && Tet [i, j + 1] == false && Tet [i + 1, j + 1] == false) // проверка свободного места справо

		{

		Tet [i - 1, j + 2] = true;

		Tet [i, j + 1] = true;

		Tet [i + 1, j + 1] = true;

		Tet [i - 1, j] = false;

		Tet [i, j] = false;

		Tet [i + 1, j] = false;

		j = j + 1;

		}

		}

		}

		}