Моделирование доски Гальтона на C++ Borland Builder

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

Рубрика Программирование, компьютеры и кибернетика
Вид курсовая работа
Язык русский
Дата добавления 15.01.2013
Размер файла 1,4 M

Отправить свою хорошую работу в базу знаний просто. Используйте форму, расположенную ниже

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

Размещено на http://www.allbest.ru/

Федеральное агентство по образованию

ГОУ ВПО "УГТУ-УПИ

имени Первого Президента России Б.Н. Ельцина"

Кафедра

Радиоэлектронных и телекоммуникационных систем

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

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

по дисциплине "Информатика"

Доска Гальтона

Выполнил: студент группы Р-28061

Гришин Анатолий Александрович

Руководитель: Саблина Наталья Григорьевна

Екатеринбург 2009 г.

Задание на разработку

Разработать программу, моделирующую процесс падения шариков в Доске Гальтона - приборе, наглядно иллюстрирующем некоторые законы теории вероятностей. В качестве исходных данных задавать общее количество шаров n, предусмотреть два варианта с разным количеством каналов (k=5 и k=10).

Оглавление

  • Задание на разработку
  • Введение
  • 1. Метод решения
  • 1.1 Структура метода решения
  • 1.2 Блок-схема меню программы
  • 1.3 Блок-схема алгоритма функции Timer1Timer (TObject *Sender)
  • 2. Описание программы
  • 2.1 Процедуры
  • 2.2 Интерфейс
  • 3. Руководство пользователя
  • 3.1 Системные требования
  • 3.2 Установка и удаление
  • 3.3 Инструкция по эксплуатации
  • 4. Результаты моделирования
  • Заключение
  • Список литературы
  • Приложения

Введение

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

Процесс моделирования включает три элемента:

субъект (исследователь),

объект исследования,

модель, определяющую (отражающую) отношения познающего субъекта и познаваемого объекта.

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

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

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

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

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

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

Данная программа моделирует лабораторный прибор, известный под названием "Доска Гальтона" и наглядно демонстрирует процесс падения шариков для произвольного числа каналов (от 3 до 15) и произвольного числа шариков (не больше квадрата от количества ячеек).

1. Метод решения

Доска Гальтона - это лабораторный прибор, наглядно иллюстрирующий некоторые законы теории вероятностей, в частности распределение Максвелла. Сверху доска прикрыта стеклом, под которым находятся расходящиеся каналы для металлических шариков. Попадая в верхний канал, шарик должен выбрать дальнейшее направление: направо или налево. После этого шарик попадает в следующий канал и т.д. При достаточном качестве прибора вероятности выбора каждого из направлений равны, а результирующая картина распределения шариков по ячейкам хорошо согласуется с вероятностными расчетами, в соответствии с которыми количество шариков, оказавшихся в отделениях, пронумерованных числами 1,., т, должны быть пропорциональными (с некоторым коэффициентом пропорциональности, зависящим от общего числа шариков) числам из m-й строки треугольника Паскаля. Кривая, огибающая верхушки столбцов из шариков, должна иметь колоколообразную форму.

1.1 Структура метода решения

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

Рассмотрим алгоритм вычисления окончательного распределения шариков по ячейкам:

Допустим, что задано начальное количество ячеек - k. Из этого следует, что каждый шарик должен сделать k-1 поворот до тех пор, пока не достигнет своей ячейки. Сформируем массив поворотов данного шарика. Каждый элемент будет соответствовать одному повороту: - 1 - если шарик поворачивает налево, и 1 - если шарик поворачивает направо. Затем посчитаем сумму поворотов. Обозначим эту сумму Sum. Для нахождения номера ячейки, в которую попадет шарик, воспользуемся формулой:

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

Графическая реализация падения и распределения шариков: рассмотрим вначале процесс построения окончательной картинки без анимации. Естественно, что он будет зависеть от параметров k, N и от размеров окна width и height, в котором отображается Доска Гальтона. Ниже приведен чертеж Доски с параметрами и формулы для расчета этих параметров, выведенные из геометрических соображений и позволяющие выполнять построение Доски Гальтона с произвольным числом ячеек и с учетом числа падающих шариков (от этого зависит максимальная высота "столбика" из шариков в ячейке) для поля рисования произвольных ширины и высоты:

Рис.1.

Формула для расчета ширины одной панели:

где width - ширина поля рисования, ramka - ширина рамки, k - число ячеек;

Формула для расчета радиуса падающих шариков:

Формула для расчета высоты нижних ячеек, в которые попадают шарики:

где N - общее число падающих шариков.

Формула для расчета высоты доски:

где height - высота поля рисования.

Формула для расчета высоты одной панели:

Формула для расчета высоты "уголка" панели:

где alfa - угол наклона сужения панели к горизонтальной оси.

Формула для расчета вертикальной части панели:

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

доска гальтон программа интерфейс

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

start (логический тип) - определяет, начал ли шарик движение;

end (логический тип) - закончил ли шарик движение;

stage (натуральное число) - номер этажа, на котором находится шарик;

z (целое число) - координата по высоте от начала текущего этажа;

linear (логический тип) - определяет, достиг ли шарик наклонный участок данного этажа;

Lstage (логический тип) - достигнут ли последний этаж;

turn (массив целых чисел) - содержит информацию о поворотах шарика в виде упорядоченного набора +1 или - 1;

OldX (целое число) - координата Х шарика в прошлый момент времени;

OldY (целое число) - координата Y шарика в прошлый момент времени;

number (натуральное число) - номер ячейки, в которую попадает шарик.

Примечание: все координаты отсчитываются от левого верхнего угла поля рисования (канвы) соответственно направо и вниз.

Изменение картинки осуществляется через определенные моменты времени, определяемые параметром dt. Приращение координаты шарика определяется параметром dz. У первого из шариков параметр start на начало анимации принимает значение "истина", у остальных "ложь". После старта первого шарика начинается отсчет времени. Когда наступит момент времени, определяемый параметром period, следующий шарик начинает движение (start приобретает значение "истина") и т.д.

В процессе построения кадра в первую очередь для каждого шарика определяется, начал ли он движение и не закончил ли его и не находится ли на последнем этаже. Далее выясняем, достиг ли шарик наклонного участка данного этажа или падает вертикально вниз. Если он находится на вертикальном отрезке, то увеличиваем его вертикальную координату пропорционально dz (коэффициент пропорциональности зависит от номера этажа, но не превышает 4, таким образом обеспечивается ускорение шариков по мере падения). Если новая координата z превысила высоту вертикального участка a, то осуществляем присваивание z=a, а параметру linear задаем значение "ложь". Если же шарик находился на наклонном участке, то он должен осуществить движение в наклонном направлении, зависящем от величины, соответствующей последнему повороту (-1 или +1), от параметра dz и от номера этажа. Ниже приведены формулы, по которым вычисляются приращения обеих координат шарика в этом случае:

знак в последней формуле определяется направлением движения - "+”, если направо и "-", если налево. После приращения соответствующих координат выясняем, не превысила ли координата z значение h. Если это так, то номер этажа stage шарика увеличиваем на 1, координату z обнуляем: z=0, а свойству linear присваиваем значение "истина".

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

,

где -количество шариков, уже попавших в данную ячейку, -оператор выделения целой части. Если шарик достиг вершины столбика, то увеличиваем на один, а свойству end данного шарика присваиваем значение "истина". Далее проверяем, есть ли еще шарики, которые не закончили движение. Если это так, то параметру End, отвечающему за конец анимации, присваиваем значение "истина" и выводим на экран окончательное распределение шариков. Если шарик не достиг вершины столбика, то увеличиваем его вертикальную координату на величину, пропорциональную dz (при числе этажей, большем трех, на ).

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

Пользователь может управлять режимом анимации с помощью функций "Старт", "Пауза", "Стоп". Функция "Старт" в режиме анимации запускает (продолжает) цикл построения кадров, "Пауза" приостанавливает этот цикл, а "Стоп" останавливает процесс, после чего на экран выводится окончательная картинка и распределение.

1.2 Блок-схема меню программы

1.3 Блок-схема алгоритма функции Timer1Timer (TObject *Sender)

Размещено на http://www.allbest.ru/

2. Описание программы

2.1 Процедуры

Основными процедурами, с помощью которых реализуется вывод изображения на экран, являются:

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

ResizePicture () - функция, которая изменяет геометрические параметры изображения в зависимости от размеров канвы. Применяется при растяжении или сжатии формы.

Timer1Timer (TObject *Sender) - эта функция отвечает за формирование очередного кадра в режиме анимации.

Draw () - функция, отвечающая за рисование всей доски с шариками, на данный момент времени попавшими в ячейки (в режиме анимации) или с полным распределением шариков по окончании анимации или в статическом режиме по ячейкам.

LowBalls () - функция, изображающая шарики, попавшие в ячейки.

DrawPanel (int x, int y) - функция рисования отдельной панели (на вход подаются координаты нижнего угла панели).

DrawBall (int x, int y) - рисует отдельный шарик с центром в точке с координатами (x, y).

DeleteBall (int x, int y) - зарисовка шарика цветом фона в точке с координатами (x, y).

2.2 Интерфейс

При вызове программы открывается заставка, она открывается первой и не является главным окном. Заставка является модальным окном и содержит кнопку "Далее", после нажатия на которую открывается главное окно программы, а форма заставки удаляется. После заставки на экране появляется главное окно. Оно содержит меню со всеми возможными действиями программы (компонент MainMenu1), панель инструментов (компоненты Panel1), строку состояния (компонент StatusBar1).

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

"Вид" дает возможность скрыть или показать такие элементы интерфейса, как панель инструментов и строку состояния.

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

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

Структура главного меню:

2. Действия:

Включить анимацию

Старт

Пауза

Стоп

Увеличить расстояние между шарами

Уменьшить расстояние между шарами

Выход

3. Настройки:

Параметры

4. Формат:

Цвет >

· фона …

· панелей …

· шариков …

· контура …

5. Вид

Панель инструментов

Строка состояний

6. Справка

Вызов справки

Теория

Об авторе

Изображение и анимация выводятся на экран с помощью свойства canvas компонента Image1 класса TImage. Компоненты этого класса хороши тем, что они автоматически перерисовываются.

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

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

· ОС - Windows 2000\XP\Vista\Seven;

· Мышь;

· CD-привод;

· 32 Мб ОЗУ;

· Процессор: Pentium II или выше;

· 1,2 Мб свободного места на жестком диске.

3.2 Установка и удаление

Программа не требует установки: просто скопируйте папку с программой в нужную директорию. Удалить программу можно стандартными средствами Windows для удаления файлов.

3.3 Инструкция по эксплуатации

Для начала работы просто запустите исполняемый файл GaltonDesk. exe.

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

4. Результаты моделирования

Заставка программы (Рис.2.):

Рис.2.

Главное окно программы с окончательным распределением шариков по ячейкам для значений параметров k=6 и N=36 (Рис.3.):

Рис.3.

Главное окно программы с окончательным распределением шариков по ячейкам для значений параметров k=3 и N=9 (Рис.4.):

Рис.4.

Главное окно программы в режиме анимации для значений параметров k=12 и N=144 (Рис.5.):

Рис.5.

Окно настройки параметров (Рис.6.):

Рис.6.

Окно справки (Рис.7.):

Рис.7.

Заключение

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

Достоинства:

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

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

§ Окно программы можно масштабировать.

Недостатки:

§ Невозможность развернуть окно программы на полный экран.

§ Отсутствует возможность сохранения результатов распределения в файл.

Список литературы

1. А.Я. Архангельский. Программирование в C++ Builder 6. - 2003, 1152 с.

2. http://cbuilder.ru - support Borland Software

3. http://www.codenet.ru - CodeNet - все для программиста

4. http://www.CyberGuru.ru - Programmers Area

5. http://www.sources.ru - Исходники.ru

6. http://ru. wikipedia.org - Википедия, свободная энциклопедия

7. С++ Builder Help

Приложения

Приложение 1

Листинг Unit1. cpp

// ---------------------------------------------------------------------------

#include <vcl. h>

#pragma hdrstop

#include "Unit1. h"

#include "Unit2. h"

#include "Unit3. h"

#include "Unit4. h"

#include "Unit5. h"

#include "Unit6. h"

#include "Math. h"

#include "Time. h"

// ---------------------------------------------------------------------------

#pragma package (smart_init)

#pragma resource "*. dfm"

TForm1 *Form1;

// ---------------------------------------------------------------------------

__fastcall TForm1:: TForm1 (TComponent* Owner)

: TForm (Owner)

{

}

void __fastcall TForm1:: FormClose (TObject *Sender, TCloseAction &Action)

{

Timer1->Enabled=false;

delete M;

delete Mas;

for (int i=0; i<N; i++)

delete Ball [i]. turn;

delete Ball;

if (TeorOpened) delete Teory;

if (HelpOpened) delete Help;

exit (0);

}

// рисование всей доски

void TForm1:: Draw ()

{

Image1->Canvas->Pen->Color= (TColor) RGB (114,134,248);

Image1->Canvas->Pen->Width=10;

// фон

Image1->Canvas->Brush->Color=ColorDialog1->Color;

Image1->Canvas->FillRect (Rect (0,0, Image1->Width, Image1->Height));

Image1->Canvas->Rectangle (0,0, Image1->Width, Image1->Height);

// рисование панелей

int x, y;

int j=1; // номер "этажа"

int i=1; // номер панели на этаже

for (y=Image1->Height-ramka-l; j<=k-1; y-=h)

{

i=1;

for (x= (Image1->Width-2* (k-j-1) *b) /2; i<=k-j; x+=2*b)

{

DrawPanel (x,y);

i++;

}

j++;

}

// рисование "ножек"

i=1;

for (x= (Image1->Width-2* (k-2) *b) /2; i<=k-1; x+=2*b)

{

Image1->Canvas->Rectangle (x-b/8, Image1->Height-ramka,x+b/8, Image1->Height-ramka-l-c/2);

i++;

}

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

Image1->Canvas->MoveTo ( (Image1->Width- (2*k-1) *b) /2, Image1->Height-ramka-l-h+c);

Image1->Canvas->LineTo ( (Image1->Width- (2*k-1) *b) /2, Image1->Height-ramka);

Image1->Canvas->LineTo ( (Image1->Width+ (2*k-1) *b) /2, Image1->Height-ramka);

Image1->Canvas->LineTo ( (Image1->Width+ (2*k-1) *b) /2, Image1->Height-ramka-l-h+c);

int q= ( (2*k-3) *b) /2;

y=Image1->Height-ramka-l-h-c;

for (i=1; i<=k-2; i++)

{

Image1->Canvas->MoveTo (Image1->Width/2-q-b,y+2*c);

Image1->Canvas->LineTo (Image1->Width/2-q,y);

Image1->Canvas->LineTo (Image1->Width/2-q,y-a);

Image1->Canvas->MoveTo (Image1->Width/2+q+b,y+2*c);

Image1->Canvas->LineTo (Image1->Width/2+q,y);

Image1->Canvas->LineTo (Image1->Width/2+q,y-a);

y-=h;

q-=b;

}

y=Image1->Height-l- (k-1) *h-ramka+c;

q=3*b/2;

x=Image1->Width/2-q;

Image1->Canvas->MoveTo (x,y);

Image1->Canvas->LineTo (x+b,y-2*c);

Image1->Canvas->LineTo (x+b,y-2*c-a);

Image1->Canvas->MoveTo (x+2*q,y);

Image1->Canvas->LineTo (x+2*q-b,y-2*c);

Image1->Canvas->LineTo (x+2*q-b,y-2*c-a);

Image1->Canvas->LineTo (x+2*q-3*b/2,y-3*c-a);

Image1->Canvas->LineTo (x+2*q-2*b,y-2*c-a);

LowBalls ();

}

// рисование отдельной панели

void TForm1:: DrawPanel (int x, int y)

{

Image1->Canvas->Pen->Color=ColorDialog4->Color;

Image1->Canvas->Pen->Width=2;

int c=int (float (b/2) *cos (alfa) /sin (alfa));

Image1->Canvas->MoveTo (x,y);

Image1->Canvas->LineTo (x+b/2,y-c);

Image1->Canvas->LineTo (x+b/2,y-c-a);

Image1->Canvas->LineTo (x,y-2*c-a);

Image1->Canvas->LineTo (x-b/2,y-c-a);

Image1->Canvas->LineTo (x-b/2,y-c);

Image1->Canvas->LineTo (x,y);

Image1->Canvas->Brush->Color=ColorDialog2->Color;

Image1->Canvas->FloodFill (x,y-a,ColorDialog1->Color,fsSurface);

}

// рисование отдельного шарика

void TForm1:: DrawBall (int x, int y)

{

Image1->Canvas->Brush->Color=clBlue; // тень от шарика

Image1->Canvas->Pen->Color=clBlue;

Image1->Canvas->Pen->Width=1;

Image1->Canvas->Ellipse (Rect (x-r+1,y-r+1,x+r+1,y+r+1));

Image1->Canvas->Brush->Color=ColorDialog3->Color;

Image1->Canvas->Pen->Color=clBlue;

Image1->Canvas->Pen->Width=1;

Image1->Canvas->Ellipse (Rect (x-r,y-r,x+r,y+r));

Image1->Canvas->Brush->Color=clWhite; // (TColor) RGB (192,218,245);

Image1->Canvas->Pen->Color=clWhite; // (TColor) RGB (192,218,245);

Image1->Canvas->Ellipse (Rect (x,y,x-r*2/3,y-r*2/3));

Image1->Canvas->Ellipse (Rect (x+r/2,y+r/2,x+r/4,y+r/4));

Image1->Canvas->Brush->Color=clWhite;

Image1->Canvas->Pen->Color=clBlack;

}

// зарисовка отдельного шарика

void TForm1:: DeleteBall (int x, int y)

{

Image1->Canvas->Pen->Color=ColorDialog1->Color;

Image1->Canvas->Brush->Color=ColorDialog1->Color;

Image1->Canvas->Ellipse (Rect (x-r,y-r,x+r,y+r));

Image1->Canvas->Ellipse (Rect (x-r+1,y-r+1,x+r+1,y+r+1));

}

// рисование шариков внизу

void TForm1:: LowBalls ()

{

int i,j;

int xc;

int p, level;

for (i=0; i<k; i++)

{

xc=Image1->Width/2- (k-1) *b+i*2*b;

p=-1;

level=0;

for (j=0; j<M [i]; j++)

{

if (p==-1) level++;

DrawBall (xc+p* ( (b-4*r) /6+r), Image1->Height-ramka-level* (b-4*r) /3- (2*level-1) *r);

p=-p;

}

}

}

// инициализация глобальных переменных

void TForm1:: Init ()

{

int i,j;

if (M_Init)

{

delete M; delete Mas;

for (int i=0; i<N; i++)

delete Ball [i]. turn;

delete Ball;

}

ramka=20;

k=StrToInt (Edit1->Text);

N=StrToInt (Edit2->Text);

if (N>k*k) {N=k*k; Edit2->Text=IntToStr (N); }

UpDown2->Max=k*k;

UpDown1->Position=k;

M=new int [k]; Mas=new int [k];

for (i=0; i<k; i++) {M [i] =0; Mas [i] =0; }

alfa=45*3.1415/180;

b= (Image1->Width-2*ramka) / (2*k-1);

r=b/6;

max=N/7;

l= (max+1) * (2*r+b/6) +r+b/6;

H=Image1->Height-2*ramka;

h= (H-l-3*ramka) / (float (k) - 0.5);

a=h-2*int (float (b/2) *cos (alfa) /sin (alfa));

c=b*cos (alfa) / (2*sin (alfa));

dh=c/2;

z0=Image1->Height- (l+ (k-1) *h+c+a+ramka);

t=0;

period=len*dt;

dz=2;

Timer1->Interval=dt;

End=true;

randomize ();

Ball=new BallProperty [N]; // свойства каждого из шариков

for (i=0; i<N; i++)

{

Ball [i]. start=false;

Ball [i]. end=false;

Ball [i]. stage=1;

Ball [i]. z=0;

Ball [i]. linear=true;

Ball [i]. Lstage=false;

Ball [i]. turn=new int [k-1];

Ball [i]. OldX=Image1->Width/2;

Ball [i]. OldY=z0;

Ball [i]. number=0;

for (j=0; j<k-1; j++) // случайным образом формируем массив поворотов шарика, состоящий из - 1 (налево) и 1 (направо)

{

Ball [i]. turn [j] =random (2);

if (! Ball [i]. turn [j]) Ball [i]. turn [j] =-1;

}

}

Ball [0]. start=true;

started=0;

M_Init=true;

int *Sum;

Sum=new int [N]; // массив сумм поворотов шарика

for (i=0; i<N; i++)

{

Sum [i] =0;

for (j=0; j<k-1; j++) Sum [i] +=Ball [i]. turn [j];

}

int e;

for (i=0; i<N; i++)

{

e=int (float (int (k/2)) +1+float (Sum [i]) /2); // ЗДЕСЬ ВЫЧИСЛЯЕТСЯ НОМЕР ЯЧЕЙКИ, В КОТОРУЮ ПОПАЕДТ ШАРИК

Ball [i]. number=e;

Mas [e-1] ++;

}

delete [] Sum;

if (! N2->Checked) for (i=0; i<k; i++) M [i] =Mas [i];

}

// изменение размеров изображения

void TForm1:: ResizePicture ()

{

int i,j;

ramka=20;

b= (Image1->Width-2*ramka) / (2*k-1);

r=b/6;

l= (max+1) * (2*r+b/6) +r+b/6;

H=Image1->Height-2*ramka;

h= (H-l-3*ramka) / (float (k) - 0.5);

a=h-2*int (float (b/2) *cos (alfa) /sin (alfa));

c=b*cos (alfa) / (2*sin (alfa));

dh=c/2;

z0=Image1->Height- (l+ (k-1) *h+c+a+ramka);

}

// ---------------------------------------------------------------------------

void __fastcall TForm1:: SpeedButton1Click (TObject *Sender)

{

if (! Timer1->Enabled)

{

k--;

Edit1->Text=IntToStr (k);

}

}

// ---------------------------------------------------------------------------

void __fastcall TForm1:: SpeedButton2Click (TObject *Sender)

{

if (! Timer1->Enabled)

{

k++;

Edit1->Text=IntToStr (k);

}

}

// ---------------------------------------------------------------------------

void __fastcall TForm1:: Timer1Timer (TObject *Sender)

{

int i,j;

// массив сумм поворотов до текущего этажа

int *TurnSum=new int [N];

for (i=0; i<N; i++)

{

TurnSum [i] =0;

for (j=0; j<Ball [i]. stage-1; j++) TurnSum [i] +=Ball [i]. turn [j];

}

for (i=0; i<N; i++)

{

if (t>=period)

{

started++;

Ball [started]. start=true;

t=0;

}

if (Ball [i]. start&&! Ball [i]. end&&! Ball [i]. Lstage)

{

if (Ball [i]. linear)

{

if (Ball [i]. z>=a)

{

Ball [i]. z=a;

Ball [i]. linear=false;

}

else if (Ball [i]. stage<4) Ball [i]. z+=dz*Ball [i]. stage; else Ball [i]. z+=dz*4;

if (Ball [i]. z>=a) Ball [i]. z=a;

DeleteBall (Ball [i]. OldX,Ball [i]. OldY);

DrawBall (Image1->Width/2+TurnSum [i] *b,z0+ (Ball [i]. stage-1) *h+Ball [i]. z+dh);

Ball [i]. OldX=Image1->Width/2+TurnSum [i] *b;

Ball [i]. OldY=z0+ (Ball [i]. stage-1) *h+Ball [i]. z+dh;

}

else

{

if (Ball [i]. z>=h)

{

Ball [i]. z=0;

Ball [i]. stage++;

if (Ball [i]. stage==k) Ball [i]. Lstage=true;

Ball [i]. linear=true;

DeleteBall (Ball [i]. OldX,Ball [i]. OldY);

DrawBall (Image1->Width/2+ (TurnSum [i] +Ball [i]. turn [Ball [i]. stage-2]) *b,z0+ (Ball [i]. stage-1) *h+dh);

Ball [i]. OldX=Image1->Width/2+ (TurnSum [i] +Ball [i]. turn [Ball [i]. stage-2]) *b;

Ball [i]. OldY=z0+ (Ball [i]. stage-1) *h+dh;

}

else

{

if (Ball [i]. stage<4) Ball [i]. z+=dz*Ball [i]. stage*sin (alfa); else Ball [i]. z+=dz*4*sin (alfa);

DeleteBall (Ball [i]. OldX,Ball [i]. OldY);

DrawBall (Image1->Width/2+TurnSum [i] *b+Ball [i]. turn [Ball [i]. stage-1] * (Ball [i]. z-a) *cos (alfa) /sin (alfa),z0+Ball [i]. z+ (Ball [i]. stage-1) *h+dh);

Ball [i]. OldX=Image1->Width/2+TurnSum [i] *b+Ball [i]. turn [Ball [i]. stage-1] * (Ball [i]. z-a) *cos (alfa) /sin (alfa);

Ball [i]. OldY=z0+Ball [i]. z+ (Ball [i]. stage-1) *h+dh;

}

}

}

if (Ball [i]. start&&! Ball [i]. end&&Ball [i]. Lstage)

{

if (Ball [i]. z>=l+c+a- (2*r* (M [Ball [i]. number-1] /2+1) +b* (M [Ball [i]. number-1] /2+2) /6))

{

Ball [i]. end=true;

M [Ball [i]. number-1] ++;

End=true;

for (int w=0; w<N; w++)

{

if (! Ball [w]. end) End=false;

}

DeleteBall (Ball [i]. OldX, Ball [i]. OldY);

if (End)

{

Timer1->Enabled=false;

Edit1->Enabled=true;

Edit2->Enabled=true;

UpDown1->Enabled=true;

UpDown2->Enabled=true;

char *Distrib=new char [120];

Distrib [0] =0;

StrCat (Distrib, "Распределение шариков по ячейкам: ");

for (int w=0; w<k; w++)

{

StrCat (Distrib, IntToStr (M [w]). c_str ());

StrCat (Distrib, " ");

}

StatusBar1->Panels->Items [0] - >Text=Distrib;

delete Distrib;

N4->Enabled=true;

N5->Enabled=false;

N6->Enabled=false;

ToolButton3->Enabled=true;

ToolButton4->Enabled=false;

ToolButton5->Enabled=false;

}

}

else

{

if (Ball [i]. z==0) TurnSum [i] +=Ball [i]. turn [k-2];

Ball [i]. z+=dz*4;

DeleteBall (Ball [i]. OldX,Ball [i]. OldY);

DrawBall (Image1->Width/2+TurnSum [i] *b, (k-1) *h+Ball [i]. z+z0+dh);

Ball [i]. OldX=Image1->Width/2+TurnSum [i] *b;

Ball [i]. OldY= (k-1) *h+Ball [i]. z+z0+dh;

}

}

}

LowBalls ();

t+=dt;

delete [] TurnSum;

}

// ---------------------------------------------------------------------------

void __fastcall TForm1:: FormCreate (TObject *Sender)

{

DoubleBuffered=true;

TeorOpened=false;

HelpOpened=false;

Activated=false;

TFLog *FLog=new TFLog (this);

FLog->ShowModal ();

delete FLog;

Form1->Height=Form1->Height-StatusBar1->Height-CoolBar1->Height;

Form1->Constraints->MaxHeight=Form1->Height;

Form1->Constraints->MaxWidth=Form1->Width;

Form1->Position=poScreenCenter;

BackColor= (TColor) RGB (255,218,119);

}

// ---------------------------------------------------------------------------

void __fastcall TForm1:: SpeedButton3Click (TObject *Sender)

{

if (! Timer1->Enabled)

Edit2->Text=IntToStr (StrToInt (Edit2->Text) - 1);

}

// ---------------------------------------------------------------------------

void __fastcall TForm1:: SpeedButton4Click (TObject *Sender)

{

if (! Timer1->Enabled)

Edit2->Text=IntToStr (StrToInt (Edit2->Text) +1);

}

// ---------------------------------------------------------------------------

void __fastcall TForm1:: CheckBox1Click (TObject *Sender)

{

End=true;

Timer1->Enabled=false;

}

// Анимация

void __fastcall TForm1:: N2Click (TObject *Sender)

{

ToolButton1->Down=! ToolButton1->Down;

if (N2->Checked)

{

N4->Enabled=true;

N13->Enabled=true;

N14->Enabled=true;

ToolButton3->Enabled=true;

ToolButton9->Enabled=true;

ToolButton10->Enabled=true;

TrackBar1->Enabled=true;

}

else

{

N13->Enabled=false;

N14->Enabled=false;

ToolButton9->Enabled=false;

ToolButton10->Enabled=false;

TrackBar1->Enabled=false;

if (! End)

{

N2->Enabled=true;

N5->Enabled=false;

N6->Enabled=false;

ToolButton3->Enabled=true;

ToolButton4->Enabled=false;

ToolButton5->Enabled=false;

Timer1->Enabled=false;

End=true;

for (int i=0; i<k; i++) M [i] =Mas [i];

Draw ();

}

}

}

void __fastcall TForm1:: ToolButton1Click (TObject *Sender)

{

N2->Checked=! N2->Checked;

if (N2->Checked)

{

N4->Enabled=true;

N13->Enabled=true;

N14->Enabled=true;

ToolButton3->Enabled=true;

ToolButton9->Enabled=true;

ToolButton10->Enabled=true;

TrackBar1->Enabled=true;

}

else

{

N13->Enabled=false;

N14->Enabled=false;

ToolButton9->Enabled=false;

ToolButton10->Enabled=false;

TrackBar1->Enabled=false;

if (! End)

{

N4->Enabled=true;

N5->Enabled=false;

N6->Enabled=false;

ToolButton3->Enabled=true;

ToolButton4->Enabled=false;

ToolButton5->Enabled=false;

Timer1->Enabled=false;

End=true;

for (int i=0; i<k; i++) M [i] =Mas [i];

Draw ();

}

}

}

// старт

void __fastcall TForm1:: N4Click (TObject *Sender)

{

if (N2->Checked)

{

if (End)

{

Init ();

Draw ();

End=false;

}

Timer1->Enabled=true;

Edit1->Enabled=false;

Edit2->Enabled=false;

UpDown1->Enabled=false;

UpDown2->Enabled=false;

N29->Enabled=false;

N4->Enabled=false;

N5->Enabled=true;

N6->Enabled=true;

ToolButton3->Enabled=false;

ToolButton4->Enabled=true;

ToolButton5->Enabled=true;

}

else

{

Init ();

char *Distrib=new char [120];

Distrib [0] =0;

StrCat (Distrib, "Распределение шариков по ячейкам: ");

for (int w=0; w<k; w++)

{

StrCat (Distrib, IntToStr (M [w]). c_str ());

StrCat (Distrib, " ");

}

StatusBar1->Panels->Items [0] - >Text=Distrib;

delete Distrib;

Draw ();

}

}

void __fastcall TForm1:: ToolButton3Click (TObject *Sender)

{

if (N2->Checked)

{

if (End)

{

Init ();

Draw ();

StatusBar1->Panels->Items [0] - >Text="";

End=false;

}

Timer1->Enabled=true;

Edit1->Enabled=false;

Edit2->Enabled=false;

UpDown1->Enabled=false;

UpDown2->Enabled=false;

N29->Enabled=false;

N4->Enabled=false;

N5->Enabled=true;

N6->Enabled=true;

ToolButton3->Enabled=false;

ToolButton4->Enabled=true;

ToolButton5->Enabled=true;

}

else

{

Init ();

char *Distrib=new char [120];

Distrib [0] =0;

StrCat (Distrib, "Распределение шариков по ячейкам: ");

for (int w=0; w<k; w++)

{

StrCat (Distrib, IntToStr (M [w]). c_str ());

StrCat (Distrib, " ");

}

StatusBar1->Panels->Items [0] - >Text=Distrib;

delete Distrib;

Draw ();

}

}

// уменьшение скорости движен // увеличение скорости движен // изменение скорости при помощи ползунка

void __fastcall TForm1:: TrackBar1Change (TObject *Sender)

{

dt=50-TrackBar1->Position;

Timer1->Interval=dt;

period=len*dt;

}

// пауза

void __fastcall TForm1:: N5Click (TObject *Sender)

{

N4->Enabled=true;

N5->Enabled=false;

ToolButton3->Enabled=true;

ToolButton4->Enabled=false;

Timer1->Enabled=false;

}

void __fastcall TForm1:: ToolButton4Click (TObject *Sender)

{

N4->Enabled=true;

N5->Enabled=false;

ToolButton3->Enabled=true;

ToolButton4->Enabled=false;

Timer1->Enabled=false;

}

// стоп

void __fastcall TForm1:: N6Click (TObject *Sender)

{

N4->Enabled=true;

N5->Enabled=false;

N6->Enabled=false;

ToolButton3->Enabled=true;

ToolButton4->Enabled=false;

ToolButton5->Enabled=false;

Timer1->Enabled=false;

Edit1->Enabled=true;

Edit2->Enabled=true;

UpDown1->Enabled=true;

UpDown2->Enabled=true;

N29->Enabled=true;

for (int i=0; i<k; i++) M [i] =Mas [i];

char *Distrib=new char [120];

Distrib [0] =0;

StrCat (Distrib, "Распределение шариков по ячейкам: ");

for (int w=0; w<k; w++)

{

StrCat (Distrib, IntToStr (M [w]). c_str ());

StrCat (Distrib, " ");

}

StatusBar1->Panels->Items [0] - >Text=Distrib;

delete Distrib;

End=true;

Draw ();

}

void __fastcall TForm1:: ToolButton5Click (TObject *Sender)

{

N4->Enabled=true;

N5->Enabled=false;

N6->Enabled=false;

ToolButton3->Enabled=true;

ToolButton4->Enabled=false;

ToolButton5->Enabled=false;

Timer1->Enabled=false;

Edit1->Enabled=true;

Edit2->Enabled=true;

UpDown1->Enabled=true;

UpDown2->Enabled=true;

N29->Enabled=true;

for (int i=0; i<k; i++) M [i] =Mas [i];

char *Distrib=new char [120];

Distrib [0] =0;

StrCat (Distrib, "Распределение шариков по ячейкам: ");

for (int w=0; w<k; w++)

{

StrCat (Distrib, IntToStr (M [w]). c_str ());

StrCat (Distrib, " ");

}

StatusBar1->Panels->Items [0] - >Text=Distrib;

delete Distrib;

End=true;

Draw ();

}

// Увеличение расстояния между шарами

void __fastcall TForm1:: ToolButton9Click (TObject *Sender)

{

if (len<H) len+=10;

period=len*dt;

}

void __fastcall TForm1:: N13Click (TObject *Sender)

{

if (len<H) len+=10;

period=len*dt;

}

// Уменьшение расстояния между шарами

void __fastcall TForm1:: ToolButton10Click (TObject *Sender)

{

if (len>3*r) len-=10;

if (len<3*r) len=3*r;

period=len*dt;

}

void __fastcall TForm1:: N14Click (TObject *Sender)

{

if (len>3*r) len-=10;

if (len<3*r) len=3*r;

period=len*dt;

}

// ---------------------------------------------------------------------------

void __fastcall TForm1:: UpDown1Click (TObject *Sender, TUDBtnType Button)

{

Edit1->Text=UpDown1->Position;

UpDown2->Max=UpDown1->Position*UpDown1->Position;

}

// ---------------------------------------------------------------------------

void __fastcall TForm1:: UpDown2Click (TObject *Sender, TUDBtnType Button)

{

Edit2->Text=UpDown2->Position;

}

// ---------------------------------------------------------------------------

void __fastcall TForm1:: Edit1Exit (TObject *Sender)

{

int kol;

if (StrToInt (Edit1->Text) <UpDown1->Min)

{

Edit1->Text=IntToStr (UpDown1->Min);

ShowMessage ("Число ячеек не меньше "+IntToStr (UpDown1->Min) +"!");

}

if (StrToInt (Edit1->Text) >UpDown1->Max)

{

Edit1->Text=IntToStr (UpDown1->Max);

ShowMessage ("Число ячеек не больше "+IntToStr (UpDown1->Max) +"!");

}

kol=StrToInt (Edit1->Text);

UpDown1->Position=kol;

if (UpDown2->Position>kol*kol)

{

UpDown2->Position=kol*kol;

Edit2->Text=IntToStr (kol*kol);

}

UpDown2->Max=kol*kol;

}

// ---------------------------------------------------------------------------

void __fastcall TForm1:: Edit2Exit (TObject *Sender)

{

if (StrToInt (Edit2->Text) <UpDown2->Min)

{

Edit2->Text=IntToStr (UpDown2->Min);

ShowMessage ("Число шариков не меньше "+IntToStr (UpDown2->Min) +"!");

}

if (StrToInt (Edit2->Text) >UpDown2->Max)

{

Edit2->Text=IntToStr (UpDown2->Max);

ShowMessage ("При таком количесвте ячеек число шариков не больше "+IntToStr (UpDown2->Max) +"!");

}

UpDown2->Position=StrToInt (Edit2->Text);

}

// ---------------------------------------------------------------------------

void __fastcall TForm1:: FormResize (TObject *Sender)

{

if (Form1->Width>105) StatusBar1->Panels->Items [0] - >Width=Form1->Width-100;

else StatusBar1->Panels->Items [0] - >Width=5;

ResizePicture ();

Draw ();

Form1->Constraints->MinHeight=1.3*Form1->Width;

}

// ---------------------------------------------------------------------------

void __fastcall TForm1:: Timer2Timer (TObject *Sender)

{

StatusBar1->Panels->Items [1] - >Text=TimeToStr (Time ());

}

// ---------------------------------------------------------------------------

void __fastcall TForm1:: Edit1KeyPress (TObject *Sender, char &Key)

{

if ( (Key >='0') && (Key<='9') || (Key==VK_BACK)) return;

if (Key==VK_RETURN) Edit2->SetFocus ();

else Key=0;

}

// ---------------------------------------------------------------------------

void __fastcall TForm1:: Edit2KeyPress (TObject *Sender, char &Key)

{

if ( (Key >='0') && (Key<='9') || (Key==VK_BACK)) return;

if (Key==VK_RETURN) Edit1->SetFocus ();

else Key=0;

}

// ---------------------------------------------------------------------------

void __fastcall TForm1:: N20Click (TObject *Sender)

{

ToolBar1->Visible=! ToolBar1->Visible;

CoolBar1->Visible=! CoolBar1->Visible;

ResizePicture ();

Draw ();

}

// ---------------------------------------------------------------------------

void __fastcall TForm1:: N21Click (TObject *Sender)

{

StatusBar1->Visible=! StatusBar1->Visible;

ResizePicture ();

Draw ();

}

// ---------------------------------------------------------------------------

void __fastcall TForm1:: N19Click (TObject *Sender)

{

TAbout *About=new TAbout (this);

About->ShowModal ();

delete About;

}

// ---------------------------------------------------------------------------

void __fastcall TForm1:: N17Click (TObject *Sender)

{

if (! TeorOpened)

{

Teory=new TTeory (Application);

try

{

Teory->RichEdit1->Lines->LoadFromFile ("Теория/Распределение Максвелла. rtf");

}

catch (EFOpenError&)

{

ShowMessage ("Отсутствует файл теории!");

return;

}

TeorOpened=true;

Teory->Show ();

}

else

{

Teory->Visible=true;

Teory->SetFocus ();

}

}

// ---------------------------------------------------------------------------

void __fastcall TForm1:: FormActivate (TObject *Sender)

{

if (! Activated)

{

M_Init=false;

dt=10;

TrackBar1->Position=50-dt;

UpDown1->Position=StrToInt (Edit1->Text);

UpDown2->Position=StrToInt (Edit2->Text);

if (Form1->Width>105) StatusBar1->Panels->Items [0] - >Width=Form1->Width-100;

else StatusBar1->Panels->Items [0] - >Width=5;

len=50;

Init ();

ColorDialog1->Color= (TColor) RGB (255,218,119);

ColorDialog2->Color= (TColor) RGB (255,153,85);

ColorDialog3->Color= (TColor) RGB (52,134,224);

ColorDialog4->Color=clRed;

char *Distrib=new char [120];

Distrib [0] =0;

StrCat (Distrib, "Распределение шариков по ячейкам: ");

for (int w=0; w<k; w++)

{

StrCat (Distrib, IntToStr (M [w]). c_str ());

StrCat (Distrib, " ");

}

StatusBar1->Panels->Items [0] - >Text=Distrib;

delete Distrib;

}

Draw ();

Activated=true;

}

// ---------------------------------------------------------------------------

void __fastcall TForm1:: N25Click (TObject *Sender)

{

exit (0);

}

// ---------------------------------------------------------------------------

void __fastcall TForm1:: N23Click (TObject *Sender)

{

ColorDialog1->Execute ();

Draw ();

}

// ---------------------------------------------------------------------------

void __fastcall TForm1:: N26Click (TObject *Sender)

{

ColorDialog2->Execute ();

Draw ();

}

// ---------------------------------------------------------------------------

void __fastcall TForm1:: N27Click (TObject *Sender)

{

ColorDialog3->Execute ();

Draw ();

}

// ---------------------------------------------------------------------------

void __fastcall TForm1:: N28Click (TObject *Sender)

{

ColorDialog4->Execute ();

Draw ();

}

// ---------------------------------------------------------------------------

void __fastcall TForm1:: N29Click (TObject *Sender)

{

TParams *Params=new TParams (this);

Params->ShowModal ();

delete Params;

}

// ---------------------------------------------------------------------------

void __fastcall TForm1:: N16Click (TObject *Sender)

{

if (! HelpOpened)

{

Help=new THelp (Application);

try

{

Help->RichEdit1->Lines->LoadFromFile ("Справка/Справка. rtf");

}

catch (EFOpenError&)

{

ShowMessage ("Отсутствует файл справки!");

return;

}

HelpOpened=true;

Help->Show ();

}

else

{

Help->Visible=true;

Help->SetFocus ();

}

}

// ---------------------------------------------------------------------------

Листинг фрагмента Unit1. h

void TForm1:: Draw ();

void TForm1:: DrawPanel (int x, int y);

void TForm1:: Init ();

void TForm1:: ResizePicture ();

void TForm1:: DrawBall (int x, int y);

void TForm1:: DeleteBall (int x, int y);

void TForm1:: LowBalls ();

__fastcall TForm1 (TComponent* Owner);

float alfa; // угол наклона треугольников в радианах

int a; // высота столбика

int b; // ширина столбика

int k; // число ячеек

int N; // число шариков

int *M; // массив, в котором хранятся количества шариков, попавших в каждую из ячеек, и получающийся в процессе падения

int *Mas; // аналогичный массив, заполняемый с помощью формулы

int max; // максимальное число шариков в ячейке

int r; // радиус падающих шариков

int l; // высота нижней части доски

int h; // высота одной панели

int ramka; // ширина рамки

int H; // высота всей доски

bool M_Init; // проверка предыдущего заполнения массива

int t; // текущее время

int dt; // приращение времени

int period; // время между запусками шаров

int dz; // шаг перемещения шаров

bool End; // все достигли конца

int z0; // начальная ордината шариков

int c; // высота "шапки" панели

int dh; // дополнительное прращение по высоте

int started; // номер шарика стартовавшего последним на данный момент

int len; // коэффициент расстояния между шариками

bool TeorOpened; // проверка: открывалась ли теория

bool HelpOpened; // проверка: открывалась ли справка

bool Activated; // активирована ли форма

TColor BackColor; // цвет фона

struct BallProperty // свойства каждого из шариков

{

bool start; // начал движение

bool end; // закончил движение

int stage; // номер этажа

int z; // координата от начала текущего этажа

bool linear; // проверка: достигнут ли наклонный участок

bool Lstage; // достиг ли последнего этажа

int *turn; // массив поворотов

int OldX; // координата Х шарика в прошлый момент времени

int OldY; // координата Y шарика в прошлый момент времени

int number; // номер ячейки, в которую попадет шарик

};

Приложение 2

Листинг Unit2. cpp

// ---------------------------------------------------------------------------

#include <vcl. h>

#pragma hdrstop

#include "Unit2. h"

#include "Unit1. h"

// ---------------------------------------------------------------------------

#pragma package (smart_init)

#pragma resource "*. dfm"

TFLog *FLog;

// ---------------------------------------------------------------------------

__fastcall TFLog:: TFLog (TComponent* Owner)

: TForm (Owner)

{

}

// ---------------------------------------------------------------------------

void __fastcall TFLog:: Button1Click (TObject *Sender)

{

Form1->Visible=true;

Close ();

}

// ---------------------------------------------------------------------------

void __fastcall TFLog:: FormClose (TObject *Sender, TCloseAction &Action)

{

Action=caFree;

}

Приложение 3

Листинг Unit3. cpp

#include <vcl. h>

#pragma hdrstop

#include "Unit3. h"

// ---------------------------------------------------------------------------

#pragma package (smart_init)

#pragma resource "*. dfm"

TAbout *About;

// ---------------------------------------------------------------------------

__fastcall TAbout:: TAbout (TComponent* Owner)

: TForm (Owner)

{

}

// ---------------------------------------------------------------------------

void __fastcall TAbout:: Button1Click (TObject *Sender)

{

Close ();

} Приложение 4

Листинг Unit5. cpp

#include <vcl. h>

#pragma hdrstop

#include "Unit5. h"

#include "Unit1. h"

// ---------------------------------------------------------------------------

#pragma package (smart_init)

#pragma resource "*. dfm"

TParams *Params;

// ---------------------------------------------------------------------------

__fastcall TParams:: TParams (TComponent* Owner)

: TForm (Owner)

{

}

// ---------------------------------------------------------------------------

void __fastcall TParams:: FormActivate (TObject *Sender)

{

Label2->Caption="Количество ячеек для шариков ("+IntToStr (Form1->UpDown1->Min) +"-"+IntToStr (Form1->UpDown1->Max) +"): ";

Edit1->Text=Form1->Edit1->Text;

Edit2->Text=Form1->Edit2->Text;

TrackBar1->Position=Form1->TrackBar1->Position;

}

// ---------------------------------------------------------------------------

void __fastcall TParams:: Button2Click (TObject *Sender)

{

Close ();

}

// ---------------------------------------------------------------------------

void __fastcall TParams:: Edit1KeyPress (TObject *Sender, char &Key)

{

if ( (Key >='0') && (Key<='9') || (Key==VK_BACK)) return;

if (Key==VK_RETURN) Edit2->SetFocus ();

else Key=0;

}

// ---------------------------------------------------------------------------

void __fastcall TParams:: Edit2KeyPress (TObject *Sender, char &Key)

{

if ( (Key >='0') && (Key<='9') || (Key==VK_BACK)) return;

if (Key==VK_RETURN) Button1->SetFocus ();

else Key=0;

}

// ---------------------------------------------------------------------------

void __fastcall TParams:: Button1Click (TObject *Sender)

{

int kol;

if (StrToInt (Edit1->Text) <Form1->UpDown1->Min)

{

ShowMessage ("Число ячеек не меньше "+IntToStr (Form1->UpDown1->Min) +"!");

Edit1->SetFocus ();

return;

}

if (StrToInt (Edit1->Text) >Form1->UpDown1->Max)

{

Edit1->Text=IntToStr (Form1->UpDown1->Max);

ShowMessage ("Число ячеек не больше "+IntToStr (Form1->UpDown1->Max) +"!");

Edit1->SetFocus ();

return;

}

kol=StrToInt (Edit1->Text);

Form1->UpDown1->Position=kol;

if (Form1->UpDown2->Position>kol*kol)

{

Form1->UpDown2->Position=kol*kol;

Form1->Edit2->Text=IntToStr (kol*kol);

}

Form1->UpDown2->Max=kol*kol;

Form1->Edit1->Text=Edit1->Text;


Подобные документы

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

    контрольная работа [111,1 K], добавлен 27.08.2012

  • Разработка программы на языке Turbo Pascal, обеспечивающей работу пользователя в диалоговом режиме с возможностью выбора функций с помощью одноуровневого меню вертикального типа. Блок-схема и листинг программы, описание руководства пользователя.

    курсовая работа [1,5 M], добавлен 17.03.2014

  • Динамика движения материальной точки. Разработка программы, моделирующей траектории полета снаряда при стрельбе из пушки под заданным углом к горизонту. Ее структурная схема, системные требования к ней. Создание приложения в среде Borland C++Builder.

    курсовая работа [3,2 M], добавлен 10.06.2014

  • Разработка программного продукта (лабиринт с входом и выходом, состоящий из комнат) в среде разработки Borland C++ Builder 6. Требования пользователя к программному изделию. Программные ограничения, совместимость. Основные процессы разработки программы.

    курсовая работа [819,9 K], добавлен 14.01.2013

  • Определение необходимых модулей программы, структуры файла базы данных. Описание разработки программы, отладка и тестирование. Разработка приложения Organizer.exe, меню и руководство пользователя. Алгоритм обработки событий главного меню (расписания).

    курсовая работа [901,8 K], добавлен 11.02.2014

  • Визуальные компоненты среды разработки С++ Builder: форма, кнопка, надпись, изображение, многостраничная панель, таблица строк. Интерфейс программы автоматизации расчета численности рабочих. Окно для ввода исходных данных. Руководство пользователя.

    курсовая работа [480,7 K], добавлен 10.02.2012

  • Компиляция и использование модулей. Разработка интерфейса программы. Факторы, воздействующие на комфорт пользователя. Структура диалога типа меню и разработка экранных форм. Обоснование выбора типа подпрограмм для решения задачи. Текст программы.

    курсовая работа [30,1 K], добавлен 22.02.2014

  • Формирование строки статуса программы с помощью метода NewStatusDef. Формирование меню и программирование диалоговых запросов. Создание и использование групп с помощью процедуры GetClipRect. Диалоговое окно выбора режима. Обработка команд пользователя.

    курсовая работа [25,7 K], добавлен 23.12.2012

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

    курсовая работа [106,6 K], добавлен 16.06.2014

  • Borland и C++Builder 6.0 как совершенная интерактивная среда программирования на языке C++. Проектирование программы, глобальные переменные. Форма создания нового каталога. Объекты на Form Dialog Delete. Блок-схема взаимодействия компонентов программы.

    курсовая работа [836,2 K], добавлен 27.08.2014

Работы в архивах красиво оформлены согласно требованиям ВУЗов и содержат рисунки, диаграммы, формулы и т.д.
PPT, PPTX и PDF-файлы представлены только в архивах.
Рекомендуем скачать работу.