Цель урока
На примере простейшей компьютерной игры будет полностью разработано первое приложение в этой книге. Это приложение должно моделировать игру в орел и решку. Игрок вносит в банк определенную сумму денег. Во время игры нельзя добавлять деньги в банк. Игра состоит из последовательности шагов, которая, вообще говоря, может быть бесконечной. На очередном шаге игрок загадывает либо орел, либо решку. Компьютер "бросает монету". Если "монета падает той же стороной", которую загадал игрок, то банк увеличивается на единицу, в противном случае - уменьшается на единицу. Игра заканчивается либо по желанию игрока, либо когда величина банка становится нулем или больше 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 |
Закрывает диалоговое окно. |
||
На экране появится диалоговое окно игры. Игрок вводит в поле Банк сумму денег, и потом, выбирая соответствующий переключатель в группе выбор, загадывает орел или Решка. Нажатие кнопки Бросание монеты приводит к подбрасыванию компьютером монеты. Текущий счет игрока отображается в поле Банк. В поле партия выводится номер текущей партии, а в полях максимум и минимум выводятся максимальный и минимальный счет игрока втечение предыдущих партий. На рис. У 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 можно моделировать бросание игральной кости.