|
Моделирование бросания игральной кости в электронной таблице Microsoft ExcelОкончание. Начало см. “В мир информатики” № 106 / “Информатика” № 6/2008 Напомним, что в разрабатываемом проекте происходит моделирование средствами электронной таблицы Microsoft Excel многократного бросания игральной кости (кубика) с подсчетом количества выпадения того или иного числа на грани кости и представлением результатов подсчета в виде диаграммы. Проект получается очень эффектным, если предварить выпадение того или иного числа вращением кубика. Для этого найдем в Интернете (Можно также подготовить 7 изображений кубика, о которых пойдет речь далее, самостоятельно. — Прим. ред.) соответствующий анимированный рисунок в формате gif (http://www.sura.ru/dikov/Mybooks/stuff.htm). В языке программирования VBA (на котором написаны все наши процедуры), к сожалению, не предусмотрена возможность непосредственной работы с анимированными изображениями. Но зато на листе Excel можно использовать элементы управления Рисунок (Image), в которые можно помещать изображение. Этим мы и воспользуемся — вращение кубика будем имитировать путем последовательного показа отдельных кадров анимированного gif-изображения: Отдельные изображения-кадры можно получить из общего gif-рисунка с помощью, например, программы Adobe ImageReady CS. Допустим, что получилось 7 файлов-картинок (как на рисунке чуть выше). Создадим на листе электронной таблицы 7 экземпляров объекта Рисунок (с помощью кнопки на панели инструментов Элементы управления). В качестве значения свойства Picture укажем путь к соответствующему файлу-рисунку, тем самым мы загрузим в наш проект рисунки, и они в последующем будут храниться в одном файле вместе с таблицей. Установим значения свойств BackStyle, BorderStyle равными нулю, убрав таким образом фон и граничную линию. Значение свойства Visible у всех рисунков, кроме одного, изменим на False, чтобы сделать их невидимыми. Напишем процедуру, которая будет имитировать на экране вращение кубика, “включая” ненадолго скрытые картинки последовательно друг за другом и снова делая их невидимыми: Private Sub Бросить_кость() DIM i As Integer For i = 1 To p2 Image2.Visible = True Image2.Visible = False Image3.Visible = True Image3.Visible = False Image4.Visible = True Image4.Visible = False Image5.Visible = True Image5.Visible = False Image6.Visible = True Image6.Visible = False Image7.Visible = True Image7.Visible = False Image8.Visible = True Image8.Visible = False For j = 1 To p1 Next j Next i End Sub Переменная p2 задает число повторений анимационной последовательности, переменная p1 — задержку времени между показом каждой последовательности. Так как процедура Бросить_кость не является процедурой обработки события, то мы сами должны вызвать окно редактора кода (нажав одновременно клавиши и F11) и написать текст процедуры, в т.ч. ее заголовок и завершающую конструкцию End Sub. Вызов процедуры Бросить_кость разместим в начале созданной ранее процедуры Бросить_1_раз_Click(): Private Sub Бросить_1_раз_Click() Бросить_кость Randomize 'Моделируем бросание кубика … Здесь возникает проблема, связанная со следующим. Так как процедура Бросить_кость вызывается еще и через процедуру Бросить_1000_раз_Click, желательно для последней уменьшить значения времени ожидания p1 и числа повторений анимации p2, чтобы не ждать окончания процесса тысячекратного “бросания” кубика с его вращением. Решить ее можно так. Введем переменную сколько_раз, фиксирующую факт вызова процедуры Бросить_кость через процедуру Бросить_1000_раз_Click (в этом случае ее значение примем равным 1000), и в зависимости от ее значения будем задавать значения переменных p1 и p2: Private Sub Бросить_1_раз_Click() If сколько_раз = 1000 Then p1 = 0 p2 = 1 Else p1 = 300 p2 = 5 End If Бросить_кость … Значение переменной сколько_раз будем задавать в процедуре Бросить_1000_раз_Click: Private Sub Бросить_1000_раз_Click() DIM i As integer сколько_раз = 1000 For i = 1 To 1000 … Чтобы переменная сколько_раз была “видна” в процедуре Бросить_1_раз_Click, а переменные p1 и p2 — в процедуре Бросить_кость, их надо описать как глобальные — со служебным словом Public перед всеми процедурами (этот раздел кода называется General): Public сколько_раз, p1, p2 As Integer От редакции. Предлагаем читателям подумать над тем, как сделать так, чтобы глобальной была только одна переменная — сколько_раз, а переменные p1 и p2 описывались бы в процедуре Бросить_кость. Решения присылайте в редакцию. Для “полноты картины” после вращения будем показывать на листе изображение кубика, соответствующее выпавшему числу: С этой целью создадим шесть рисунков игральной кости с различными значениями на верхней грани. Для этого найдем в Интернете (http://www.sura.ru/dikov/Mybooks/stuff.htm) рисунок кубика в векторном формате и загрузим его, например, в программу Microsoft PowerPoint. В ней разгруппируем рисунок, после чего путем копирования и перемещения черных кружочков получим еще 5 нужных изображений. Сгруппируем элементы каждого изображения и сохраним рисунки в файле формата emf. Так же, как и для предыдущих рисунков, создадим на листе шесть экземпляров объекта Рисунок и загрузим туда полученные изображения из файлов. Дадим имена экземплярам g1, g2, …, g6. Установим в 0 значения свойств BackStyle, BorderStyle. Свойству Visible присвоим значением False. В конструкцию Select Case существующей процедуры Бросить_1_раз_Click добавим строки, “показывающие” изображение кубика, соответствующее выпавшему числу: Private Sub Бросить_1_раз_Click() …… Select Case выпало Case 1 Range("C4").Select g1.Visible = True Case 2 Range("C5").Select g2.Visible = True Case 3 Range("C6").Select g3.Visible = True Case 4 Range("C7").Select g4.Visible = True Case 5 Range("C8").Select g5.Visible = True Case 6 Range("C9").Select g6.Visible = True End Select Так как мы сделали видимой выпавшую грань игральной кости, то при следующем бросании необходимо ее скрыть. Сделаем это для всех граней в существующей процедуре Бросить_кость путем добавления в начало следующих строчек: Private Sub Бросить_кость() g1.Visible = False … g6.Visible = False … Теперь — все! От редакции. Нет — не все! :) Предлагаем читателям провести эксперимент по моделированию бросания кубика и определить значения общего количества выпадения того или иного числа на грани кости при большом (в несколько тысяч) числе испытаний. |