Справочник Жаркова по проектированию и программированию искусственного интеллекта. Том 6: Программирование на Visual Basic искусственного интеллекта. Продолжение 2 - Жарков Валерий Алексеевич 8 стр.


Dim PlayerName As String = s.Split(CChar(";"))(0)

Dim PlayerScore As String = s.Split(CChar(";"))(1)

ArrPlayer.Add(New Player(PlayerName, PlayerScore))

Next

FSR.Close()

Exit Sub

newScore:

ArrPlayer.Add(New Player("AAA", "5000"))

ArrPlayer.Add(New Player("AAA", "4500"))

ArrPlayer.Add(New Player("AAA", "4000"))

ArrPlayer.Add(New Player("AAA", "3500"))

ArrPlayer.Add(New Player("AAA", "3000"))

ArrPlayer.Add(New Player("AAA", "2500"))

ArrPlayer.Add(New Player("AAA", "2000"))

ArrPlayer.Add(New Player("AAA", "1500"))

ArrPlayer.Add(New Player("AAA", "1000"))

ArrPlayer.Add(New Player("AAA", "500"))

End Sub

Public Sub SaveScore()

LoadScore()

For i As Integer = 0 To 9

If CDbl(AddedPlayer.PlayerScore) >= _

CDbl(CType(ArrPlayer(i), Player).PlayerScore) Then

ArrPlayer.Insert(i, AddedPlayer)

Exit For

End If

Next

Dim FSW As New StreamWriter("Score.dat")

Dim s As String = "#Assignment Line#"

s += Chr(13) + Chr(10)

For i As Integer = 0 To 9

s += CType(ArrPlayer(i), Player).PlayerName + ";" + _

CType(ArrPlayer(i), Player).PlayerScore

s += Chr(13) + Chr(10)

Next

FSW.Write(s)

FSW.Close()

End Sub

Public Sub PlashScreen()

Me.BackgroundImage = Image.FromFile("GameOver.gif")

Application.DoEvents()

Threading.Thread.Sleep(2000)

End Sub

Ниже формы Form2 дважды щёлкаем по значку первого таймера Timer. Появляется шаблон метода, который после записи нашего кода принимает следующий вид.

Листинг 21.13. Метод-обработчик события Tick.

Private Sub Timer1_Tick(ByVal sender As System.Object, _

ByVal e As System.EventArgs) Handles Timer1.Tick

gr = CreateGraphics()

midPoint = New Point(Me.Width \ 2, 10)

Dim strText As String = "Score Board"

Dim fnt As New Font("Microsoft Sans Serif", 30, _

FontStyle.Bold, GraphicsUnit.Point)

Dim strSize As New SizeF(gr.MeasureString(strText, fnt))

Dim ptfGradientStart As New _

PointF(intCurrentGradientShift, 0)

Dim ptfGradientEnd As New PointF(0, intCurrentGradientRow)

lbrTitle = New LinearGradientBrush(ptfGradientStart, _

ptfGradientEnd, Color.SteelBlue, Color.Brown)

startPoint = New PointF(midPoint.X _

CInt(strSize.Width / 2), midPoint.Y)

gr.DrawString(strText, fnt, lbrTitle, startPoint)

ptfGradientStart = New PointF(0, intCurrentGradientShift)

ptfGradientEnd = New PointF(intCurrentGradientRow, 0)

lbrTitle = New LinearGradientBrush(ptfGradientEnd, _

ptfGradientStart, Color.MediumSlateBlue, _

Color.GhostWhite)

gr.DrawString(strText, fnt, lbrTitle, startPoint.X 2, _

startPoint.Y + 2)

intCurrentGradientShift += intGradiantStep

If intCurrentGradientShift = 400 Then

intGradiantStep = -5

ElseIf intCurrentGradientShift = -400 Then

intGradiantStep = 5

End If

End Sub

Ниже формы Form2 дважды щёлкаем по значку второго таймера Timer. Появляется шаблон метода, который после записи нашего кода принимает следующий вид.

Листинг 21.14. Метод-обработчик события Tick.

Private Sub Timer2_Tick(ByVal sender As System.Object, _

ByVal e As System.EventArgs) Handles Timer2.Tick

'showScore()

Dim g As Graphics = CreateGraphics()

Dim fnt As New Font("Courier New", 20, FontStyle.Bold, _

GraphicsUnit.Point)

Dim startPoint As PointF = New PointF(20, 80)

Dim nextPoint As PointF = _

New PointF(startPoint.X + colW1, 80)

Dim ptfGradientStart As New PointF(intCurrentGradientRow, _

startPoint.X)

Dim ptfGradientEnd As New PointF(nextPoint.Y, _

intCurrentGradientRow)

lbrBoard = New LinearGradientBrush(ptfGradientStart, _

ptfGradientEnd, Color.GreenYellow, Color.SlateGray)

Dim PlayerNames As String = "Name" + Chr(13) + Chr(10)

Dim PlayerScores As String = "Score" + Chr(13) + Chr(10)

For i As Integer = 0 To 9

PlayerNames += CType(ArrPlayer(i), Player).PlayerName _

+ Chr(13) + Chr(10)

PlayerScores += CType(ArrPlayer(i), Player).PlayerScore _

+ Chr(13) + Chr(10)

Next

g.DrawString(PlayerNames, fnt, lbrBoard, startPoint)

g.DrawString(PlayerScores, fnt, lbrBoard, nextPoint)

intCurrentGradientRow += intGradiantStep

End Sub

В случае необходимости, методика добавления в проект звукового сигнала Beep (по-русски: Бип) описана ранее.

21.5. Запуск игры


Строим и запускаем программу на выполнение обычным образом:

Build, Build Selection; Debug, Start Without Debugging.

В ответ Visual Studio выводит показанную выше форму, на которой в отдельных квадратах сетки, например, 9 x 9 сначала произвольным образом (при помощи генератора случайных чисел г.с.ч. класса Random) искусственный интеллект выводит определённое количество, в данной игре 3, разноцветных объекта, например, 3 больших мяча, которые игрок может перемещать при помощи мыши, и 3 маленьких разноцветных мяча, которые размещает искусственный интеллект, чтобы помешать игроку построить прямую линию из мячей (так как в клетку с маленьким мячом большой мяч уже нельзя разместить).

Игрок периодически щёлкает по выбранному им мячу и по клетке, в которую мяч перемещается. А искусственный интеллект периодически размещает в пустующие клетки следующие 3 больших мяча произвольных цветов.

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

По методике данной главы можно разрабатывать самые разнообразные игры с использованием искусственного интеллекта по сборке линий одного цвета из разноцветной палитры разнообразных фигур.

Часть X. Методология программирования искусственного интеллекта в ролевых сюжетных играх


Глава 22. Методика программирования искусственного интеллекта в сюжетных играх на примере сюжета о пещерных людях Адаме и Еве


22.1. Общие сведения


Опишем методику проектирования и программирования типичной и распространённой ролевой (Role-playing game RPG) сюжетной игры и использованием искусственного интеллекта, когда игрок в роли пещерного человека Адама собирает на земле горящие факелы для Евы (чтобы согреть её в пещере).

Данную игру мы будем разрабатывать, следуя проекту в заархивированном виде CaveManHank.zip (Пещерный человек Хэнк) автора Ivo Salmre от 27.6.2002 с сайта gotdotnet.com для устаревшей версии Visual Studio, причём, для карманного компьютера (КПК), но с нашими усовершенствованиями для современной версии Visual Studio, причём для настольного компьютера или планшета.

В панели Solution Explorer (нашего будущего проекта) или в папке с именем проекта дважды щёлкаем по имени графического файла Hank_FacingForward1.bmp (загруженного, например, из Интернета) для изображения пещерного мужчины с именем Хэнк (у нас он будет зваться, как Адам). Появляется собственный графический редактор Visual Studio с изображением этого мужчины, причём инструментами этого редактора можно редактировать это изображение (рис. 22.1) применительно к нашим задачам.

Аналогично в панели Solution Explorer дважды щёлкаем по имени графического файла Jane_FacingForward1a.bmp для изображения пещерной женщины с именем Джейн (у нас она будет зваться, как Ева). Появляется редактор Visual Studio с изображением этой женщины (рис. 22.2). Аналогично можно открыть и редактировать остальные графические файлы проекта.





Рис. 22.1. Пещерный мужчина Адам. Рис. 22.2. Пещерная женщина Ева.

Как уже и ранее было рассказано, и в этой методической игре поле игры состоит из нескольких слоёв (layers) изображений.

Нижний слой это фоновое изображение (фоновая картинка). Оно рисуется только один раз в начале выполнения программы.

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

В главном (переднем) слое находятся динамические изображения, которые изменяются от кадра к кадру и за счёт этого перемещаются на экране. Они должны рисоваться каждый раз, когда обновляются анимированные изображения.

Другие пояснения этой игры можно найти (если необходимо) в книгах с сайта ZharkovPress.ru.

22.2. Правила игры

1. После запуска игры на экране появляется форма с пользовательским интерфейсом игры (рис. 22.3).



Рис. 22.3. Начало игры.

Слева в верхней части экрана мы видим индикатор энергии Адама, которая уменьшается по мере течения времени.

Правее находятся надпись Очки: 0 и Бонус в виде начального времени, которое стремительно уменьшается.

Ниже расположен рисунок, на котором Ева кричит Адаму: Bring me fire!!! (Принеси мне огонь).

Левее находится рисунок Адама с озабоченным видом.

Ниже мы видим указание игроку, управляющему изображением Адама: Соберите факелы и принесите Еве.

Управление Адамом состоит в том, чтобы щёлкать по экрану указателем мыши в том месте экрана, куда должен идти Адам, чтобы взять факел. После каждого щелчка появляется пунктирная линия, показывающая, куда пойдёт Адам.

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

Очки засчитываются за каждый собранный факел данного уровня, за оставшееся время бонуса и за энергию игрока, оставшуюся в конце каждого уровня.

Адам потеряет энергию, если он будет поражён валуном или птицей. Адам будет подскакивать, чтобы не быть поражённым этими объектами. Адам также потеряет энергию, если он упадёт с большой высоты.

Звучит мелодия начала игры.

2. Через несколько секунд поясняющая надпись Соберите факелы и принесите Еве исчезает (чтобы не заслонять игровое поле).

3. Щёлкаем указателем мыши в том месте формы, куда должен идти Адам, чтобы взять факел. После каждого щелчка появляется пунктирная линия, показывающая, куда пойдёт Адам.

Например, щёлкаем по первому факелу, который расположен по горизонтали справа от Адама. На этом пути нет настилов, поэтому Адам без помех берет этот факел, и игроку начисляются 200 очков (рис. 22.4)



Рис. 22.4. Игроку начислено 200 очков.

4. К другим факелам подойти не так просто, так как мешают настилы. И Адам может пройти к факелам только через промежутки в настилах и по лестницам.

Щёлкаем указателем мыши в промежутках между настилами и по лестницам, указывая Адаму путь к факелам.

Мы взяли ещё один факел и получили 500 очков (рис. 22.5).



Рис. 22.5. Игроку начислено 500 очков.

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

Мы не успели нажать клавишу пробела, Адам не подпрыгнул и был сбит валуном. Энергия у Адама закончилась (на индикаторе вверху), и игра тоже закончилась (рис. 22.6).

Звучит мелодия окончания игры.

6. Для начала новой игры следует нажать кнопку Новая игра.

7. Если нам нужна справка о правилах игры, то щёлкаем кнопку Помощь. Последовательно появляются несколько библиотечных панелей MsgBox с записанными нами в программу текстами (рис. 22.7 22.9).

8. Если в игре участвует несколько человек, то победителем считается тот, кто набрал большее количество очков.

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

И, естественно, в качестве графических изображений объектов и звуковых файлов игры можно использовать файлы различных форматов (с внесением соответствующих изменений в приведённую далее программу).



Рис. 22.6. Игра закончена.



Рис. 22.7. Первая часть справки.



Рис. 22.8. Вторая часть справки.



Рис. 22.9. Третья часть справки.

22.3. Создание проекта


Создаём проект по обычной схеме: в VS в панели New Project в окне Project types выбираем тип проекта Visual Basic, Windows, в окне Templates выделяем шаблон Windows Forms Application, в окне Name записываем имя проекта HankTheCaveMan и щёлкаем OK.

Так как, в отличие от указанного выше оригинала, в нашем проекте при загрузке графических файлов имя проекта будет определяться в программе, то сейчас в окне Name можно записать любое имя. Создаётся проект, появляется форма Form1 в режиме проектирования (рис. 22.10). Оставляем по умолчанию или проектируем форму, как подробно описано в параграфе Методика проектирования формы. Например, в панели Properties (для Form1) в свойстве Font увеличиваем размер шрифта до 10. За маркеры увеличиваем размеры формы таким образом, чтобы в свойстве Size были, например, такие величины: 405; 456.

С панели инструментов Toolbox переносим в нижнюю часть формы элемент управления типа окна текста TextBox.

Ниже размещаем кнопку Button с номером 1. В панели Properties (для этого элемента) в свойстве Text записываем Новая игра.

Правее размещаем кнопку Button. В панели Properties (для этого элемента) в свойстве Name записываем ButtonNextLevel, а в свойстве Text записываем Уровень.

Правее размещаем кнопку Button. В панели Properties (для этого элемента) в свойстве Name записываем buttonInstructions, а в свойстве Text записываем Помощь.

Свойства и формы, и этих элементов управления можно изменять, как описано ранее.

Переносим таймер Timer. В панели Properties (для этого невидимого на форме компонента) в свойстве Name записываем timerGame, в свойстве Enabled выбираем True, а свойству Interval задаём значение 40 миллисекунд, что соответствует 25 кадрам в секунду по стандарту телевещания России.

Теперь добавляем в проект графические файлы по обычной схеме: в панели Solution Explorer выполняем правый щелчок по имени проекта, в контекстном меню выбираем Add, Existing Item (или Project, Add Existing Item), в панели Add Existing Item в окне Files of type выбираем All Files, в центральном окне находим (например, в папке с загруженными из Интернета файлами) и с нажатой клавишей Ctrl выделяем файлы и щёлкаем кнопку Add, чтобы после этого добавления в панели Solution Explorer были файлы, показанные на рис. 22.9.

В панели Solution Explorer выделяем все графические файлы (с нажатой клавишей Ctrl), а в панели Properties в свойстве Build Action (Действие при построении) вместо заданного по умолчанию выбираем значение Embedded Resource (Встроенный ресурс) для всех этих файлов.

Если в игре применяются несколько звуковых файлов, то их целесообразно разместить в одной папке с именем, например, Sounds. Для добавления в проект этой папки, в панели Solution Explorer выполняем правый щелчок по имени проекта, в контекстном меню выбираем Add, New Folder, в поле появившегося значка папки записываем имя папки и нажимаем клавишу Enter.

Добавляем в эту папку звуковые файлы по стандартной схеме: выполняем правый щелчок по имени этой папки, в контекстном меню выбираем Add, Existing Item, в панели Add Existing Item в окне Files of type выбираем All Files, в центральном окне находим (например, в папке с загруженными из Интернета файлами) и с нажатой клавишей Ctrl выделяем файлы и щёлкаем кнопку Add. В панели Solution Explorer мы увидим эти файлы.





Рис. 22.10. Форма Form1 в режиме проектирования. Рис. 22.11. Панель Solution Explorer.

22.4. Код и запуск программы


Открываем файл Form1.vb (например, по схеме: File, Open, File) и в самом верху импортируем пространства имён для управления соответствующими классами:

Назад Дальше