Solutions TOPIC E: Records

Contents :

  RECORD.

Exercises :


D1: Sum of Complex numbers.

Exercise
MODULE D1;
<* NOOPTIMIZE + *>
    FROM IO IMPORT RdChar, WrChar, WrStr, RdStr, WrLn, RdCard, WrCard, RdInt, WrInt, RdReal, WrReal, WrFixReal, RdBool, WrBool;  (*
import general procedures *)
 

    VAR
      c1, c2, c3: RECORD            (* variable-declarations *)
                    re, img: REAL;
                  END;
BEGIN
    WrLn;
    c1.re := 3.5;
    c1.img := -4.76;
    c2.re := 4.0;
    c2.img := 14.6;

    (* sum *)
    c3.re := c1.re + c2.re;
    c3.img := c1.img + c2.img;

    (* print *)
    WrStr("The complex sum of ");WrFixReal(c1.re, 1, 0);WrChar('+'); WrFixReal(c1.img, 1, 0);WrChar('i');
    WrStr(" and ");WrFixReal(c2.re, 1, 0);WrChar('+'); WrFixReal(c2.img, 1, 0);WrChar('i');
    WrStr(" is: ");WrFixReal(c3.re, 2, 0);WrChar('+'); WrFixReal(c3.img, 2, 0);WrChar('i');WrLn;
END D1.



MODULE D2;
<* NOOPTIMIZE + *>
    FROM IO IMPORT RdChar, WrChar, WrStr, RdStr, WrLn, RdCard, WrCard, RdInt, WrInt, RdReal, WrReal, WrFixReal, RdBool, WrBool;  (*
import general procedures *)

    TYPE ComplexRc = RECORD
                       re, img: REAL;
                     END;
    VAR
      c1, c2, c3: ComplexRc;
BEGIN
    WrLn;
    c1.re := 3.5;
    c1.img := -4.76;
    c2.re := 4.0;
    c2.img := 14.6;

    (* sum *)
    c3.re := c1.re + c2.re;
    c3.img := c1.img + c2.img;

    (* print *)
    WrStr("The complex sum of ");WrFixReal(c1.re, 1, 0);WrChar('+'); WrFixReal(c1.img, 1, 0);WrChar('i');
    WrStr(" and ");WrFixReal(c2.re, 1, 0);WrChar('+'); WrFixReal(c2.img, 1, 0);WrChar('i');
    WrStr(" is: ");WrFixReal(c3.re, 2, 0);WrChar('+'); WrFixReal(c3.img, 2, 0);WrChar('i');WrLn;
END D2.


S1

oplossing van produkt: 83,5+32.1i
Exercise


S2

MODULE S2;

<* WOFF + *> <* NOOPTIMIZE + *>
FROM IO IMPORT WrStr, WrLn, RdCard, WrCard, RdInt, WrInt, RdKey, RdLn, WrFixReal, KeyPressed;
FROM Graph IMPORT Init, Line, Ellipse, Disc, Circle, Rectangle, _clrBLACK, _clrBLUE, _clrGREEN, _clrCYAN, _clrRED, _clrMAGENTA;
FROM RealMath IMPORT cos, sin, pi;
FROM Lib IMPORT Delay; (* Wait n milliseconds *)

CONST SCREEN_SIZE = 600;

TYPE LedemaatRc = RECORD
                    x,y: CARDINAL;
                    lengte, lengteVoet: CARDINAL;
                    hoek: INTEGER; (* in graden *)
                    kleur: CARDINAL; 
                    naarLinks: BOOLEAN; (* voet naar links tekenen ipv. naar rechts *)

                   END;

PROCEDURE TekenLedemaat(ledemaat: LedemaatRc);
  VAR hoek_rad, x2, y2, x3, y3: REAL;
BEGIN
  hoek_rad := VAL(REAL, ledemaat.hoek) * pi / 180.0;
  x2 := VAL(REAL, ledemaat.x) + VAL(REAL, ledemaat.lengte) * sin(hoek_rad);
  y2 := VAL(REAL, ledemaat.y) + VAL(REAL, ledemaat.lengte) * cos(hoek_rad);
  Line(ledemaat.x, ledemaat.y, VAL(CARDINAL, x2), VAL(CARDINAL, y2), ledemaat.kleur);
  IF ledemaat.lengteVoet > 0 THEN
    IF ledemaat.naarLinks THEN
        x3 := x2 - VAL(REAL, ledemaat.lengteVoet) * cos(hoek_rad);
        y3 := y2 + VAL(REAL, ledemaat.lengteVoet) * sin(hoek_rad);
    ELSE
        x3 := x2 + VAL(REAL, ledemaat.lengteVoet) * cos(hoek_rad);
        y3 := y2 - VAL(REAL, ledemaat.lengteVoet) * sin(hoek_rad);
    END;
    Line(VAL(CARDINAL, x2), VAL(CARDINAL, y2), VAL(CARDINAL, x3), VAL(CARDINAL, y3), ledemaat.kleur);
  END;
END TekenLedemaat;

(*********************************************************************************)
  VAR c: CHAR;
      ledemaat: LedemaatRc;
BEGIN
  WrLn;
  IF NOT Init(1, 1 , SCREEN_SIZE, SCREEN_SIZE) THEN
     WrStr("Sorry, graphics doesn't work");WrLn;
     RETURN;
    END;

  WITH ledemaat DO
      x := 100;
        (* dit is hetzelfde als schrijven ledemaat.x := 100;  *)
      y := 100;                      (*                  ledemaat.y := 100;  etcetera *)
      lengte := 100;
      lengteVoet := 20;
      hoek := -60;
      kleur := _clrRED;
   END;

  TekenLedemaat(ledemaat);

  WrStr("Press any key to finish the program");
  c := RdKey();
  WrLn; RdLn;

END S2.

Exercise


S3

Exercise

MODULE S3;
<* WOFF + *> <* NOOPTIMIZE + *>
FROM IO IMPORT WrCard, WrStr, WrInt, WrLn, RdKey, RdLn, KeyPressed;
FROM Lib IMPORT Delay;
FROM Graph IMPORT _clrBLACK, _clrBLUE, _clrGREEN, _clrCYAN, _clrRED, _clrMAGENTA, _clrBROWN, _clrWHITE, _clrGRAY,   _clrLIGHTBLUE, _clrLIGHTGREEN, _clrLIGHTCYAN, _clrLIGHTRED, _clrLIGHTMAGENTA,  _clrLIGHTYELLOW, _clrBRIGHTWHITE;
FROM Graph IMPORT Init, Rectangle, Line, Polygon, Disc, RawOutText;

CONST
    SCHERM_BREEDTE = 800;
    SCHERM_HOOGTE  = 600;
    D = 150;   (* afstand en hoogte van observer *)
    H = SCHERM_HOOGTE/2;
   
TYPE
   Point2D = RECORD
                  x,y:INTEGER;
                END;
    Point3D = RECORD
                  x,y,z:INTEGER;
                END;
           
PROCEDURE Rectangle2 (p0, p1: Point2D; Color :CARDINAL; Fill :BOOLEAN);
BEGIN
  IF p0.x < 0 THEN
    IF p1.x > 0 THEN
      IF (p0.y > 0) AND (p1.y > 0 ) THEN
        Rectangle(0, p0.y, p1.x, p1.y, Color, Fill);
      END;
    END;
  ELSIF p1.x < 0 THEN
     Rectangle(p0.x, p0.y, 0, p1.y, Color, Fill);
  ELSIF (p0.y > 0) AND (p1.y > 0 ) THEN
     Rectangle(p0.x, p0.y, p1.x, p1.y, Color, Fill);
  END;
END Rectangle2;

PROCEDURE Line2(p0, p1:Point2D; Color: CARDINAL);
   VAR y : INTEGER;
BEGIN
  IF p0.x < 0 THEN
    IF p1.x > 0 THEN
      y := p0.y - VAL(INTEGER, VAL(REAL, p0.y - p1.y) * (VAL (REAL, p0.x) / VAL(REAL, p0.x - p1.x)));
      IF y > 0 THEN
          Line(0, y, p1.x, p1.y, Color);
      END;
    END;
  ELSIF p1.x < 0 THEN
     Line(p0.x, p0.y, 0, p1.y + (p0.y - p1.y) * p0.x/ (p0.x - p1.x), Color);
  ELSIF (p0.y > 0) AND (p1.y > 0) THEN
     Line(p0.x, p0.y, p1.x, p1.y, Color);
  END;
END Line2;


VAR
  x : CHAR;
BEGIN

    IF NOT Init(1, 1 , SCHERM_BREEDTE, SCHERM_HOOGTE) THEN
        RETURN;
    END;
    (* schrijf tekst op het graph scherm, op positie (50, 40) *)
    RawOutText(50, 40, _clrGREEN, "Press q to finish the program");


   x := RdKey();
END S3.



Toe te voegen om flight simulator te maken

FROM Lib IMPORT Delay, RANDOM, RANDOMIZE;
FROM Str IMPORT CardToStr;
CONST
NBR = 40;(* aantal buildings *)

(* geeft een willekeurig getal tussen min en max *)
PROCEDURE RandomInt(min, max: INTEGER): INTEGER;
  BEGIN
    IF max < min THEN
      WrStr("ERROR calling RandomInt: min ");WrInt(min, 0);WrStr(" is bigger than max ");WrInt(max, 0);WrLn;
      RETURN min;
    ELSE
        RETURN min + VAL(INTEGER, RANDOM(max-min+1));
    END;
  END RandomInt;

  buildings: ARRAY[1..NBR] OF Point3D;
  buildingsBreedte: ARRAY[1..NBR] OF INTEGER;
  yb:INTEGER;
  i, punten: CARDINAL;
  puntenString: ARRAY[1..80] OF CHAR;
BEGIN

(* de buildings aanmaken met random numbers *)
    RANDOMIZE; (* Initialise the Modula-2 random generator *)
    FOR i := 1 TO NBR DO
       buildings[i].x := RandomInt(-SCHERM_BREEDTE/2, SCHERM_BREEDTE/2);
       buildings[i].y := yb + RandomInt(100, 200);
       buildings[i].z := RandomInt(300, 600);
       buildingsBreedte[i] := RandomInt(50, 100);
       yb := buildings[i].y;
    END;

Printen van de punten:
     CardToStr(punten, puntenString, 10, OK); (* omzetting CARDINAL naar string *)
     RawOutText(50, 90, _clrLIGHTMAGENTA, "Punten: "); RawOutText(120, 90, _clrLIGHTMAGENTA, puntenString);

Formule om te checken of building geraakt wordt (dp is positie van vliegtuig):

IF (ABS(buildings[i].y - dp.y) < (buildingsBreedte[i]/2+5)) AND (ABS(buildings[i].x - dp.x) < 25) AND (buildings[i].z > (dp.z + H)) AND ((dp.z + H) > 0) THEN


H1


Exercise

MODULE H1;
<* WOFF + *> <* NOOPTIMIZE + *>
    FROM IO IMPORT RdChar, WrChar, WrStr, RdStr, WrLn, RdLn, RdCard, WrCard, RdInt, WrInt, RdReal, WrReal, WrFixReal, RdBool, WrBool, RdKey,KeyPressed;
    FROM RealMath IMPORT sqrt, exp, sin, cos, tan, arcsin, arccos, arctan, power, round;
    FROM Lib IMPORT Delay; (* Wait n milliseconds *)
    FROM Graph IMPORT Init, Line, Rectangle, Circle, Ellipse, Disc, _clrBLACK, _clrBLUE, _clrGREEN, _clrCYAN, _clrRED, _clrMAGENTA;
    FROM Graph IMPORT _clrBROWN, _clrWHITE, _clrGRAY, _clrLIGHTBLUE, _clrLIGHTGREEN, _clrLIGHTCYAN, _clrLIGHTRED, _clrLIGHTMAGENTA, _clrLIGHTYELLOW, _clrBRIGHTWHITE;
         (* zie C:/Bin/Xds/Def/Ts/Graph.def  *)

   (* A. Constants *)
    CONST SCREEN_SIZE = 600;
        MIN_FIG_SIZE = 10;
    MAX_FIG_SIZE = 50;

   (* B. Types *)
    TYPE
        ColourSb = [0..15];  (* subrange *)
        SizeSb = [MIN_FIG_SIZE..MAX_FIG_SIZE];

   (* C. Procedures *)

    (* GEGEVEN procedures:
       de cirkel & ellipse komen uit de graph-library en zijn als volgt gedefinieerd:
        PROCEDURE Circle(x0, y0, r, c :LONGCARD);
          centre x0,y0; radius r
        PROCEDURE Ellipse ( x0,y0,a,b,c :LONGCARD; fill :BOOLEAN );
          center x0,y0; semi-axes a,b;  color c ; whether filled
      neem voor a size/2 en voor b size/3

  de andere procedures zijn als volgt gedefinieerd:
         PROCEDURE Square(x0,y0,size,colour:CARDINAL);
         PROCEDURE Asterisk(x0,y0,size,colour:CARDINAL); tekent een 'ster'
         PROCEDURE Triangle(x0,y0,size,colour:CARDINAL);
    x0, y0 is steeds het middelpunt

      deze procedure geeft een random getal terug tussen min en max:
         PROCEDURE RandomCard(min, max: CARDINAL): CARDINAL;
   *)
    PROCEDURE Square(x0,y0,size,colour:CARDINAL);
    BEGIN
      Rectangle (x0 - size/2,y0 - size/2,x0 + size/2,y0 + size/2, colour,TRUE);
    END Square;

    PROCEDURE Asterisk(x0,y0,size,colour:CARDINAL);
      VAR a:CARDINAL;
    BEGIN
      a:= VAL(CARDINAL,((VAL(REAL,size)/(2.0))*0.7071) ); (* cos(45)*)
      Line(x0-size/2, y0, x0+size/2,y0, colour);
      Line(x0, y0+size/2, x0, y0-size/2, colour);
      Line(x0-a, y0+a, x0+a, y0-a, colour);
      Line(x0+a, y0+a, x0-a, y0-a, colour);
    END Asterisk;

    PROCEDURE Triangle(x0,y0,size,colour:CARDINAL);
      VAR a:CARDINAL;
    BEGIN
      a:= VAL(CARDINAL,((VAL(REAL,size)/(2.0))*0.7071) ); (* cos(45)*)
      Line(x0, y0-a, x0-size/2, y0+a, colour);
      Line(x0-size/2, y0+a, x0+size/2, y0+a, colour);
      Line(x0, y0-a, x0+size/2, y0+a, colour);
    END Triangle;

    VAR  gSeed: CARDINAL; (* Random waarde generator *)
    PROCEDURE RandomCard(min, max: CARDINAL): CARDINAL;
       VAR
         factor: REAL;
    BEGIN
        factor := (VAL(REAL, max - min) + 0.99999) / FLOAT(1013 - 1);
        gSeed := (gSeed * 351 + 138) MOD 1013;
        RETURN min + VAL(CARDINAL, VAL(REAL, gSeed) * factor);
    END RandomCard;
    (************* TOT HIER DE GEGEVEN PROCEDURES ******************)

   (* D. Variables*)
    VAR x: CHAR;
BEGIN
    WrLn;
  IF NOT Init(1, 1 , SCREEN_SIZE, SCREEN_SIZE) THEN
    WrStr("Sorry, graphics doesn't work");WrLn;
    RETURN;
  END;

  WrStr("Welke figuur wenst u? (c=cirkel, e=ellips, v=vierkant, s=ster, d=driehoek)");WrLn;
  x := RdChar();

  Rectangle(1, 1, 60, 60, _clrWHITE, FALSE);

  WrStr("Press any key to finish the program");WrLn;
  x := RdKey(); RdLn;
END H1.
 


H2

MODULE H2;
<* NOOPTIMIZE + *> <* WOFF + *>
    FROM IO IMPORT RdChar, WrChar, WrStr, RdStr, WrLn, RdLn, RdCard, WrCard, RdInt, WrInt,RdReal, WrReal, WrFixReal, RdBool, WrBool, RdKey, KeyPressed;
    FROM RealMath IMPORT sqrt, exp, sin, cos, tan, arcsin, arccos, arctan, power, round;
    FROM Lib IMPORT Delay; (* Wait n milliseconds *)
    FROM Graph IMPORT Init, Line, Rectangle, Circle, Disc, _clrBLACK, _clrBLUE, _clrGREEN,_clrCYAN, _clrRED, _clrMAGENTA;
    FROM Graph IMPORT _clrBROWN, _clrWHITE, _clrGRAY, _clrLIGHTBLUE, _clrLIGHTGREEN,_clrLIGHTCYAN, _clrLIGHTRED, _clrLIGHTMAGENTA, _clrLIGHTYELLOW, _clrBRIGHTWHITE;
         (* zie C:/Bin/Xds/Def/Ts/Graph.def  *)

   (* A. Constants *)
    CONST SCREEN_SIZE = 600;
          NBR = 10;
          SIZE = 4;

   (* B. Types *)
  TYPE PointRc = RECORD
                           x, y: REAL;
      (*4*)
      (*6*)
                       END;

   (* C. Procedures *)
  PROCEDURE Square(x0,y0,size,colour:CARDINAL);
  BEGIN
    Rectangle (x0 - size/2,y0 - size/2,x0 + size/2,y0 + size/2, colour,TRUE);
  END Square;

  PROCEDURE Asterisk(x0,y0,size,colour:CARDINAL);
    VAR a:CARDINAL;
  BEGIN
    a:= VAL(CARDINAL,((VAL(REAL,size)/(2.0))*0.7071) ); (* cos(45)*)

    Line(x0-size/2, y0, x0+size/2,y0, colour);
    Line(x0, y0+size/2, x0, y0-size/2, colour);
    Line(x0-a, y0+a, x0+a, y0-a, colour);
    Line(x0+a, y0+a, x0-a, y0-a, colour);
  END Asterisk;

  PROCEDURE CalculateDistance(p1, p2: PointRc): REAL;
  BEGIN
    RETURN sqrt((p1.x-p2.x)*(p1.x-p2.x) + (p1.y-p2.y)*(p1.y-p2.y));
  END CalculateDistance;

  PROCEDURE AverageDistance(p: PointRc; points: ARRAY OF PointRc): REAL;
    VAR sum : REAL;
      i: CARDINAL;
  BEGIN
    sum := 0.0;
    FOR i := 0 TO HIGH(points) DO
      sum := sum + CalculateDistance(p, points[i]);
    END;
    RETURN sum / VAL(REAL, HIGH(points) + 1);
  END AverageDistance;

  (* 2 make procedure PlotArray *)
    (*6 change procedure PlotArray*)

  (* 3 procedure to calculate centre of gravity *)

   (* D. Variables*)
     VAR x: CHAR;
       (*1 define arr*)
       (*3 define cg *)
BEGIN
    WrLn;
  IF NOT Init(1, 1 , SCREEN_SIZE, SCREEN_SIZE) THEN
    WrStr("Sorry, graphics doesn't work");WrLn;
    RETURN;
  END;
  (* fill array *)
    arr[1].x := 7.3;   arr[1].y := 8.4E-1;
    arr[2].x := 14.2;  arr[2].y := 7.34;
    arr[3].x := 1.4;   arr[3].y := 6.23;
    arr[4].x := 1.0E1; arr[4].y := 1.0E1;
    arr[5].x := 2.5;   arr[5].y := 4.5;
    arr[6].x := 5.2;   arr[6].y := 10.4;
    arr[7].x := 3.4;   arr[7].y := 5.432;
    arr[8].x := 14.6;  arr[8].y := 9.8;
    arr[9].x := 12.2;  arr[9].y := 15.8;
    arr[10].x := 4.5;  arr[10].y := 4.5;

  (* plot array *)
    (*2 call plot procedure for arr *)

  (* calculate centre of gravity *)
     (*3 call procedure *)

  (* plot centre of gravity *)
     (*3 draw asterisk on cg *)

  (* distance to cg for every point*)
     (*4 use the given CalculateDistance procedure *)

  (*5 *)

  (*6 call plot array again*)

  (* Show graphics until user presses a key *)
  WrStr("Press any key to finish the program");
  x := RdKey();
  WrLn; RdLn;
END H2.

Exercise

Solution

  1. cg.x = 6.8,  cg.y = 7.4
  2. distance to cg: arr[1].distance = ,  arr[2].distance = ,  arr[3].distance = , ...
  3. average distance to cg = 6.44
  4. Points further away from cg than average:..




T2

Check je oplossing met XDS door de identifier op die lijn te gebruiken en zien of de compiler een fout geeft.

Exercise