Самоучитель VBA

         

Цель урока



На примере простейшей компьютерной игры будет полностью разработано первое приложение в этой книге. Это приложение должно моделировать игру в орел и решку. Игрок вносит в банк определенную сумму денег. Во время игры нельзя добавлять деньги в банк. Игра состоит из последовательности шагов, которая, вообще говоря, может быть бесконечной. На очередном шаге игрок загадывает либо орел, либо решку. Компьютер "бросает монету". Если "монета падает той же стороной", которую загадал игрок, то банк увеличивается на единицу, в противном случае - уменьшается на единицу. Игра заканчивается либо по желанию игрока, либо когда величина банка становится нулем или больше 10 000. Игрок забирает себе содержимое банка. В приложении отслеживаются максимальные и минимальные суммы, которые были в банке в течение игры.

Конструируя данное приложение, вы на практике узнаете, как:

Создавать из формы диалоговое окно

Набирать код программы

Программировать контроль ввода, т. е. проверять вводятся ли в поля числа или строковая информация

Управлять запретом ввода данных в поле

Работать с функцией генератора случайных чисел

Выводить числовую информацию в поле

Запускать программы на выполнение



ПРАКТИЧЕСКИЕ ПРИЕМЫ ПРОГРАММИРОВАНИЯ НА VBA


ЧАСТЬ П. ПРАКТИЧЕСКИЕ ПРИЕМЫ ПРОГРАММИРОВАНИЯ НА VBA

УРОК 1. ТЕМА: ИГРА "ОРЕЛ И РЕШКА"

ЦЕЛЬ УРОКА

ТЕОРИЯ

ПРАКТИКА



САМОСТОЯТЕЛЬНОЕ ЗАДАНИЕ

Часть II.

Практические приемы программирования на VBA



Практика



Выберите команду Сервис, Макрос, Редактор Visual Basic (Tools, Macro, Edit Visual Basic), откроется окно редактора Visual Basic.

Выберите команду Вставить User Form (Insert UserForm).

Используя панель элементов и окно свойств, заполните пользовательскую форму элементами управления (рис. У1.1), создав требуемое диалоговое окно приложения.

Рис. У1.1. Вид редактора Visual Basic при создании пользовательской формы для игры в орел и решка

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

Private Sub CommandButtonl_Click() End Sub

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

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

' Переменные уровня модуля

'

Dim Банк As Long

Dim Партия As Long

Dim НомерМаксимум As Long

Dim НомерМинимум As Long

Dim Максимум As Long

Dim Минимум As Long

'

Private Sub CommandButtonl_Click()



' Определяет номер очередной партии

Партия = Партия + 1

' Запрещается изменение пользователем значения

' в поле Банк в течение игры

TektBoxl.Enabled = False

'

' Проверяется, являются ли вводимыми в поле Банк данные числом

If IsNumeric(TextBoxl.Text) = False Then

MsgBox "Введите ставку", vbExclamation, "Орел и решка"

TextBoxl.Enabled = True

TextBoxl.SetFocus

Exit Sub End If Банк = CLng(TextBoxl.Text)

' Проверяется, не превышает ли Банк максимально допустимую величину

If Банк > 10000 Or Банк <= 0 Then

MsgBox "Ставка должна быть в диапазоне [1,10000]", vbExclamation, "Орел и решка"

TextBoxl.Enabled = True TextBoxl.SetFocus

Exit Sub

End If

'

' Бросается монета

'

Randomize

Монета = Int(2'* Rnd)

' Сравнение результата бросания монеты компьютером

' с ситуацией, когда игрок загадал "орел"

'

If OptionButtonl.Value = True Then

If Монета = 0 Then

Банк = Банк - 1

TextBoxl,Text = CStr(BaHK)

End If

If Монета = 1 Then

Банк = Банк + 1

TextBoxl.Text = CStr(Банк)

End If

End If

' Сравнение результата бросания монеты компьютером

' с ситуацией, когда игрок загадал "решка"

If OptionButton2.Value = True Then

If Монета = 1 Then Банк = Банк - 1

TextBoxl.Text = CStr(Банк)

End If

If Монета = 0 Then Банк = Банк + 1

TextBoxl.Text = CStr(Банк)

End If

End If TextBox2.Text = CStr(Партия)

' Определяется, превышает ли текущее значение поля Банк максимальную

' величину

'

If Банк > Максимум Then

Максимум = Банк

НомерМаксимум = Партия

TextBox3.Text = CStr(Максимум)

TextBox5.Text = CStr(НомерМаксимум)

End If

' Определяется, превышает ли минимальное значение поля Банк текущее

' значение

'

If Банк < Минимум Then

Минимум = Банк

НомерМинимум = Партия

TextBox4.Text = CStr(Минимум)

TextBox6.Text = CStr(НомерМинимум)

End If

End Sub

'

Private Sub CommandButton2_Click()

'

' Процедура закрытия диалогового окна

'

UserForml.Hide End Sub



Private Sub UserForm_Initialize()

' Процедура инициализации диалогового окна

Максимум = 0

Минимум = 10000

Партия = 0

'

' Поле Банк доступно для ввода информации пользователем

' при инициализации диалогового окна

'

TextBoxl.Enabled = True

'

' Поля Партия, Максимум, Минимум и Игра не доступны для

' ввода информации пользователем

'

TextBox2.Enabled = False

TextBox3.Enabled = False

TextBox4 ..Enabled = False

TextBox5.Enabled = False

TextBox6.Enabled = False

' При инициализации диалогового окна выбран переключатель Орел

OptionButtonl.Value = True

End Sub

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



UserForm_Initialize



Активизирует диалоговое окно.

Поле Банк доступно для ввода информации пользователем при инициализации диалогового окна.

В поля Партия, Максимум, Минимум и Игра разрешен только программный ввод данных.

При инициализации диалогового окна выбран переключатель орел.



Нажатие кнопки

Бросание монеты

запускает на выполнение процедуру

CommandButton1 Click



В переменной партия учитывается номер очередной партии.

В поле Банк разрешен только программный ввод данных. Перед началом игры первой партии проверяется, является ли вводимое данное числом в диапазоне от 1 до 10 000. Если это условие не выполняется, отображается соответствующее сообщение (рис. У 1.2), предлагающее пользователю откорректировать данные. В поле Банк снова разрешен ввод данных пользователем. После чего происходит выход из процедуры для повтора ввода данных.

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



Нажатие кнопки Отмена запускает на выполнение процедуру

CommandButton2 Click



Закрывает диалоговое окно.

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



На экране появится диалоговое окно игры. Игрок вводит в поле Банк сумму денег, и потом, выбирая соответствующий переключатель в группе выбор, загадывает орел или Решка. Нажатие кнопки Бросание монеты приводит к подбрасыванию компьютером монеты. Текущий счет игрока отображается в поле Банк. В поле партия выводится номер текущей партии, а в полях максимум и минимум выводятся максимальный и минимальный счет игрока втечение предыдущих партий. На рис. У 1.3 приведено диалоговое окно орел-решка на 30-м ходе игры при начальном банке в 100 единиц. Отображаемая информация в диалоговом окне Орел-Решка показывает, что 30 партий изнурительной игры принесли игроку выигрыш только в 2 единицы. Если бы игрок не жадничал и остановил игру на 18 ходе, то его выигрыш был бы в два раза больше. А если бы игрок струсил, когда стал проигрывать, и вышел из игры на 3 ходе, то его проигрыш составил бы 3 единицы.



Рис. У1.2. Возможное сообщение о неправильном вводе данных в поле Банк



Рис. У1.3. Диалоговое окно Орел-Решка




Самостоятельное задание


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



Теория



Для моделирования бросания монеты потребуется генератор случайных чисел. Функция Rnd возвращает случайное число типа single из диапазона [0,1). Это приятное известие, что в VBA имеется генератор случайных чисел из диапазона [0,1). Но нам-то надо, чтобы моделировался процесс бросания монеты и с равной вероятностью генерировались два числа, скажем, 1 для орла и 0 для решки. На самом деле, этого легко достичь, рассматривая вместо Rnd функцию Int(2*Rnd). Функция int отбрасывает дробную часть аргумента и возвращает его целую часть. По аналогии с помощью функции Int (6*Rnd) +1 можно моделировать бросание игральной кости.