Одномерные массивы

 

Допустим, у нас имеется сложный объект, у котрого много координат или по экрану должны двигаться много объектов, например, у вас пулемет, который стреляет очередями, да и врагов немало. Конечно, можно завести под каждый объект переменные, как мы это делали раньше. Но если объектов много, то и переменных будет очень много, как в них не запутаться? Кроме того, программа будет длинной, если по очереди рисовать все объекты. Эти действия похожи и хотелось бы использовать цикл. Но как это сделать, если координаты каждого объекта – различные перменные. Выход есть – массивы.

Массивы – это переменные Паскаля, которые используются для хранения таблиц. Например таблицу

 

1

2

3

4

5

Число

 

 

 

 

 

можно хранить в массиве, который описывается следующим образом

var a:array[1..5] of integer;

Таблица пока пуста, но в любую ячейку можно записать некоторое целое число. Каждая ячейка массива имеет свой номер - индекс. Например, номера ячеек массива a 1, 2, 3, 4, 5. Число, которое содержится в ячейке с номером i часто будем также называть элементом с номером i. В теле программы содержимое любой ячейки массива можно использовать, как обычную переменную, при этом нужно указывать имя массива и далее в квадратных скобках индекс ячейки в массиве. Например после выполнения операторов

a[2]:=11;

a[3]:=9;

a[4]:=a[2]+a[3];

В таблице будут записаны следующие числа

1

2

3

4

5

Число

 

11

9

20

 

Рассмотрим еще раз, как описывается массив

var a:array[1..20] of integer;

Ключевые слова в этой конструкции окрашены в синий цвет. Имя у массива может быть любое и записывается перед двоеточием, так же, как при описании любой переменной. Далее идет ключевое слово array – массив. Затем в квадратных скобках указываются два числа, между которыми лежат возможные значения индексов ячеек (в нашем случае ячейки имеют номера от 1 до 20). После слова of указывается тип данных, которые могут храниться в массиве. Запомните: во всех ячейках массива хрантяся однотипные переменные. Если массив of integer, то в его ячейках можно хранить целые числа. Большинство операций с массивом удобно проводить в цикле.

Пример 1. Прочитать с клавиатуры 10 целых чисел. Вывести их на экран в обратном порядке.

Решение. Сначала в цикле прочитаем все числа и запишем их в массив, а потом выведем элементы массива в обратном порядке.

Var i:integer;

A:array[1..10] of integer;

Begin

For i:=1 to 10 do

Begin

Write(‘input a[‘,i,’] ’);

Readln(a[i]);

End;

i:=10;

while i>0 do

begin

writeln(a[i]);

i:=i-1;

end;

End. 

Пример 2. Заполнить массив в соответствии с закономерностью 1, 2, 1, 2, 1….

Решение. Как видно из представленной закономерности, в ячейки с нечетными номерами нужно записать число 1, а в ячейки с четными – 2. Значит нужен цикл с условием.

var

a:array[1..20] of integer;

i:integer;

begin

for i:=1 to 20 do

if i mod 2=1 then a[i]:=1

else a[i]:=2;

writeln;

for i:=1 to 20 do write(a[i]);

end.

Генератор случайных чисел

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

x:=random(y);

Если вы собираетесь использовать функцию random в своей программе, то до ее первого использования необходимо выполнить процедуру randomize без параметров, которая устанавливает генератор в начальное состояние. Если не использовать randomize, то вызовы random будут все время выдавать одну и ту же последовательность чисел.

Пример 3. Заполнить массив случайными числами от 0 до 9 и вывести на экран его элементы через пробел.

Решение.

var a:array[1..20] of integer;

begin

randomize;

for i:=1 to 20 do a[i]:=random(10);

for i:=1 to 20 do write(a[i],’ ‘);

end.

Задачи

  1. Прочитать с клавиатуры элементы массива. Вывести на экран те элементы, индексы которых нечетны.
  2. Записать в ячейки массива последовательность вида 1,2,3,1,2,3,1,2,3,1,2,3,1,2,3…
  3. Заполнить массив случайными числами от 0 до 100 и вывести все элементы, которые лежат от 30 до 50.
  4. Заполнить массив случайными числами от 10 до 90 и вывести все элементы, которые лежат от 30 до 50.
  5. Ряд чисел образуется следующим образом. Сначала записывают числа 1 и 2. Каждое следующее число получается как сумма двух предыдущих. Вывести на экран первые 10 чисел ряда в порядке убывания.

Константы.

В примере 4 число 20 встречается во многих местах программы. Если его вдруг придется изменить, то легко запутаться. По этой причине имеет смысл дать числу 20 некоторое имя, а затем использовать это имя в программе. Для этих целей в паскале предусмотрен еще один тип объектов – константы. Константы имеют имя и значение и в этом смысле очень напоминают переменные. Два важнейших отличия констант:

  • значения констант нельзя изменять в программе
  • константы можно использовать вместо чисел в квадратных скобках при описании массива, а переменные – нельзя.

Для описания констант предусмотрен специальный раздел, который начинается со слова const и располагается до тела программы.

const n=10; k=5;

Рассмотрим использование константы на примере.

Пример 5. Массив из 20 элементов заполнить случайными числами от 0 до 99. Все элементы массива, меньшие 10, заменить нулями.

Решение.

const n=20;k=100;

var

a:array[1..n] of integer;

i,s:integer;

begin

randomize;

for i:=1 to n do a[i]:=random(k);

s:=0;

for i:=1 to n do if a[i]<10 then a[i]:=0;

writeln;

for i:=1 to n do write(a[i],’ ‘);

end.

Далее в задачах о массивах количество ячеек следует описывать как константу .

Задачи.

  1. Заполнить массив случайными числами от 0 до 100. Вывести элементы массива на экран. Все элементы массива, лежащие между 20 и 30 и между 50 и 60, уменьшить на 2.

Максимальный элемент массива

Сразу рассмотрим пример.

Пример 6. Заполнить массив случайными числами и вывести на экран наибольший элемент массива и его индекс.

Решение.

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

const n=20;

var

a:array[1..n] of integer;

i,imax:integer;

begin

randomize;

for i:=1 to n do a[i]:=random(100);

imax:=i;

for i:=2 to n do if a[i]>a[imax] then imax:=i;

writeln(‘максимальный элемент ’,a[imax]);

writeln(‘индекс максимального элемента’,imax);

end.

 

Задачи.

  1. Заполнить массив случайными числами. Вывести элементы массива на экран. Вывести на экран минимальный элемент массива.
  2. Заполнить массив случайными числами. Вывести элементы массива на экран. Вывести на экран разность между его максимальным и минимальным элементами.
  3. Заполнить массив случайными числами. Вывести элементы массива на экран. Заменить все его минимальные элементы нулями.

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

Теперь пришло время применить наши знания о массивах для программирования игр. Рассмотрим такую игру. По полю разбросаны золотые самородки. Игрок бегает по полю и собирает их. Если он «пробегает» по самородку на экране, у него растут очки. Их следует изображать в левом верхнем углу экрана.

Решение. Самородки по экрану нужно разбрасывать при помощи генератора случайных чисел. При этом координата x самородка – случайное число от 1 до 79, а координата y – число от 1 до 24. Самородков много, поэтому их координаты следует хранить в массивах. x[i] – координата x самородка с номером i, y[i] – у – координата. Перед игрой отображаем самородки на экране. Работаем в цикле. После этого при движении игрока на экране постоянно проверяем, не попал ли он на какой-нибудь самородок. Здесь тоже нужен цикл при знании текущей позиции игрока и координатам самородков. Если позиция игрока совпадает с координатой одного из самородков, добавляем игроку очки. Остается одна проблема. Если самородок найден, нужно сделать так, чтобы при повторном проходе по этому же месту очки не добавлялись. Для этого можно, например, завести еще один массив – taken, причем taken[i]=1, если самородок i уже взяли и 0 в противном случае. При этом при любых операциях с самородком i нужно проверять значение taken[i].

Задачи

  1. Реализовать описанную игру
  2. Игра становится более интересной и даже оригинальной, если мы к самородкам добавим бандитов, которые узнают о находке и устраивают в месте находки засаду. Таким образом, если игрок еще раз пройдет по месту, в котором был самородок, его деньги-очки обнуляются. Игра становится не очень простой, если после находки самородка место, где он ранее находился, никак не обозначается. Запрограммируйте.
  3. Игра еще более оживляется, если играют два конкурента. Попробуйте запрограммировать.
  4. Запрограммировать движение на экране n независимых объектов, отражающихся от стенок.
  5. Изменить предыдущую задачу: объект, вышедший за границу экрана, «входит» на экран с противоположной стороны. Подумайте, что при этом происходит с координатами?

Двумерные массивы.

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

var a:array[1..4,1..6] of integer;

Подпись: 
 
 
 

Смысл всех элементов конструкции такой же, как в одномерном массиве. Единственное отличие – добавился еще один индекс, который может изменяться от 1 до 6. Этому массиву будет соответствовать таблица из 4 строк и 6 столбцов

В теле программы содержимое таблицы можно изменить так

Подпись: 
3 
 2 
 

a[2,1]:=3;

i:=2;

a[i+1,4]:=a[2,1]-1;

Использование аналогично использованию одномерного массива. Единственное отличие – дополнительный индекс. После выполнения операций в массиве будет записана информация, показанная на рисунке. Поскольку у элементов массива два индекса, для работы с ним приходится использовать вложенные циклы.

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

Решение.

const n=5;m=6;

var a:array[1..n,1..m] of integer;

begin

randomize;

for i:=1 to n do

for j:=1 to m do

a[i,j]:=random(20);

for i:=1 to n do

begin

writeln;

for j:=1 to m do write(a[i,j]:3);

end;

end.

Обратите внимание: в операторе write после элемента массива стоит «:3». При использовании этой конструкции компьютер отведет под каждое выводимое число ровно 3 клетки на экране. В результате получится красивая таблица.

Задачи

  1. Заполнить двумерный массив нулями и единицами в шахматном порядке
  2. Вывести на экран самый большой элемент двумерного массива.
  3. Двумерный массив «of char» заполнить случайными маленькими буквами русского алфавита.

Использование двумерных массивов при создании игр

В двумерном массиве размера 25 на 80 удобно хранить состояние экрана. Зачем это нужно? Дело в том, что вы не можете так просто узнать, какой символ находится в той или иной клетке экрана. Например, как узнать, находится ли в клетке, в которую попал игрок, мина? Конечно, можно хранить координаты всех клеток с минами в одномерных массивах, как мы делали в предыдущем параграфе. Каждый раз нужно будет в цикле просматривать все массивы и проверять, есть ли в них координаты, совпадающие с текущими координатами игрока. Это не очень-то удобно. Рассмотрим теперь способ, использующий двумерный массив – копию экрана. Для того, чтобы выяснить, что содержится в клетке экрана с координатами (i,j), нужно просто проверить элемент массива a[i,j]. При этом, когда мы выводим на экран какую-нибудь информацию, следует эту же информацию записывать в массив. Массив может быть такой

var a:array[1..25,1..80] of char;

Программа становится проще. Потом мы узнаем еще более простые методы. Но это будет потом.

Задачи.

  1. Вы помните игру о самородках? Надеюсь, уже очевидно, что с двумерным массивом игровая программа становится гораздо проще. Но давайте ее усложним. Пусть у на экране будут не только самородки, но и бандиты, при попадании на которых у вас теряются все очки.
  2. Переделайте эту игру для двух игроков.
  3. Пусть теперь бандиты летают по экрану.
  4. Попробуйте теперь соорудить пулемет, который будет стрелять очередями. Может быть, короткими – по 3-4 патрона. Пулемет установить в нижней части экрана. А вверху пусть летят самолеты. Как-то бы еще имитировать попадание и взрыв. Не знаю, как. И добавить звуковые эффекты.

Вот мы прошли самые основы программирования и разработки компьютерных игр. Дальше-больше. В следующих частях мы должны будем научиться разрабатывать большие игры – очень большие. Научимся работать в коллективе и вместе создавать супер игры. Научимся сохранять результаты и не начинать всегда игру заново.