Тверской государственный университет
Опубликован: 13.09.2006 | Доступ: свободный | Студентов: 2720 / 260 | Оценка: 4.03 / 3.74 | Длительность: 19:48:00
Специальности: Программист, Менеджер
Лекция 7:

Организация диалога. Объект Assistant

< Лекция 6 || Лекция 7: 12345 || Лекция 8 >
Как Рокки ведет диалог?

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

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

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

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

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

Public StateOfPlay As String 'Состояние игры
Public Answer As MsoBalloonButtonType	'Выбор пользователя
'Другие общие параметры
Public WidthOfRiver	'Ширина реки
Public MyPath As String	 'каталог, хранящий исходный документ и другие файлы игры
Листинг 7.8.

Изменения внесены и в процедуру инициализации:

Public Sub InitialStates()
	'Задаем начальные состояния объектов и их образов
	StateOfMan = "LeftBank"
	StateOfWolf = "LeftBank"
	StateOfGoat = "LeftBank"
	StateOfCabbage = "LeftBank"
	StateOfBoat = "LeftBank"
	CountInBoat = 0
	StateOfPlay = "InitState"
	'Инициализация объектов формы
	With WGCForm
		.Man.Top = .LeftBank.Top + 15: .Man.Left = .LeftBank.Left + 10
		.Man.Visible = True
		.Wolf.Top = .LeftBank.Top + 80: .Wolf.Left = .LeftBank.Left + 10
		.Wolf.Visible = True
		.Goat.Top = .LeftBank.Top + 140: .Goat.Left = .LeftBank.Left + 10
		.Goat.Visible = True
		.Cabbage.Top = .LeftBank.Top + 200: .Cabbage.Left = .LeftBank.Left + 10
		.Cabbage.Visible = True
		
		.Boat.Top = .LeftBank.Top + 130: .Boat.Left = .LeftBank.Left + .LeftBank.Width
		.Boat.Visible = True
		WidthOfRiver = .Width - .LeftBank.Width - .RightBank.Width _
			- .Boat.Width
		'Поместить Рокки на остров
		Assistant.FileName = "Rocky.acs"
		'Debug.Print Assistant.Left, Assistant.Top
		Assistant.Move XLeft:=.Left + .Island.Left + .Island.Width / 2, _
			YTop:=.Top + .Island.Top + .Island.Height - 10
		Assistant.Animation = msoAnimationCharacterSuccessMajor
		'Assistant.AssistWithAlerts = False
		'Assistant.AssistWithHelp = False
		'Debug.Print Assistant.Left, Assistant.Top

	 
	    End With
	'Путь к каталогу
	MyPath = ActiveDocument.Path
	'Сформировать баллончики - диалоговые окна
	Call FormBalloons
	'Инициализировать диалог
	 Call Dialog1

End Sub
Листинг 7.9.

Я улучшил инициализацию, задав относительное расположение объектов, что позволяет менять размеры игрового поля, сохраняя взаимное расположение объектов. Наиболее серьезные дополнения выделены цветом фона. Как видите, здесь вводится объект Assistant и, используя метод Move, он помещается на свое место - остров, при этом задается его анимационное поведение. Далее вызываются две процедуры модуля Dialogs. В первой из них формируются объекты - баллончики разного типа, во второй - инициализируется начальный диалог Помощника, приглашающий к началу игры.

Других изменений в процедурах этого модуля не было, если не считать замены вызовов функции MsgBox на вызовы соответствующих функций модуля Dialogs, как, например, в процедуре TestingState:

Public Sub TestingState()
	'Тестирование состояний
	With WGCForm
	'Волк съел козу
	If (StateOfWolf = StateOfGoat) And (StateOfWolf  < > StateOfMan) Then
		.Goat.Visible = False
		'MsgBox Prompt:=Mes1 + vbCrLf + Mes3, Buttons:=vbCritical + vbOKOnly, Title:=Mes13
		Call Dialog5
		InitialStates
	End If
	'Коза съела капусту
	If (StateOfCabbage = StateOfGoat) And (StateOfCabbage  < < StateOfMan) Then
		.Cabbage.Visible = False
		'MsgBox Prompt:=Mes1 + vbCrLf + Mes4, Buttons:=vbCritical + vbOKOnly, Title:=Mes13
		Call Dialog6
		InitialStates
	End If
	'Слишком много пассажиров!
	If (CountInBoat > 2) Then
		If StateOfMan = "InBoat" Then .Man.Visible = False
		If StateOfWolf = "InBoat" Then .Wolf.Visible = False
		If StateOfGoat = "InBoat" Then .Goat.Visible = False
		If StateOfCabbage = "InBoat" Then .Cabbage.Visible = False
		'MsgBox Prompt:=Mes1 + vbCrLf + Mes5, Buttons:=vbCritical + vbOKOnly, Title:=Mes13
		Call Dialog7
		InitialStates
	End If
	'Конец игры - Все пассажиры собрались на правом берегу
	If (StateOfMan = "RightBank") And (StateOfWolf = "RightBank") And _
		(StateOfGoat = "RightBank") And (StateOfCabbage = "RightBank") Then
		
		'MsgBox Prompt:=Mes2 + vbCrLf + Mes6, Buttons:=vbExclamation + vbOKOnly, Title:=Mes14
		Call Dialog8
	End If
	End With
End Sub
Листинг 7.10.

Приведем теперь текст модуля Dialogs:

Option Explicit
'Константы для организации диалогов
Public Const Mes1 = "Ужасно, нелепо и грустно! "
Public Const Mes2 = "Прекрасно, как славно,отлично! "
Public Const Mes3 = " Волк съел козу! "
Public Const Mes4 = " Коза съела капусту! "
Public Const Mes5 = " Лодка перевернулась и все утонули! "
Public Const Mes6 = " Вам это удалось! Все переправились!"
Public Const Mes7 = " Не удалось дотащить "
Public Const Mes8 = " Человека! "
Public Const Mes9 = " Волка! "
Public Const Mes10 = " Козу! "
Public Const Mes11 = " Капусту! "
Public Const Mes12 = " Повторите попытку! "
Public Const Mes13 = " Беда!"
Public Const Mes14 = " Радость! "
Public Const Mes15 = " Лодку! "
Public Const Txt1 = "Привет! Я Рокки." & vbCrLf _
	& "Щелкни по острову, если захочешь поговорить со мной."
Public Const Txt2 = "Волк, Коза и Капуста!"
'Public Const Txt3 = "{wmf " & MyPath & "\goat.wmf}"
'Public Const Txt4 = "{wmf " & MyPath & "\cabbage.wmf}"
Public Const Txt5 = ""

'Массив баллончиков - диалоговых окон Рокки
Public RockyBalloons(1 To 10) As Balloon
Public Sub Dialog()
	'Начальный диалог при открытии игры
	 'Анализ состояния игры
	 Select Case StateOfPlay
		Case "InitState"
			Call Dialog1
		Case "State1"
			Call Dialog2
		Case "State2"
			Call Dialog9
		Case "StateFinish"
			Call Dialog10
		Case Else
	 End Select
		
End Sub
Public Sub OneBall()
	Dim Text1 As String, Text2 As String, Text3 As String
	Dim Text4 As String, Text5 As String
	Dim MyPath As String
	MyPath = ActiveDocument.Path
	'Формирование свойства Text
		Text1 = "Хочешь знать, как перевезти с берега на берег"
'		Вставка графики в середину текста
		Text2 = "{wmf " & MyPath & "\wolf.wmf}" & " Волка," & vbCrLf
		Text3 = "{wmf "& MyPath & "\goat.wmf}" & " Козу" & "	И "
		Text4 = "{wmf " & MyPath & "\cabbage.wmf}" & " Капусту?" & vbCrLf & vbCrLf
		'Text5 = "Соблюдая 3 правила?"
	Dim FirstBall As Balloon
	Set FirstBall = Assistant.NewBalloon
	With FirstBall
		.Heading = "Волк, Коза и Капуста"
		.Icon = msoIconAlert
		.Text = Text1 & Text2 & Text3 & Text4
		.Button = msoButtonSetYesNo
		.Show
	End With
End Sub


Public Sub FormBalloons()
	'Инициализация баллончиков
	Dim I As Integer
	For I = 1 To 10
		Set RockyBalloons(I) = Assistant.NewBalloon
		RockyBalloons(I).Heading = Txt2
		RockyBalloons(I).Icon = msoIconAlertInfo
	Next I
	FormBall1
	FormBall2
	FormBall3
	FormBall4
	FormBall5
	FormBall6
	FormBall7
	'FormBall8
End Sub
Public Sub FormBall1()
		'Формирование свойства Text - знакомство
		With RockyBalloons(1)
			.Text = Txt1
			.Button = msoButtonSetOK
		End With
End Sub

Public Sub Dialog1()
	 RockyBalloons(1).Show
	 StateOfPlay = "State1"	 'Игра началась
End Sub
Public Sub FormBall2()
	Dim Text1 As String, Text2 As String, Text3 As String
	Dim Text4 As String, Text5 As String
	'Формирование свойства Text
		Text1 = "Нужно срочно перевезти с берега на берег"
'		Вставка графики в середину текста
		Text2 = "{wmf " & MyPath & "\wolf.wmf}" & " Волка," & vbCrLf
		Text3 = "{wmf " & MyPath &"\goat.wmf}" & " Козу" & "	И "
		Text4 = "{wmf " & MyPath & "\cabbage.wmf}" & " Капусту?" & vbCrLf & vbCrLf
		Text5 = "Хочешь знать правила игры?"
		With RockyBalloons(2)
			.Text = Text1 & Text2 & Text3 & Text4 & Text5
			.Button = msoButtonSetYesNo
		End With
End Sub

Public Sub Dialog2()
	Answer = RockyBalloons(2).Show
	Select Case Answer
		Case msoBalloonButtonYes	'Нажата кнопка Yes
			'Показать правила игры
			Call Dialog3
		Case msoBalloonButtonNo	'Нажата кнопка No
			'Предложить начать играть
			Call Dialog4
	End Select
End Sub


Public Sub FormBall3()
	Dim Text1 As String, Text2 As String, Text3 As String
	Dim Text4 As String, Text5 As String
	'Формирование переменных Text
	Text1 = "В лодке, используемой для перевоза," & _
		" может находиться не более двух путников" & _
		" (человек, волк, коза и капуста - это путники)." & vbCrLf _
		& "При попытке посадить большее число путников лодка перевернется. "
	Text2 = "Если оставить	в лодке или на берегу волка и козу без присмотра человека," & _
		vbCrLf &"то волк немедленно съест козу."
	Text3 = "Если оставить в лодке или на берегу капусту и козу без присмотра человека," & _
		vbCrLf & "то коза немедленно съест капусту."
	Text4 = "Без человека лодка не может переплыть на другой берег."
	Text5 = "Начинайте играть! Желаю успеха!"
	With RockyBalloons(3)
		.BalloonType = msoBalloonTypeNumbers
		.Labels(1).Text = Text1
		.Labels(2).Text = Text2
		.Labels(3).Text = Text3
		.Labels(4).Text = Text4
		.Labels(5).Text = Text5
	End With
End Sub

Public Sub Dialog3()
	RockyBalloons(3).Show
	StateOfPlay = "State2"	 'Правила заданы
End Sub

Public Sub FormBall4()
	RockyBalloons(4).Text = "Начинайте играть! Желаю успеха!"
End Sub
Public Sub Dialog4()
	RockyBalloons(4).Show
	StateOfPlay = "State2"	 'Правила заданы
End Sub

Public Sub FormBall5()
	RockyBalloons(5).Icon = msoIconAlertCritical
	
End Sub
Public Sub Dialog5()
	RockyBalloons(5).Text = Mes1 + vbCrLf + Mes3
	RockyBalloons(5).Show
	StateOfPlay = "State1"	 'Начало игры
End Sub

Public Sub Dialog6()
	RockyBalloons(5).Text = Mes1 + vbCrLf + Mes4
	RockyBalloons(5).Show
	StateOfPlay = "State1"	 'Начало игры
End Sub
Public Sub Dialog7()
	RockyBalloons(5).Text = Mes1 + vbCrLf + Mes5
	RockyBalloons(5).Show
	StateOfPlay = "State1"	 'Начало игры
End Sub
Public Sub FormBall6()
	RockyBalloons(6).Icon = msoIconAlert
	RockyBalloons(6).Text = Mes2 + vbCrLf + Mes6
End Sub
Public Sub Dialog8()
	RockyBalloons(6).Show
	StateOfPlay = "StateFinish"	 'Конец игры
End Sub


Public Sub Dialog9()
	'Совет!
	
	'Rule1: Если волк и коза на одном берегу, то увези козу.
	'Rule2: Если капуста и коза на одном берегу, то увези капусту.
		If (StateOfWolf = StateOfGoat) Then
			RockyBalloons(7).Text = "Увези козу!"
		ElseIf (StateOfCabbage = StateOfGoat) Then
			 RockyBalloons(7).Text = "Увези капусту!"
		Else
			RockyBalloons(7).Text = "Тут моя помощь не нужна!"
		End If
	RockyBalloons(7).Show
	
End Sub

Public Sub FormBall7()
	RockyBalloons(7).Icon = msoIconTip
End Sub
Public Sub Dialog10()
	RockyBalloons(6).Text = "Приходите, поиграем еще раз! Рокки будет ждать."
	RockyBalloons(6).Show
	StateOfPlay = "StateFinish"	 'Конец игры
End Sub
Листинг 7.11.

Я не буду комментировать процедуры этого модуля. Все что нужно было сказать, уже сказано. Отмечу только процедуру Dialog9, которая вызывается, когда Рокки должен дать совет. Заметьте, его интеллектуальность определяется двумя правилами типа "если… то". Если не выполняются условия ни одного из этих правил, то Рокки полагает, что ситуация очень простая и его советы не нужны, поскольку можно принимать любое решение, допустимое правилами игры.

На этом мы и закончим разговор об организации диалогов с использованием возможностей объекта Assistant.

< Лекция 6 || Лекция 7: 12345 || Лекция 8 >