СПО в российских школах

Команда ALT Linux рассказывает о внедрении свободного программного обеспечения в школах России
Январь 28, 2011

BASIC-256. Глава 13

Методические материалы
Автор: Владимир Черный

Продолжаем публиковать перевод книги Джеймса Рено. Эту главу перевел Владимир Черный.
Оглавление:

Где взять BASIC-256

Глава 13 Массивы — коллекции данных

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

Одномерный числовой массив.

Одномерный массив создает список в памяти так, что вы можете обращаться к его элементам по числовому адресу, называемому индексом. Массивы могут быть как числовыми, так и строковыми в зависимости от типа переменной, использованной в операторе dim.

1 # numeric1d.kbs
2
3 dim a(10)
4
5 a[0] = 100
6 a[1] = 200
7 a[3] = a[1] + a[2]
8
9 input "Введите число: ", a[9]
10 a[8] = a[9] - a[3]
11
12 for t = 0 to 9
13     print "a[" + t + "] = " + a[t]
14 next t

Программа 66 Одномерный числовой массив

Введите число: 63
a[0] = 100
a[1] = 200
a[2] = 0
a[3] = 200
a[4] = 0
a[5] = 0
a[6] = 0
a[7] = 0
a[8] = -137
a[9] = 63

Примерный вывод программы 66 Одномерный числовой массив

dim variable(количество_элементов)
dim variable$(количество_элементов)
dim variable(количество_рядов, количество_столбцов)
dim variable$(количество_рядов, количество_столбцов)

Оператор dim создает массив в оперативной памяти компьютера размером равном указанному в скобках и именем variable или variable$ (можно задать свое). Размер массива (количество элементов, строк и рядов) должно быть целым положительным числом.

Оператор dim автоматически назначает значение элементам массива равное нулю (0), если массив числовой или равное пустой строке (""), если массив строковый.

variable[номер_элемента]
variable[номер_строки, номер_столбца]
variable$[номер_элемента]
variable$[номер_строки, номер_столбца]

где variable или variable$ — имя массива.
Вы можете делать ссылки на элементы массива (с помощью его имени и индекса внутри квадратных скобок) в любом месте, где можно использовать простые переменные. Индексы должны быть целым числом от 0 до уменьшенного на один значения указанного в операторе dim

Вас может смутить тот факт, что BASIC-256 использует нуль (0) для первого элемента массива и число на единицу меньшее, чем его размер для последнего, но так принято в программировании. Массивы с отсчетом от нуля – так называют такие объекты программисты.

Мы можем использовать числовые массивы для рисования большого количества одновременно прыгающих на экране мячиков. Программа 66 использует 5 массивов для хранения местоположения каждого из мячей, его направления движения и цвета. С помощью циклов мы задаем начальные значения этим массивам, а также заставляем мячи двигаться. Эта программа также использует функцию rgb(), которая определяет и сохраняет цвет каждого мяча.


1 # manyballbounce.kbs
2 fastgraphics
3
4 r = 10 # размер мяча
5 balls = 50 # количество мячей
6
7 dim x(balls)
8 dim y(balls)
9 dim dx(balls)
10 dim dy(balls)
11 dim colors(balls)
12
13 for b = 0 to balls-1
14      # начальная позиция мяча
15      x[b] = 0
16      y[b] = 0
17      # скорость по осям x и y
18      dx[b] = rand * r + 2
19      dy[b] = rand * r + 2
20      # каждому мячу — свой цвет!
21      colors[b] = rgb(rand*256, rand*256, rand*256)
22 next b
23
24 color green
25 rect 0,0,300,300
26
27 while true
28      # очистим экран
29      clg
30      # позиционируем и рисуем мячики
31      for b = 0 to balls -1
32          x[b] = x[b] + dx[b]
33          y[b] = y[b] + dy[b]
34          # если мяч выходит за боковые границы поля — поворачиваем его
35          if x[b] < 0 or x[b] > 300 then
36              dx[b] = dx[b] * -1
37          end if
38          # если мяч выходит за верхнюю/нижнюю границу — поворачиваем его
39          if y[b] < 0 or y[b] > 300 then
40              dy[b] = dy[b] * -1
41          end if
42          # рисуем новый мяч
43          color colors[b]
44          circle x[b],y[b],r
45      next b
46      # обновляем экран
47      refresh
48      pause .05
49 end while

Программа 67 Много прыгающих мячиков.


Пример экрана программы 67. Много прыгающих мячиков.

rgb (красный, зеленый, синий)

Функция rgb возвращает одно число, которое представляет цвет, вычисленный из трех значений (красного, зеленого и синего). Аргументами этой функции могут быть арифметические выражения, но с одним условием — их значение должно быть в интервале от 0 до 255.

Еще один вариант реализации прыгающих мячей приведен в программе 68. В этом примере используются спрайты и два массива для хранения их траекторий.

1 #manyballsprite.kbs
2
3 # Еще один способ заставить прыгать мячи с использованием спрайтов
4
5 fastgraphics
6 color white
7 rect 0, 0, graphwidth, graphheight
8
9 n = 20
10 spritedim n
11
12 dim dx(n)
13 dim dy(n)
14
15 for b = 0 to n-1
16      spriteload b, "greenball.png"
17      spriteplace b,graphwidth/2,graphheight/2
18      spriteshow b
19      dx[b] = rand * 5 + 2
20      dy[b] = rand * 5 + 2
21 next b
22
23 while true
24      for b = 0 to n-1
25          if spritex(b) <=0 or spritex(b) >= graphwidth -1 then
26              dx[b] = dx[b] * -1
27          end if
28          if spritey(b) <= 0 or spritey(b) >= graphheight -1 then
29              dy[b] = dy[b] * -1
30          end if
31          spritemove b, dx[b], dy[b]
32      next b
33      refresh
34 end while

Программа 68 Много прыгающих мячиков с использованием спрайтов.


Пример вывода программы 68 Много прыгающих мячиков с использованием спрайтов.

Массивы строк

Массивы могут хранить не только числа, но и строки. Чтобы открыть строковый массив необходимо использовать идентификатор строковой переменной в операторе dim. Все, что мы знаем про числовые массивы применимо и к строковым с учетом различия в типах данных. Использование строковых массивов показано в программе 69.

1 # listoffriends.kbs
2 print "Составь список друзей"
3 input "Сколько всего друзей?", n
4
5 dim names$(n)
6
7 for i = 0 to n-1
8     input "Напиши имя друга ?", names$[i]
9 next i
10
11 cls
12 print "Мои друзья"
13 for i = 0 to n-1
14     print "Друг номер ";
15     print i + 1;
16     print " это " + names$[i]
17 next i

Программа 69 Список друзей.

Составь список друзей
Сколько всего друзей?3
Напиши имя друга ?Иван
Напиши имя друга ?Артем
Напиши имя друга ?Денис
-- очистка экрана --
Мои друзья
Друг номер 1, это Иван
Друг номер 2, это Артем
Друг номер 3, это Денис

Пример вывода программы 69 Список друзей.

Присваивание значений массивам

Мы использовали фигурные скобки ({}) для воспроизведения музыки, рисования многоугольников и штампов. Фигурные скобки можно также использовать для задания конкретных значений массивам.

1 # arrayassign.kbs
2 dim number(3)
3 dim name$(3)
4
5 number = {1, 2, 3}
6 name$ = {"Юра", "Аня", "Петя"}
7
8 for i = 0 to 2
9     print number[i] + " " + name$[i]
10 next i

Программа 70 Задание значений массива списком.


1 Юра
2 Аня
3 Петя

Пример вывода программы 70 Задание значений массива списком.

array = {знач0, знач1, … }
array$ = {текст0, текст1, … }

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

Звуки и массивы

В главе 3 мы видели как использовать список частот и длительностей (заключенных в фигурные скобки) для проигрывания нескольких звуков одновременно. Команда sound также может принять список частот и длительностей из массива. Массив должен иметь четное чиcло элементов, причем частоты хранятся в элементах с четными индексами (0, 2, 4, …), а длительности в элементах с нечетными индексами (1,3,5, …)

Следующий пример (программа 71) ниже использует простую линейную зависимость для создания фонового звука типа чириканья.


1 # spacechirp.kbs
2
3 # четные значения 0,2,4... - частота звука
4 # нечетные значения 1,3,5... - длительность
5
6 # чириканье начинается со 100гц и увеличивается на 40 для каждого из 50 звуков в списке, длительность всегда равна 10
7
8 dim a(100)
9 for i = 0 to 98 step 2
10     a[i] = i * 40 + 100
11     a[i+1] = 10
12 next i
13 sound a

Программа 71 Космическое чириканье

Как много разных фантастических звуков ты сможешь запрограммировать? Поэкспериментируй с предложенными формулами для изменения частот и длительностей.

Графики и массивы

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

В массиве, используемом для штампов и многоугольников четные элементы (0,2,4,…) содержат абсциссы (х), а нечетные элементы (1,3,5,..) содержат ординату (y) точек, образующих фигуру, по два значения на каждую точку.

1 # shadowstamp.kbs
2
3 dim xmark(24)
4 xmark = {-1, -2, 0, -1, 1, -2, 2, -1, 1, 0, 2, 1, 1, 2, 0, 1, -1, 2, -2, 1, -1, 0, -2, -1}
5
6 clg
7 color grey
8 stamp 160,165,50,xmark
9 color black
10 stamp 150,150,50,xmark

Программа 72 Штамп с тенью


Пример вывода программы 72 Штамп с тенью

Массивы также можно использовать, чтобы создать многоугольник математически (по формулам). В программе 73 мы создаем массив из 10 элементов (5 точек) придавая им случайные значения. BASIC-256 заполняет эти формы как умеет, но если линии сторон пересекаются (невыпуклый многоугольник), заполнение может оставлять пустоты и дырки.

1 # mathpoly.kbs
2
3 dim shape(10)
4
5 for t = 0 to 8 step 2
6     x = 300 * rand
7     y = 300 * rand
8     shape[t] = x
9     shape[t+1] = y
10 next t
11
12 clg
13 color black
14 poly shape

Программа 73 создание случайного прямоугольника


Примерный вывод программы 73 создание случайного прямоугольника

Для продвинутых: Двумерные массивы

До сих пор в этой главе мы использовали массивы, как простые списки чисел или строк. Такие массивы называются одномерными, поскольку они похожи на линейку значений. Массивы также могут быть созданы с использованием строк и столбцов данных — такие массивы называют двумерными. Программа 74 использует одномерные и двумерные массивы для вычисления средней оценки студента. (см таблицу к программе 74)

  Оценка 1 Оценка 2 Оценка 3 Оценка 4 Среднее
Джим 90 92 81 55 ?
Сью 66 99 98 88 ?
Тони 79 81 87 73 ?

Таблица к программе 741

1 # grades.kbs
2 # вычисление средней оценки студента
3 # и для всего класса
4
5 nstudents = 3 # количество студентов
6 nscores = 4 # количество оценок у студента
7
8 dim students$(nstudents)
9
10 dim grades(nstudents, nscores)
11 # сохраняем оценки студента в столбцах одного ряда
12 # первый студент
13 students$[0] = "Джим"
14 grades[0,0] = 90
15 grades[0,1] = 92
16 grades[0,2] = 81
17 grades[0,3] = 55
18 # второй студент
19 students$[1] = "Сью"
20 grades[1,0] = 66
21 grades[1,1] = 99
22 grades[1,2] = 98
23 grades[1,3] = 88
24 # Третий студент
25 students$[2] = "Тони"
26 grades[2,0] = 79
27 grades[2,1] = 81
28 grades[2,2] = 87
29 grades[2,3] = 73
30
31 total = 0
32 for row = 0 to nstudents-1
33     studenttotal = 0
34     for column = 0 to nscores-1
35         studenttotal = studenttotal + grades[row, column]
36         total = total + grades[row, column]
37     next column
38     print students$[row] + " - среднее равно ";
39     print studenttotal / nscores
40 next row
41 print "Среднее по классу ";
42 print total / (nscores * nstudents)
43
44 end

Программа 74 Вычисление успеваемости


Джим - среднее равно 79,5
Сью - среднее равно 87,75
Тони - среднее равно 80,
Среднее по классу 82,416667

Пример вывода программы 74 Вычисление успеваемости

Для действительно продвинутых — Размеры массива

Иногда необходимо в программе использовать массив, размеры которого мы не знаем. Если поставить вместо индекса внутри квадратных скобок знак вопроса, BASIC-256 вернет размер этого массива. В программе 75 мы распечатываем массив независимо от размера. В строке 16 обратите внимание на специальный знак [?] использованный для получения размера массива.

1 # size.kbs
2 dim number(3)
3 number = {77, 55, 33}
4 print "до"
5 gosub shownumberarray
6
7 # добавляем новый элемент в конец
8 redim number(4)
9 number[3] = 22
10 print "после"
11 gosub shownumberarray
12 #
13 end
14 #
15 shownumberarray:
16 for i = 0 to number[?] - 1
17     print i + " " + number[i]
18 next i
19 return

Программа 75 Получение размера массива


до
0,
77,
1,
55,
2,
33,
после
0,
77,
1,
55,
2,
33,
3,
22,

Пример вывода программы 75 Получение размера массива

array[?]
array$[?]
array[?,]
array$[?,]
array[,?]
array$[,?]

Ссылка на [?] элемент массива возвращает длину одномерного массива или полное число элементов (количество строк умноженное на количество столбцов) двумерного массива. [?,] – возвращает количество строк , а [,?] – возвращает количество столбцов двумерного массива.

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

BASIC-256 позволяет изменять размер существующего массива. Оператор redim предназначен для изменения массива с сохранением существующих данных. Если новый массив больше старого, новые элементы заполняются нулями (0) или пустыми строками (""). Если новый массив меньше старого, значения, которые выходят за рамки нового массива обрезаются. Массивы, размеры которых можно менять во время работы программы называются динамическими2.


1 # redim.kbs
2 dim number(3)
3 number = {77, 55, 33}
4 # создаем новый элемент в конце массива
5 redim number(4)
6 number[3] = 22
7 #
8 for i = 0 to 3
9      print i + " " + number[i]
10 next i

Программа 76 Изменение размера массива

0  77
1  55
2  33
3  22

Пример вывода программы 76 Изменение размера массива

redim variable(количество_элементов)
redim variable$(количество_элементов)
redim variable(число_рядов, число_колонок)
redim variable$(число_рядов, число_колонок)

Оператор redim изменяет размер массива в памяти компьютера. Данные, хранившиеся в массиве сохраняются, если они подходят по размеру к новому массиву.

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

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


1 # spacewarp.kbs
2 # Игра Космический мусор
3
4 balln = 5  # количество мячей
5 dim ballx(balln) # массивы для хранения положения и скоростей мячей
6 dim bally(balln)
7 dim ballspeed(balln)
8 ballr = 10 # радиус мяча
9
10 minx = ballr # минимальное значение координаты х мяча
11 maxx = graphwidth - ballr # максимальное значение координаты х мяча
12 miny = ballr # минимальное значение координаты y мяча
13 maxy = graphheight - ballr # максимальное значение координаты y мяча
14 score = 0 # в начале счет равен 0
15 playerw = 30  # ширина игрока
16 playerm = 10  # шаг игрока
17 playerh = 10  # высота игрока
18 playerx = (graphwidth - playerw)/2  # начальное значение координаты х игрока - середина поля
19 keyj = asc("J") # значение для клавиши 'j'
20 keyk = asc("K") # значение для клавиши 'k'
21 keyq = asc("Q") # значение для клавиши 'q'
22 growpercent = .20  # случайное расширение игрока - чем больше, тем быстрее
23 speed = .15  # скорость - чем меньше, тем быстрее
24
25 print "Космический мусор - использовать j и k клавиши чтобы избежать столкновения с космическим мусором"
26 print "q - закончить"
27
28 fastgraphics
29
30 # установка начальных значений скорости и положения мячей
31 for n = 0 to balln-1
32     gosub setupball
33 next n
34
35 more = true
36 while more
37     pause speed
38     score = score + 1
39
40     # очистка экрана
41     color black
42     rect 0, 0, graphwidth, graphheight
43
44     # рисуем мячи и проверяем на наличие столкновений
45     color white
46     for n = 0 to balln-1
47         bally[n] = bally[n] + ballspeed[n]
48         if bally[n] > maxy then gosub setupball
49         circle ballx[n], bally[n], ballr
50         if ((bally[n]) >= (maxy-playerh-ballr)) and ((ballx[n]+ballr) >= playerx) and ((ballx[n]-ballr) <= (playerx+playerw)) then more = false
51     next n
52
53     # рисуем игрока
54     color red
55     rect playerx, maxy - playerh, playerw, playerh
56     refresh
57
58     # игрок растет в ширину
59     if (rand<growpercent) then playerw = playerw + 1
60
61     # проверяем нажата ли клавиша и перемещаем игрока, если нажата
62     k = key
63     if k = keyj then playerx = playerx - playerm
64     if k = keyk then playerx = playerx + playerm
65     if k = keyq then more = false
66
67     # не вышел ли игрок за границы поля?
68     if playerx < 0 then playerx = 0
69     if playerx > graphwidth - playerw then playerx = graphwidth - playerw
70
71 end while
72
73 print "счет " + string(score)
74 print "вы погибли."
75 end
76
77 setupball:
78 bally[n] = miny
79 ballx[n] = int(rand * (maxx-minx)) + minx
80 ballspeed[n] = int(rand * (2*ballr)) + 1
81 return

Программа 77 Большая программа – Игра Космический мусор


Примерный экран программы 77 Большая программа – Игра Космический мусор

—————————————————
1В школах многих зарубежных стран используется 100-бальная система оценок (прим. переводчика)

2Программа 75 также является демонстрацией динамических массивов. Обратите внимание на оператор redim (прим. переводчика).

============================

Где скачать BASIC-256:

Для дистрибутивов ALT Linux

Windows версия
http://basic256.org (http://www.sourceforge.net/projects/kidbasic)

Как установить BASIC-256 в Linux

Для Альт Линукс: настроить репозиторий и обновить/установить пакет через synaptic или apt
Для rpm-based дистрибутивов: rpm -Uvh <имя_пакета>.rpm

Оставьте комментарий