Turbo Pascal 2.0 course cover
← Back to Modules
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.

This form is protected by reCAPTCHA, and the Google Privacy Policy and Terms of Service apply.