Читать книгу «Справочник Жаркова по проектированию и программированию искусственного интеллекта. Том 6: Программирование на Visual Basic искусственного интеллекта. Продолжение 2» онлайн полностью📖 — Валерия Алексеевича Жаркова — MyBook.
image

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

Создаём проект по обычной схеме: в VS в панели New Project в окне Project types выбираем тип проекта Visual Basic, Windows, в окне Templates выделяем шаблон Windows Forms Application, в окне Name записываем имя проекта Line и щёлкаем OK. Создаётся проект, появляется форма Form1 в режиме проектирования (рис. 21.9). Оставляем по умолчанию или проектируем форму, как подробно описано в параграфе “Методика проектирования формы”. За маркер увеличиваем размеры формы таким образом, чтобы в панели Properties (для Form1) в свойстве Size были значения, например, 880; 630. Устанавливаем белый цвет Window для фона формы в свойстве BackColor.

Для задания режимов и управления игрой воспользуемся каким-либо элементом управления или компонентом. Как и выше, с панели инструментов Toolbox переносим на форму элемент управления MenuStrip и щёлкаем по нему (ниже формы в режиме проектирования). На форме Form1 появляются окна с надписью Type Here (Печатайте здесь), в которые записываем команды сначала на английском языке:

File, New Game, Save, Load, Exit;

Score, Show Score, Calculate Avg;

Help, Help, About.

Теперь в панели Properties (для каждой команды) в свойстве Text изменяем английские команды на соответствующие русские:

Игра, Новая, Сохранить, Загрузить, Выход;

Очки, Показать, Рассчитать средние;

Помощь, Справка, О программе (рис. 21.10 – 21.12).


Рис. 21.9. Форма Form1 в режиме проектирования.

Рис. 21.10. Команды меню Игра. Рис. 21.11. Команды меню Очки. Рис. 21.12. Меню Помощь.

С панели инструментов Toolbox переносим на форму первую надпись Label. В панели Properties (для этого элемента) в свойстве Location устанавливаем координаты верхнего левого угла элемента 430; 124, в свойстве Name изменяем имя на lblName, в свойстве Font увеличиваем размер шрифта до 28, в свойстве Text записываем “Имя:”.

Правее на этой же горизонтали размещаем вторую надпись Label. В панели Properties (для этого элемента) в свойстве Location устанавливаем координаты верхнего левого угла элемента 568; 124, в свойстве Name изменяем имя на lblNameShow, в свойстве Font увеличиваем размер шрифта до 28, в свойстве Text записываем “игрока”.

Ниже размещаем третью надпись Label. В панели Properties (для этого элемента) в свойстве Location устанавливаем координаты верхнего левого угла элемента 430; 212, в свойстве Name изменяем имя на lblScore, в свойстве Font увеличиваем размер шрифта до 28, в свойстве Text записываем “Очки: ” (с пробелами для вывода очков в эти пробелы).

Ниже размещаем четвёртую надпись Label. В панели Properties (для этого элемента) в свойстве Location устанавливаем координаты верхнего левого угла элемента 430; 302, в свойстве Name изменяем имя на lblTime, в свойстве Font увеличиваем размер шрифта до 28, в свойстве Text записываем “Время: ” (с пробелами для вывода секунд, минут и часов в эти пробелы).

Ниже размещаем пятую надпись Label. В панели Properties (для этого элемента) в свойстве Location устанавливаем координаты верхнего левого угла элемента 430; 392, в свойстве Name изменяем имя на lblBallPreview, в свойстве Font увеличиваем размер шрифта до 28, в свойстве Text записываем “Следующие мячи:”.

Ниже размещаем первый графический элемент управления PictureBox. В панели Properties (для этого элемента) в свойстве Location устанавливаем координаты верхнего левого угла элемента 453; 477, в свойстве Size устанавливаем размеры 52; 52, в свойстве Name изменяем имя на picBallPre1.

Правее размещаем второй элемент PictureBox. В панели Properties (для этого элемента) в свойстве Location устанавливаем координаты верхнего левого угла элемента 510; 477, в свойстве Size устанавливаем размеры 52; 52, в свойстве Name изменяем имя на picBallPre2.

Правее размещаем третий элемент PictureBox. В панели Properties (для этого элемента) в свойстве Location устанавливаем координаты верхнего левого угла элемента 568; 477, в свойстве Size устанавливаем размеры 52; 52, в свойстве Name изменяем имя на picBallPre3.

Чтобы программа периодически через Interval времени дополняла поле игры новыми разноцветными мячами, с панели инструментов Toolbox переносим на форму (точнее, ниже формы) первый таймер Timer. В панели Properties (для этого таймера) в свойстве Name записываем имя tmr1, в свойстве Enabled оставляем заданное по умолчанию значение False, т.к. мы включим этот таймер в программе в нужном месте при помощи строки (Timer1.Enabled = True). А в свойстве Interval вместо заданных по умолчанию 100 миллисекунд задаём, например, значение 150 миллисекунд.

Чтобы после начала игры на форме шел отсчёт времени (Time), на форму переносим второй таймер Timer. В панели Properties (для этого таймера) в свойстве Name записываем имя tmr2, в свойстве Enabled оставляем заданное по умолчанию значение False, а в свойстве Interval задаём 1000 миллисекунд (равные 1 секунде).

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

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





Рис. 21.13. Панель Solution Explorer. Рис. 21.14. Панель Properties.

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

Для ввода в проект новой формы (для таблицы с результатами игры) в меню Project выбираем Add Windows Form, в панели Add New Item оставляем заданные по умолчанию параметры и щёлкаем кнопку Add. В ответ VS выводит новую форму Form2 и добавляет в панель Solution Explorer новый пункт Form2.vb. Эта форма Form2, которая должна выводиться после выбора команды Показать в меню Очки, будет проектироваться программно согласно приведённому далее коду.

С панели инструментов Toolbox переносим на форму Form2 (точнее, ниже формы) первый таймер Timer. В панели Properties (для этого таймера) в свойстве Enabled оставляем заданное по умолчанию значение False, т.к. мы включим этот таймер в программе в нужном месте при помощи строки (Timer1.Enabled = True). А в свойстве Interval вместо заданных по умолчанию 100 миллисекунд задаём, например, значение 20 миллисекунд.

Аналогично переносим на форму Form2 второй таймер Timer. В панели Properties (для этого таймера) в свойстве Enabled оставляем заданное по умолчанию значение False, а в свойстве Interval задаём 40 миллисекунд.

Аналогично добавляем в проект третью форму Form3, которая будет выводиться после выбора команды Справка в меню Помощь. На форме Form3 размещаем какой-либо элемент управления, например, TextBox, в который записываем справочную информацию, например, правила игры по описанной ранее методике.

Аналогично добавляется и проектируется следующая форма, которая должна выводиться после выбора команды “О программе” в меню Помощь.

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

21.4. Код программы

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

Imports System.IO 'Для класса StreamWriter.

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

Теперь в классе Form1 нашего проекта записываем следующие переменные и методы.

Листинг 21.1. Переменные и методы.

Const intBaseX As Integer = 10

Const intBaseY As Integer = 120

Dim Rand As New Random

'***

Dim playerName As String

Dim playerScore As Double

Dim playerTime As Integer

Dim DDScore As New DPaint

Dim DDTime As New DPaint

'***

Dim intFlag As Integer = -1

Dim flagMadeNew = 0

Dim posMoveTo As Integer

Dim MPBoxes(80) As MotionPic

Dim ThreeBI(2) As Integer

Dim ThreeBP(2) As Integer

Dim prePic(2) As PictureBox

Private Sub InitBoard(ByVal plName As String, _

ByVal plScore As Double, ByVal plTime As Integer)

playerName = plName

playerScore = plScore

playerTime = plTime

If flagMadeNew = 0 Then

Dim i As Integer

Dim intX = intBaseX + 2

Dim intY = intBaseY + 2

For i = 0 To 80

Dim MP As New MotionPic(New Size(36, 36), _

New Point(intX, intY))

MP.SizeMode = PictureBoxSizeMode.StretchImage

intX += 45

If (i + 1) Mod 9 = 0 Then

intY += 45

intX = intBaseX + 2

End If

AddHandler MP.Click, AddressOf Ball_Click

MPBoxes(i) = MP

Next

Me.Controls.AddRange(MPBoxes)

DDScore.width = lblScore.Height / 2 – 6

DDScore.thick = DDScore.width / 4

DDScore.position = New Point(lblScore.Width – _

(DDScore.width + 2) * 9, lblScore.Height / 2)

DDTime.width = lblTime.Height / 2 – 6

DDTime.thick = DDTime.width / 4

DDTime.position = New Point(lblTime.Width – _

(DDTime.width + 2) * 9, lblTime.Height / 2)

AddHandler lblScore.Paint, AddressOf LabelScore_Paint

lblScore.Refresh()

AddHandler lblTime.Paint, AddressOf LabelTime_Paint

lblTime.Refresh()

For i = 0 To 2

prePic(i) = New PictureBox

prePic(i).SizeMode = PictureBoxSizeMode.StretchImage

prePic(i).Size = New Size(16, 16)

prePic(i).Visible = False

Me.Controls.Add(prePic(i))

AddHandler prePic(i).Click, AddressOf PrePic_Click

prePic(i).BringToFront()

Next

Else

ResetBoard()

End If

lblNameShow.Text = playerName

If playerName.Length > 8 Then

lblNameShow.Text += " "

tmr1.Enabled = True

End If

tmr2.Enabled = True

DDScore.number = plScore

lblScore.Refresh()

DDTime.number = plTime

lblTime.Refresh()

PreShow()

End Sub

Private Sub FindSol(ByVal i As Integer)

If MPBoxes(i).Tag <> "" Or MPBoxes(i).Tag = "Here" Then

Return

Else

MPBoxes(i).Tag = "Here"

End If

Select Case TestABox(i)

Case 1

FindSol(1)

FindSol(9)

Case 2

FindSol(7)

FindSol(17)

Case 3

FindSol(71)

FindSol(79)

Case 4

FindSol(63)

FindSol(73)

Case 5

FindSol(i + 1)

FindSol(i + 9)

FindSol(i – 1)

Case 6

FindSol(i – 9)

FindSol(i – 1)

FindSol(i + 9)

Case 7

FindSol(i – 1)

FindSol(i – 9)

FindSol(i + 1)

Case 8

FindSol(i – 9)

FindSol(i + 1)

FindSol(i + 9)

Case Else

FindSol(i – 9)

FindSol(i + 9)

FindSol(i + 1)

FindSol(i – 1)

End Select

End Sub

Private Sub ResetAllTag()

For Each Pic As MotionPic In MPBoxes

If Pic.Tag = "Here" Then

Pic.Tag = ""

End If

Next

End Sub

Private Function TestABox(ByVal val As Integer)

Select Case val

Case 0 : Return 1

Case 8 : Return 2

Case 80 : Return 3

Case 72 : Return 4

Case 1 To 7 : Return 5

Case 73 To 79 : Return 7

Case 17, 26, 35, 44, 53, 62, 71 : Return 6

Case 9, 18, 27, 36, 45, 54, 63 : Return 8

Case Else : Return 0

End Select

End Function

'Serious trouble happened – think more

Private Function GiveThreeBalls() As Boolean

If ThreeBI(1) = -1 Then 'Review for Game over

Return False

Else

For i As Integer = 0 To 2

If ThreeBI(i) = -1 Then

Exit For

Else

If MPBoxes(ThreeBP(i)).MPState = BallState. _

NO_BALL And ThreeBP(i) <> posMoveTo Then

MPBoxes(ThreeBP(i)).Init(ThreeBI(i))

CalWin(ThreeBP(i))

End If

End If

Next

End If

RandomThreeBalls()

PreShow()

Return True

End Function

Private Function IsFullBoard() As Boolean

Dim i As Integer

For Each Pic As PictureBox In MPBoxes

If MPBoxes(i).MPState <> BallState.NO_BALL Then

i += 1

End If

Next

If i = 81 Then

Return True

Else

Return False

End If

End Function

Private Sub RandomThreeBalls()

Dim ArrL As New ArrayList

Dim i As Integer

Dim pos As Integer

Dim ind As Integer

For i = 0 To 80

If MPBoxes(i).MPState = BallState.NO_BALL Or _

MPBoxes(i).MPState = BallState.DESTROYING_BALL Then

ArrL.Add(i)

End If

Next

For i = 0 To IIf(ArrL.Count > 2, 2, ArrL.Count – 1)

pos = Rand.Next(0, ArrL.Count)

pos = CInt(ArrL(pos))

ArrL.Remove(pos)

ThreeBP(i) = pos

ind = Rand.Next(0, 12)

ind = (ind \ 2) * 2

ThreeBI(i) = ind

Next

For j As Integer = i To 2

ThreeBI(j) = -1

ThreeBP(j) = -1

Next

End Sub

'#Region "Check for Calculate Score"

Private Function CheckHor(ByVal pos As Integer) As Integer

Dim type As Integer = MPBoxes(pos).MPIndex

Dim i As Integer = (pos \ 9) * 9

Dim count As Integer

Dim startpos As Integer = i

Dim endpos As Integer = i

While i < (pos \ 9) * 9 + 9

If MPBoxes(i).MPIndex = type Then

endpos += 1

count = endpos – startpos

Else

If count > 4 Then

While MPBoxes(pos).MPState = _

BallState.ZOOMING_BALL

Application.DoEvents()

End While

For j As Integer = 0 To count – 1

MPBoxes(startpos + j).Destroy()

Next

Return count

End If

If i >= (pos \ 9) * 9 + 5 Then

Return count

End If

startpos = i + 1

endpos = i + 1

End If

i += 1

End While

If count > 4 Then

While MPBoxes(pos).MPState = BallState.ZOOMING_BALL

Application.DoEvents()

End While

For j As Integer = 0 To count – 1

MPBoxes(startpos + j).Destroy()

Next

Return count

End If

End Function

Private Function CheckVer(ByVal pos As Integer) As Integer

Dim type As Integer = MPBoxes(pos).MPIndex

Dim i As Integer = pos Mod 9

Dim count As Integer

Dim startpos As Integer = i

Dim endpos As Integer = i

While i < (pos Mod 9) + 73

If MPBoxes(i).MPIndex = type Then

endpos += 9

count = (endpos – startpos) / 9

Else

If count > 4 Then

While MPBoxes(pos).MPState = _

BallState.ZOOMING_BALL

Application.DoEvents()

End While

For j As Integer = 0 To count – 1

MPBoxes(startpos + j * 9).Destroy()

Next

Return count

End If

If i >= (pos Mod 9) + 36 Then

Return count

End If

startpos = i + 9

endpos = i + 9

End If

i += 9

End While

If count > 4 Then

While MPBoxes(pos).MPState = BallState.ZOOMING_BALL

Application.DoEvents()

End While

For j As Integer = 0 To count – 1

MPBoxes(startpos + j * 9).Destroy()

Next

Return count

End If

End Function

Private Function CheckLR(ByVal pos As Integer) As Integer

If pos = 5 Or pos = 6 Or pos = 7 Or pos = 8 Or pos = 15 _

Or pos = 16 Or pos = 17 _

Or pos = 25 Or pos = 26 Or pos = 35 Or pos = 45 _

Or pos = 54 Or pos = 55 _

Or pos = 63 Or pos = 64 Or pos = 65 Or pos = 72 _

Or pos = 73 Or pos = 74 Or pos = 75 Then

Return 0

End If

Dim type As Integer = MPBoxes(pos).MPIndex

Dim i As Integer = pos Mod 10

i = IIf(i = 8, 18, IIf(i = 7, 27, IIf(i = 6, 36, i)))

Dim count As Integer

Dim startpos As Integer = i

Dim endpos As Integer = i

Dim tempi As Integer = i + 1

Dim temp As Integer

If i < 9 Then

temp = 9 – i

Else

temp = 9 – (i \ 9)

End If

While i < tempi + (temp – 1) * 10

If MPBoxes(i).MPIndex = type Then

endpos += 10

count = (endpos – startpos) \ 10

Else

If count > 4 Then

While MPBoxes(pos).MPState = _

BallState.ZOOMING_BALL

Application.DoEvents()

End While

For j As Integer = 0 To count – 1

MPBoxes(startpos + j * 10).Destroy()

Next

Return count

End If

If i >= pos + 40 Then

Return count

End If

startpos = i + 10

endpos = i + 10

End If

i += 10

End While

If count > 4 Then

While MPBoxes(pos).MPState = BallState.ZOOMING_BALL

Application.DoEvents()

End While

For j As Integer = 0 To count – 1

MPBoxes(startpos + j * 10).Destroy()

Next

Return count

End If

End Function

Private Function CheckRL(ByVal pos As Integer) As Integer

If pos = 0 Or pos = 1 Or pos = 2 Or pos = 3 Or pos = 9 _

Or pos = 10 Or pos = 11 _

Or pos = 18 Or pos = 19 Or pos = 27 Or pos = 53 _

Or pos = 61 Or pos = 62 _

Or pos = 69 Or pos = 70 Or pos = 71 Or pos = 77 _

Or pos = 78 Or pos = 79 Or pos = 80 Then

Return 0

End If

Dim type As Integer = MPBoxes(pos).MPIndex

Dim i As Integer = pos Mod 8

If i = 0 Then

i = 8

ElseIf i < 4 Then

i = (i + 1) * 8 + i

ElseIf pos \ 8 >= 5 Then

i = 45

End If

Dim count As Integer

Dim startpos As Integer = i

Dim endpos As Integer = i

Dim tempi As Integer = i + 1

Dim temp As Integer

If i < 9 Then

temp = i + 1

Else

temp = 9 – (i \ 8)

End If

While i < tempi + temp * 8

If MPBoxes(i).MPIndex = type Then

endpos += 8

count = (endpos – startpos) \ 8

Else

If count > 4 Then

While MPBoxes(pos).MPState = _

BallState.ZOOMING_BALL

Application.DoEvents()

End While

For j As Integer = 0 To count – 1

MPBoxes(startpos + j * 8).Destroy()

Next

Return count

End If

If i >= pos + 32 Then

Return count

End If

startpos = i + 8

endpos = i + 8

End If

i += 8

End While

If count > 4 Then

While MPBoxes(pos).MPState = BallState.ZOOMING_BALL

Application.DoEvents()

End While

For j As Integer = 0 To count – 1

MPBoxes(startpos + j * 8).Destroy()

Next

Return count

End If

End Function

Private Function CalWin(ByVal pos As Integer) As Integer

Dim point As Integer = CheckHor(pos)

If point < 4 Then

point = CheckVer(pos)

End If

If point < 4 Then

point = CheckLR(pos)

End If

If point < 4 Then

point = CheckRL(pos)

End If

If point > 4 Then

Dim dpoint As Double = point * 100 + (dpoint \ 6) * 100

Dim n As Double = DDScore.number + dpoint

For i As Double = DDScore.number To n Step 10

DDScore.number = i

lblScore.Refresh()

Next

DDScore.number = n

Return point

Else

Return 0

End If

End Function

'#Region "Ball Event And Paint Board"

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

ByVal e As System.EventArgs)

CType(sender, MotionPic).Jump()

If CType(sender, MotionPic).MPState <> _

BallState.NO_BALL Then

If intFlag <> -1 Then

MPBoxes(intFlag).Jump()

End If

'intFlag = MPBoxes.IndexOf(MPBoxes, sender)

'Исправляем предупреждение:

intFlag = Array.IndexOf(MPBoxes, sender)

ElseIf intFlag <> -1 Then

Dim tempS As String = MPBoxes(intFlag).Tag

MPBoxes(intFlag).Tag = ""

FindSol(intFlag)

If sender.tag = "Here" Then

'posMoveTo = MPBoxes.IndexOf(MPBoxes, sender)

'Исправляем предупреждение:

posMoveTo = Array.IndexOf(MPBoxes, sender)

If posMoveTo = ThreeBP(0) Then

prePic(0).SendToBack()

ElseIf posMoveTo = ThreeBP(1) Then

prePic(1).SendToBack()

ElseIf posMoveTo = ThreeBP(2) Then

prePic(2).SendToBack()

End If

CType(sender, MotionPic).Init(MPBoxes(intFlag). _

MPIndex)

MPBoxes(intFlag).Destroy()

While MPBoxes(intFlag).MPState = _

BallState.DESTROYING_BALL

Application.DoEvents()

End While

If CalWin(posMoveTo) = 0 Then

If GiveThreeBalls() = False Then

playerScore = DDScore.number

Dim frm As Form2 = New Form2

frm.AddPlayer() = _

New Player(playerName, playerScore)

frm.Show()

frm.PlashScreen()

frm.drawTable()

ResetBoard()

End If

End If

PreShow()

intFlag = -1

Else

MPBoxes(intFlag).Tag = tempS

End If

ResetAllTag()

End If

End Sub

Private Sub ResetBoard()

ThreeBI(0) = -1

tmr1.Enabled = False

tmr2.Enabled = False

playerScore = 0

playerTime = 0

DDScore.number = 0

DDTime.number = 0

Me.Refresh()

PreShow()

lblNameShow.Text = ""

1
...
...
9