Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
VB.doc
Скачиваний:
0
Добавлен:
01.05.2025
Размер:
7.65 Mб
Скачать

0.4.Какие бывают массивы

Массивы бывают не только числовые, но и строковые и типа Date и прочие. Подходит любой известный нам тип. Например:

Dim s(1 To 50) As String

Это означает, что в каждой из 50 ячеек должно находиться не число, а произвольная строка. Вот элементарный пример использования строкового массива:

Dim s(1 To 50) As String

Private Sub Command1_Click()

s(21) = "Привет": Debug.Print s(21)

End Sub

Вот пример работы с массивами других типов:

Dim b(1 To 30, 1 To 6) As Boolean

Dim DT(1 To 10) As Date

Private Sub Command1_Click()

b(2, 3) = False: Debug.Print b(2, 3)

DT(2) = #1/15/2156 11:59:42 PM#: Debug.Print DT(2)

End Sub

Еще пример:

Private Enum типРуль

вверх

влево

вниз

вправо

End Enum

Dim Руль(1 To 300) As типРуль

Private Sub Command1_Click()

Руль(200) = вправо: Debug.Print Руль(200)

Руль(220) = влево: Debug.Print Руль(220)

End Sub

Здесь будут напечатаны числа 3 и 1, так как элементы перечислимого типа пронумерованы по порядку от 0.

Границы индексов в круглых скобках тоже могут быть разными, например:

Dim a(20 To 60) As Integer

Здесь под числа отводится 41 ячейка. Еще пример:

Dim b(0 To 9, -20 To 30) As Integer

Здесь под числа отводится 10*51=510 ячеек.

Раз вы объявили границы индексов, то должны их придерживаться. Так, неправильно было бы теперь написать a(15) = 0.

Если нижняя граница индекса вашего массива равна нулю, то вы можете сэкономить усилия и вместо

Dim f(0 To 9) As Integer

писать

Dim f(9) As Integer

так как Visual Basic по умолчанию считает нижней границей индекса всех массивов число 0. Если же вам хочется, чтобы эта льгота касалась массивов с нижней границей равной не 0, а 1, то наверху программы напишите

Option base 1

Массивы могут быть одномерные, двумерные, трехмерные, четырехмерные и т.д.:

Dim a (1 To 10) As Integer

-одномерный массив

10 ячеек

Dim a (1 To 10, 1 To 5) As Integer

-двумерный массив

50 ячеек

Dim a (1 To 10, 1 To 5, 1 To 2) As Integer

-трехмерный массив

100 ячеек

Dim a (1 To 10, 1 To 5, 1 To 2, 1 To 3) As Integer

-четырехмерный массив

300 ячеек

0.5.Использование массивов при программировании игр

Какая польза от массивов при программировании игр? Вряд ли хоть одну «умную» игру можно запрограммировать без применения массивов. Возьмем хотя бы «крестики-нолики» на поле размером 3 на 3. Вам придется рисовать на экране большие клетки, а в них – нолики (кружочки) после ваших ходов и крестики (пересекающиеся косые линии) после ходов компьютера. Но этого недостаточно. Чтобы компьютер не поставил случайно крестик в занятом поле, он должен хотя бы знать, в каких клетках крестики и нолики уже стоят. Анализировать для этого информацию о пикселах экрана очень неудобно. Гораздо разумнее заранее организовать Dim a (1 To 3, 1 To 3) As Integer и записывать туда в нужные места нолики после ходов человека и, скажем, единички после ходов компьютера. Сразу же после записи в массив 0 или 1 программа должна рисовать в соответствующем месте экрана кружок или крестик. Мыслить компьютер мог бы при помощи примерно таких операторов – if a(1,1)=0 And a(1,2)=0 Then a(1,3)=1. Это очевидный защитный ход компьютера - на два кружочка в ряду он ставит в тот же ряд крестик.

Проиллюстрируем эту идею подробнее на специально придуманном примитивном примере (типа морского боя).

Задание на создание игры: Играют друг против друга два человека на квадратном поле размером 2 на 2:

Компьютер в игре участвует только как судья. Сначала первый игрок тайком от второго сообщает компьютеру, в каких двух клетках находятся его одноклеточные корабли (например, в правой верхней и правой нижней). Затем второй производит два выстрела (наугад – например, в левую верхнюю и правую нижнюю клетки). Если подбиты оба корабля - он выиграл, если один - ничья, если ни одного - проиграл.

Сначала запрограммируем эту игру без графики.

Поле боя после двух выстрелов будет показано на экране в следующем виде:

м к

о х

Здесь я использовал такие обозначения:

о - корабля здесь нет и сюда не стреляли

к - неподбитый корабль

х - подбитый корабль

м - мимо (стреляли и промахнулись)

Других вариантов быть не может. До окончания игры поле на экране не показывается.

Вот программа:

Dim a(1 To 2, 1 To 2) As String * 1 'Поле боя

Dim i As Integer

Dim j As Integer

Dim Подбито As Integer

______________________________________________________________________

Private Sub Command1_Click() 'Главная процедура

a(1, 1) = "о": a(2, 1) = "о" 'Поначалу на поле боя кораблей нет

a(1, 2) = "о": a(2, 2) = "о"

Устанавливаем_корабль 1

Устанавливаем_корабль 2

Подбито = 0 'Пока не стреляли

Выстрел 1

Выстрел 2

'Показываем поле боя после битвы:

For i = 1 To 2

For j = 1 To 2

Debug.Print a(i, j);

Next j

Debug.Print

Next i

Debug.Print Подбито 'Показываем исход битвы

End Sub

______________________________________________________________________

Private Sub Устанавливаем_корабль(Номер_корабля As Integer)

i = InputBox("Первый игрок, назовите номер строки корабля " & Номер_корабля)

j = InputBox("Первый игрок, назовите номер столбца корабля " & Номер_корабля)

a(i, j) = "к"

End Sub

______________________________________________________________________

Private Sub Выстрел(Номер_выстрела As Integer)

i = InputBox("Второй игрок, назовите номер строки для выстрела " & Номер_выстрела)

j = InputBox("Второй игрок, назовите номер столбца для выстрела " & Номер_выстрела)

If a(i, j) = "к" Then 'Если попал, то

a(i, j) = "х" 'ставим крестик

Подбито = Подбито + 1 'и увеличиваем счетчик подбитых кораблей

ElseIf a(i, j) = "о" Then 'иначе если промахнулся, то

a(i, j) = "м" 'ставим м

End If

End Sub

Пояснения касательно Dim a(1 To 2, 1 To 2) As String * 1 :

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

Определение победителя оставляю вам.

Когда готова и работает программа без графики, можно подумать о том, как оживить ее графическими изображениями. Эффективнее всего создать единую процедуру, которая сначала оператором Cls все стирает с экрана, а затем все рисует снова согласно новым значениям массива a. Например, рисует во весь экран пустое поле из 4 клеток и тут же их заполняет: скажем, ставит маленькие кружочки туда, куда стреляли и промахнулись, красит красным клетки с подбитыми кораблями и синим - с неподбитыми. Для заполнения достаточно в написанном уже фрагменте, показывающем поле

For i = 1 To 2

For j = 1 To 2

Debug.Print a(i, j);

Next j

Debug.Print

Next i

вместо Debug.Print a(i, j) написать некий код такого примерно смысла:

If a(i, j) = "х" Then Крась_красным i j

If a(i, j) = "к" Then Крась_синим i j

If a(i, j) = "м" Then Рисуй_кружок i j

Здесь мы видим три процедуры с параметрами i и j, от значения которых зависят координаты кружочков на форме и закрашиваемых квадратов. Зависимость эту продумайте сами.

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

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]