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

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

Так или «примерно так» звучат задачи из этой серии….

Доска Гальтона (как в материальном, так и в виртуальном виде) при высокой точности изготовления (а умельцев, слава богу, во все времена хватало) демонстрирует «НОРМАЛЬНОЕ РАСПРЕДЕЛЕНИЕ» во всей его красе. Мы не знаем, как будет вести себя любой отдельный шар, но мы знаем, как будет себя вести «большое множество шаров».

Если взять тысячу шаров, то лишь единичные из них отклонятся от своей первоначальной траектории настолько, что попадут в боковые отсеки (полюса). Большая же часть ляжет в центральные карманы. Если один колышек сбивал их вправо, следующий направлял влево и так далее. Это явление называется «нормальным распределением» и широко используется в теории вероятностей.

программа Доска Гальтона

Нормальное распределение – это такой же мощный закон, как, допустим, гравитационное притяжение. Даже наша жизнь очень напоминает доску Гальтона. Черная полоса в жизни, как правило, сменяется белой. Человека качает из стороны в сторону, но бьет не до смерти. Отдельные личности, конечно, становятся маргиналами-бомжами или, напротив, миллионерами. Но, сами знаете, большинство из нас, поободрав бока о житейские «препятствия», рано или поздно останавливаются в умеренной зоне (т.е. вдали от полюсов).

Ну, «теории» достаточно… Пора дробить поставленную задачу на части…

Раз на экране должны двигаться шары – значит не обойтись без мультипликации.
Раз будет мультипликация, значит, будут сменяющие друг друга, кадры.
Каждый очередной кадр должен показать шары с их новыми координатами (чуть ниже предыдущего местоположения, а правее или левее, как бог-случай даст).
Понятно, что воронка, упоры и стаканы, на всех кадрах – это МОНУМЕНТЫ. Поэтому их целесообразно поместить на отдельный bipmap, а каждый кадр получать, изображая нужные шары на копии этого фонового рисунка.

Сколько в воронке шаров я показываю только числом. Сколько шаров в каждом стакане – цифрами и пропорциональной величины прямоугольником красного цвета. А вот все движущиеся шары нужно прорисовывать конкретно. Так сколько же их будет? Какого размера массив создавать (под движущиеся шары)?

Безусловно, количество, одновременно движущихся шаров, зависит от количества стаканов (число которых, пусть задается пользователем). На единицу меньшим, чем количество стаканов, будет количество упоров в самом нижнем ряду. Да и количество рядов упоров будет таким же (на единицу меньшим, чем количество стаканов). Количество движущихся шаров целесообразно сделать меньше или равным количеству стаканов, допуская, что одновременно будет показываться шар над самым верхним упором или шар ниже последнего ряда упоров. Большее число одновременно движущихся шаров будет мешать зрительному восприятию траектории движения каждого отдельного шара.

const S_ARR=20; //максимальный размер массива движущихся шаров

Данные движущегося шара я храню (и изменяю) в записи-структуре:

type shpt=Record //координаты шара и знак смещения (одно из трех значений -1 0 1)
     x, y, rnd: integer; //rnd изменяется случайно на каждом следующем упоре
end;

Описание массивов:
var
     glass:array of integer;
// массив стаканов (размерность устанавливает пользователь)
     shar:array [0..S_ARR-1] of shpt;
//массив движущихся в настоящий момент шаров

Перебор всех движущихся шаров производится в процедуре-обработчике события таймера, формируя очередной кадр:

procedure TForm1.Timer1Timer(Sender: TObject);
var i:integer;
begin
     inc(cou);
     for i:=0 to m-1 do OneStepShar(shar[i]);
    …
    …
end;

где m – количество движущихся шаров в настоящий момент (в начале процесса растет от 0 до определенного числа, а после того как шары в воронке кончатся, начнет быстро убывать).

Таким образом, процедура OneStepShar(shar[i]) для каждого шара выполняет один очередной шаг, изменяя его координаты. Y постоянно увеличивается, т.к. шар движется вниз, а смещение по Х зависит от значения shar[i].rnd . В момент касания шаром упора знак смещения генерируется случайным образом:

if hod=3 then
begin
     hod:=0; inc(row);
     if(random(1000)<500)
     then
sh.rnd:=1
     else sh.rnd:= -1;
end;

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

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

скачать exe-файл для тестирования




Другие примеры на тему «Математические методы компьютерной 2D 3D графики»

Другие примеры на тему «Компьютерные игры (учебные, простенькие)»

Другие примеры на языке «Delphi»



Поделиться в соц сетях:




Если на этой странице не нашлось того, что Вы так искали...

         Не расстраивайтесь, не все потеряно... Смело щелкайте...

исходный код на заказ. orenstudent.ru Автоматизация документов MS Office. orenstudent.ru исходный код на заказ. orenstudent.ru Помогите найти и устранить ошибку в исходном коде программы. orenstudent.ru Skype-консультирование по программированию
Скайп-консультации

Акция !!!
исходный код комментарии цена минимальная


требуются
школьники!


и СТУДЕНТЫ!
Кому не плевать
на деньги!
Сайт помощи студентам по программированию и информатике

Program code