Recent

Author Topic: identifier idents no member error  (Read 214 times)

Synaii

  • Newbie
  • Posts: 4
identifier idents no member error
« on: February 14, 2020, 03:01:52 pm »
hi, im studying design patterns and then..

Code: Pascal  [Select]
  1. {$mode objfpc}
  2. program mygame;
  3. uses crt;
  4.  
  5. type
  6.     IStatePlayer = interface
  7.         function speed(): IStatePlayer;
  8.         function slow(): IStatePlayer;
  9.     end;
  10.  
  11.     TPlayerNormal = class(TInterfacedObject, IStatePlayer)    
  12.         vel: byte;
  13.  
  14.         constructor create();
  15.  
  16.         function speed(): IStatePlayer;
  17.         function slow(): IStatePlayer;
  18.     end;
  19.  
  20.     TPlayerSpeed = class(TInterfacedObject, IStatePlayer)
  21.         vel: byte;
  22.  
  23.         constructor create();
  24.  
  25.         function speed(): IStatePlayer;
  26.         function slow(): IStatePlayer;
  27.     end;
  28.  
  29.     TPlayer = class    
  30.         x: byte;
  31.         dir: boolean;
  32.         state: IStatePlayer;
  33.  
  34.         constructor create();
  35.  
  36.         procedure move();
  37.  
  38.         procedure speed();
  39.         procedure slow();        
  40.     end;
  41.  
  42. { TPlayerNormal }
  43.  
  44. constructor TPlayerNormal.create();
  45. begin
  46.     self.vel := 1;
  47. end;
  48.  
  49. function TPlayerNormal.speed(): IStatePlayer;
  50. begin
  51.     result := TPlayerSpeed.create;
  52. end;
  53.  
  54. function TPlayerNormal.slow(): IStatePlayer;
  55. begin
  56.     result := self;
  57. end;
  58.  
  59. { TPlayerSpeed }
  60.  
  61. constructor TPlayerSpeed.create();
  62. begin
  63.     self.vel := 2;
  64. end;
  65.  
  66. function TPlayerSpeed.speed(): IStatePlayer;
  67. begin
  68.     result := self;
  69. end;
  70.  
  71. function TPlayerSpeed.slow(): IStatePlayer;
  72. begin
  73.     result := TPlayerNormal.create;
  74. end;
  75.  
  76. { TPlayer }
  77.  
  78. constructor TPlayer.create();
  79. begin
  80.     x     := 1;
  81.     dir   := true;
  82.     state := TPlayerNormal.create;
  83. end;
  84.  
  85. procedure TPlayer.speed();
  86. begin
  87.     state := TPlayerSpeed.create;
  88. end;
  89.  
  90. procedure TPlayer.slow();
  91. begin
  92.     state := TPlayerNormal.create;
  93. end;
  94.  
  95. procedure TPlayer.move();
  96. begin
  97.     case (dir) of
  98.         TRUE : dir := not (x >= 80);
  99.         FALSE: dir := not (x <= 1);
  100.     end;
  101.  
  102.     case (dir) of
  103.         TRUE : x := x + state.vel;
  104.         FALSE: x := x - state.vel;
  105.     end;
  106.  
  107.     gotoxy(x, 1); write('V');
  108. end;
  109.  
  110. var Player: TPlayer;
  111.  
  112. begin
  113.     highvideo; cursoroff; clrscr;
  114.  
  115.     Player := TPlayer.create;
  116.  
  117.     repeat
  118.         if (keypressed()) then  
  119.         begin
  120.             clrscr;
  121.  
  122.             case (readkey()) of
  123.                 'w': Player.speed;
  124.                 's': Player.slow;
  125.                 ' ': exit;
  126.             end;
  127.  
  128.             Player.move; writeln; write(Player.state.vel);
  129.         end;
  130.     until (false);
  131. end.
  132.  

identifier idents no member "vel" at:
line(103,31);
line(104, 31);
line(128, 54);

can u help me?
« Last Edit: February 14, 2020, 03:04:07 pm by Synaii »

JuhaManninen

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 3685
  • I like bugs.
Re: identifier idents no member error
« Reply #1 on: February 14, 2020, 06:43:11 pm »
identifier idents no member "vel" at:
line(103,31);
line(104, 31);
line(128, 54);
state: IStatePlayer;
The interface IStatePlayer does not define the variable "vel". Naturally, because interfaces can only define methods.

Quote
can u help me?
Yes. Use an abstract base class instead of an interface. A base class can also have variables.
I don't know what design experts say but IMO an interface is overrated. In most cases an abstract base class does a better job. The only exception is when your design really needs multiple interfaces for one class. Such a situation can usually be avoided. Actually the concept of "interface" is a hack to complement the lack of multiple inheritance (as in C++), which again has many inherent problems.
Object Pascal makes the issue worse because it mixes memory management with interfaces. An interfaced object by default is freed automatically while other objects are not.

Lazarus IDE and its ...Intf classes that support plugins use abstract base classes extensively. Please take a look.
« Last Edit: February 14, 2020, 06:50:29 pm by JuhaManninen »

howardpc

  • Hero Member
  • *****
  • Posts: 3308
Re: identifier idents no member error
« Reply #2 on: February 14, 2020, 10:34:13 pm »
In fact a simpler approach without either interfaces or classes is better suited to this example.
When you have an interface or class hammer, the temptation is to see everything as a nail.

Whereas a record and an enumeration are all that is required.

For example:
Code: Pascal  [Select]
  1. program MyGame;
  2.  
  3. {$mode objfpc}
  4. {$ModeSwitch advancedrecords}
  5.  
  6. uses crt;
  7.  
  8. type
  9.  
  10.   TSpeed = (sStopped, sSlow, sFast, sVeryFast);
  11.  
  12.   TPlayer = record
  13.   private
  14.     directionRight: Boolean;
  15.     icon: Char;
  16.     speed: TSpeed;
  17.     velocity: Byte;
  18.     x: Byte;
  19.   public
  20.     procedure Init;
  21.     procedure ChangeSpeed(aSpeed: TSpeed);
  22.     procedure ReportVelocity;
  23.     procedure Move;
  24.   end;
  25.  
  26. procedure TPlayer.Init;
  27. begin
  28.   speed := sSlow;
  29.   x := 0;
  30.   velocity := Ord(speed);
  31.   directionRight := True;
  32.   icon := '>';
  33. end;
  34.  
  35. procedure TPlayer.ChangeSpeed(aSpeed: TSpeed);
  36. begin
  37.   if speed <> aSpeed then
  38.     begin
  39.       speed := aSpeed;
  40.       velocity := Ord(speed);
  41.     end;
  42. end;
  43.  
  44. procedure TPlayer.Move;
  45. begin
  46.   case directionRight of
  47.     True:  Inc(x, velocity);
  48.     False: Dec(x, velocity);
  49.   end;
  50.  
  51.   if x > 80 then
  52.     begin
  53.       x := 80;
  54.       directionRight := False;
  55.       icon := '<';
  56.     end
  57.   else
  58.   case speed of
  59.     sSlow: if x < 1 then
  60.              begin
  61.                x := 1;
  62.                directionRight := True;
  63.                icon := '>';
  64.              end;
  65.     sFast: if x < 2 then
  66.              begin
  67.                x := 1;
  68.                directionRight := True;
  69.                icon := '>';
  70.              end;
  71.     sVeryFast: if x < 3 then
  72.                  begin
  73.                    x := 1;
  74.                    directionRight := True;
  75.                    icon := '>';
  76.                  end;
  77.   end;
  78.  
  79.   GotoXY(x, 4);
  80.   Write(icon);
  81. end;
  82.  
  83. procedure TPlayer.ReportVelocity;
  84. begin
  85.   GotoXY(4, 6);
  86.   Write('velocity: ',velocity);
  87. end;
  88.  
  89. procedure GiveDirections;
  90. begin
  91.   GotoXY(1, 2);
  92.   Write('Keys:  s, S stop;  w, W: slow;  f, F fast;  v, V: very fast;   Space, Esc quit');
  93. end;
  94.  
  95. var
  96.   player: TPlayer;
  97.  
  98. begin
  99.   cursoroff;
  100.   ClrScr;
  101.   player.Init;
  102.  
  103.   while True do
  104.     begin
  105.       if KeyPressed then
  106.         begin
  107.           ClrScr;
  108.           GiveDirections;
  109.           case ReadKey of
  110.             'F','f': player.ChangeSpeed(sFast);
  111.             'W','w': player.ChangeSpeed(sSlow);
  112.             'S','s': player.ChangeSpeed(sStopped);
  113.             'V','v': player.ChangeSpeed(sVeryFast);
  114.             ' ', #27: begin
  115.                         ClrScr;
  116.                         Exit;
  117.                       end;
  118.           end;
  119.           player.Move;
  120.           player.ReportVelocity;
  121.         end;
  122.     end;
  123. end.
« Last Edit: February 15, 2020, 06:18:20 am by howardpc »