Turbo Pascal 2.0 course cover
← Back to Courses
module
19

Lists Of Things

Introduction

A Warehouse level is a grid of squares - up to sixteen across and ten down, a hundred and sixty of them. Nobody wants a hundred and sixty variables. An array is one variable that holds many values of the same type, each picked out by a number, and a grid is an array of arrays.

An Array

var
  A: array[1..4] of Integer;

A holds four integers, A[1] to A[4]. Each is used exactly like an ordinary variable - A[2] := 7, Writeln(A[3]) - and the number in the square brackets, the index, can be any expression: A[I], A[I + 1]. That is the whole point. A loop can visit every element:

for I := 1 to 4 do
  A[I] := I * I;

The index does not have to start at 1, and it does not have to be a number. With S17's tiles, an array can be indexed by the tile itself:

var
  Count: array[Tile] of Integer;
...
Count[Crate] := 5;

One array can be copied into another of the same type in a single assignment, B := A, and then they are separate: changing B does not change A.

Arrays Of Arrays

A grid needs two indexes, a row and a column:

var
  Board: array[1..16, 1..20] of Tile;

Board[3, 5] is the square in row 3, column 5. You can also write it Board[3][5], which is the same square - the board is an array of rows, and each row is an array of squares.

To visit every square, put one loop inside another (S13):

for R := 1 to 16 do
  for C := 1 to 20 do
    Board[R, C] := Floor;

Filling An Array In The Program

A typed constant is a variable whose starting value is written in the program:

const
  Look: array[Tile] of Char =
    ('#', ' ', '.', '$');

Look[Crate] is then '$' - a one-line way to turn a tile into the character that draws it. An array of strings makes a perfectly good level:

const
  Level: array[1..5] of Str20 = (
    '#######',
    '#     #',
    '# $ . #',
    '#  @  #',
    '#######');

The values go in brackets, separated by commas, and they may run over as many lines as you like. Level[3] is the third row, a string, and Level[3][3] is its third character, $.

A typed constant is a variable, not a constant, so it cannot be used to size an array (Error 41); use a plain const for that.

Outside The Array

What is A[5] of a four-element array? It does not exist - but unless you ask for checking, Turbo will not stop you using it, and the result is worse than an error. Declare X, then a three-element array A, then Y; set X to 1 and Y to 2; then put 100 in A[0] and 400 in A[4]. Print X and Y, and you get 400 and 100: the writes have landed on the variables next door.

This is the most dangerous mistake in the course, because the damage shows up somewhere else entirely. With {$R+} at the top of the program, every index is checked, and the first one out of range stops the program:

Run-time error 90, PC=00A3
Program aborted

with ESC pointing at the statement. Use {$R+} for any program with arrays while you are writing it.

Arrays also cost memory, and the Einstein has only so much: an array of twenty thousand integers is Error 98: Memory overflow before the program even runs. A Warehouse board is no trouble: even a 16 by 20 array of tiles, bigger than the game needs, reported Data: 327 bytes - about one byte a square - with over 26,000 bytes still free.

The Code

program Board;
type
  Str20 = string[20];
const
  Level: array[1..5] of Str20 = (
    '#######',
    '#     #',
    '# $ . #',
    '#  @  #',
    '#######');
var
  R, C, Crates: Integer;
begin
  for R := 1 to 5 do
    Writeln(Level[R]);
  Crates := 0;
  for R := 1 to 5 do
    for C := 1 to Length(Level[R]) do
      if Level[R][C] = '$' then
        Crates := Crates + 1;
  Writeln('Crates: ', Crates);
  Writeln('At row 4, column 4: ',
          Level[4][4]);
end.

Your first warehouse: walls, one crate, one goal, and the worker, @.

Starting from

Turbo freshly started, Y, a new work file called BOARD.

What you should see

#######
#     #
# $ . #
#  @  #
#######
Crates: 1
At row 4, column 4: @

Change One Thing

  • Put a second $ in the second row. What does the count say?
  • Add {$R+} as the first line and change the first loop to run 1 to 6. What happens after the fifth row?
  • Change Level[4][4] to Level[4][5]. What is printed at the end of the last line, and why does it look like nothing?

Exercises

19.1 Five marks are 7, 8, 10, 6 and 9. Put them in a typed constant array and print their average to one decimal place.

19.2 Ask for five numbers, one at a time, into an array, and print them in reverse order.

19.3 Using Pos on each row of this section's level, print the row and column where the worker, @, is standing.

Worked solutions are in Appendix II.

When It Goes Wrong

SymptomCause
Variables change that the program never setAn array index out of range, writing over its neighbours. Put {$R+} at the top and run again.
Run-time error 90An index out of range, with {$R+} on. ESC shows where.
Error 98: Memory overflowAn array too big for the machine's memory.
Error 41 at an array's sizeThe size uses a typed constant. Use a plain const.
[ and ] look like arrowsThat is how the Einstein draws them (S3).

Summary

array[1..n] of T holds n values of type T, picked out with A[I]; the index can be a number range or an enumerated type. array[1..R, 1..C] is a grid, B[R, C] a square. Typed constants fill arrays in the program. An index out of range is not caught unless {$R+} is on - and without it, it damages other variables.

Next

S20, Records - several values of different types held together: a level with its name, its size and its best score.

Get the Newsletter

New guides, disk images and community finds, roughly once a quarter. No spam, we promise, this isn't Tatung's marketing department.
Your subscription could not be saved. Please try again.
Your subscription has been successful.

Newsletter

Subscribe to our newsletter and stay updated.