
A Warehouse level is more than its squares. It has a name. It has a place where the worker starts. It has the fewest moves anyone has solved it in. These belong together - a level's best score means nothing apart from the level - and Pascal has a type for keeping them together: the record.
type
Str20 = string[20];
Level = record
Name: Str20;
Moves, Best: Integer;
end;
var
L: Level;
A record type lists its fields between record and end, each with a name and a type, laid out like a var section. A Level variable holds all three at once.
A field is reached with a full stop between the variable and the field:
L.Name := 'First steps';
L.Best := 12;
Writeln(L.Name);
L.Best is an ordinary integer variable in every way - it just lives inside L.
Writing L. in front of every field gets tiresome. with opens a record up, so that its fields can be named on their own:
with L do
begin
Writeln(Name);
if Moves < Best then
Writeln('New best!');
end;
Inside the with, Name means L.Name. Outside it, a bare Name is Error 41, because on its own it is not a variable at all.
One record can be assigned to another of the same type, and all its fields are copied:
M := L;
M.Name := 'Changed';
leaves L.Name as it was. M is a separate copy, not another name for L.
Records and arrays combine naturally. A list of players, each with a name and a score:
var
P: array[1..3] of Player;
...
P[2].Score := 17;
P[2] is the second player, a record; P[2].Score is that player's score. Later, a list of levels is exactly this.
A record can be a typed constant too, with each field named, separated by semicolons:
const
Start: Level = (Name: 'Starter';
Moves: 0; Best: 9);
program Levels;
type
Str20 = string[20];
Level = record
Name: Str20;
Moves, Best: Integer;
end;
var
L: Level;
begin
L.Name := 'First steps';
L.Moves := 10;
L.Best := 12;
with L do
begin
Writeln(Name);
Writeln('Moves: ', Moves,
' Best: ', Best);
if Moves < Best then
Writeln('New best!');
end;
end.
Starting from
Turbo freshly started, Y, a new work file called LEVELS.
What you should see
First steps
Moves: 10 Best: 12
New best!
with L do, leaving the begin and end. What does Turbo say, and about which word?Level, M; before the with, copy L into it, change M.Name and print it. Does L's name change?L.Moves to 15 instead of 10. What is missing from the output?20.1 Declare a record Point with fields X and Y. Set two points, (2, 3) and (5, 7), and print how far across and how far down the second is from the first.
20.2 Make an array of three players, each a record with a name and a score. Fill them in and print the name of the one with the highest score.
20.3 Write a record typed constant for a level called Starter with a best score of 9, and print both fields.
Worked solutions are in Appendix II.
| Symptom | Cause |
|---|---|
Error 41 on a field name | Used without the record and a full stop, outside a with - or misspelt. |
| A change to a copied record does not show in the original | Assignment copies; the two are separate. To change the original, change it, not the copy. |
A record type lists named fields of any types between record and end. R.Field reaches one; with R do lets the fields be named alone. Assigning a record copies every field. Arrays of records, and record typed constants written as (Field: value; ...), hold whole lists of things - such as a game's levels.
S21, Files - keeping records on the disc, so that levels and best scores outlast the program.