Recent

Author Topic: Jogo da memória  (Read 172 times)

zerowin

  • New member
  • *
  • Posts: 7
Jogo da memória
« on: April 11, 2019, 02:39:32 am »
fala guys, meu objetivo é montar um jogo da memória, mas cada vez que rodo o programa e clico em qualquer botão da tela, ele da erro e me redireciona pra isso
" GetTextMethod := TMethod(@Self.GetTextBuf);  "


A seguir o código:

Code: Pascal  [Select]
  1. unit Unit1;
  2.  
  3. {$mode Delphi}
  4.  
  5. interface
  6.  
  7. uses
  8.   Classes, SysUtils, Forms, Controls, Graphics, Dialogs, StdCtrls;
  9.  
  10. type
  11.  
  12.   { TForm1 }
  13.  
  14.     TForm1 = class(TForm)
  15.     GroupBox2: TGroupBox;
  16.     procedure FormCreate(Sender: TObject);
  17.     procedure FormDblClick(Sender: TObject);
  18.     procedure Clique(Sender: TObject);
  19.  
  20.  
  21.   private
  22.  
  23.   public
  24.  
  25.   end;
  26.  
  27. var
  28.   Form1: TForm1;
  29.   CartaVirada1      : TButton;
  30.   CartaVirada2      : TButton;
  31.   Viradas           : Integer;
  32.  
  33. implementation
  34.  
  35. {$R *.lfm}
  36.  
  37. { TForm1 }
  38. procedure TForm1.Clique(Sender: TObject);
  39.   begin
  40.  
  41.   if(Sender as TButton).Caption = 'OK' then
  42.   begin
  43.             ShowMessage('Esta carta já foi virada');
  44.   end
  45.  
  46.   else if(Sender as TButton).Caption <> 'OK' then
  47.   begin
  48.  
  49.   if(Sender as TButton).Caption = '' then
  50.             (Sender as TButton).Caption := (Sender as TButton).Hint
  51.   else
  52.   (Sender as TButton).Caption := '';
  53.  
  54.   Viradas := Viradas + 1;
  55.  
  56.   if(Viradas mod 2 = 1)then
  57.   CartaVirada1 := (Sender as TButton);
  58.  
  59.   if(Viradas mod 2 = 0) then
  60.   begin
  61.  
  62.     CartaVirada2 := (Sender as TButton);
  63.  
  64.  
  65.  
  66.  
  67.        if(CartaVirada1.Name = CartaVirada2.Name) then
  68.        begin
  69.             CartaVirada1.Caption := '';
  70.             CartaVirada2.Caption := '';
  71.        end
  72.  
  73.        else if(CartaVirada2.Caption = CartaVirada1.Caption) then
  74.        begin
  75.  
  76.        CartaVirada1.Caption := 'OK';
  77.        CartaVirada2.Caption := 'OK';
  78.  
  79.          end;
  80.  
  81.        end;
  82.  
  83.        if (CartaVirada2.Caption <> CartaVirada1.Caption) then
  84.        begin
  85.             ShowMessage('Tente Novamente');
  86.             CartaVirada1.Caption := '';
  87.             CartaVirada2.Caption := '';
  88.  
  89.        end;
  90.  
  91.        CartaVirada1 := Nil;
  92.        CartaVirada2 := Nil;
  93.  
  94.   end;
  95.   end;
  96.  
  97.  
  98. procedure TForm1.FormDblClick(Sender: TObject);
  99. var
  100.  
  101.   I       : Integer;
  102.   cont    : Integer;
  103.   num     : Integer;
  104.   linha   : Integer;
  105.   coluna  : Integer;
  106.   botao   : Tbutton;
  107.  
  108.  
  109.   letras          : array[0..5] of char = ('A','B', 'C', 'D', 'E', 'F');
  110.   letras2         : array[0..5] of char = ('A','B', 'C', 'D', 'E', 'F');
  111.   letrasRandom    : array[0..5] of char = ('.','.', '.', '.', '.', '.');
  112.   Result          :
  113. array[0..11] of char = ('.','.', '.', '.', '.','.','.','.', '.', '.', '.', '.');
  114.  
  115.  
  116. begin
  117.  
  118.   Randomize;
  119.  
  120.   cont      := 0;
  121.   linha     := 30;
  122.   coluna    := 30;
  123.  
  124.   for I := 0 to 5 do
  125.     begin
  126.          cont := Random(6);
  127.  
  128.          letrasRandom[I] := letras[cont];
  129.  
  130.          while letras[cont] = '.' do
  131.          begin
  132.                cont := Random(6);
  133.                letrasRandom[I] := letras[cont];
  134.  
  135.            end;
  136.             letras[cont] := '.';
  137.  
  138.  
  139.         end;
  140.  
  141.      for num := 0 to 5 do
  142.        begin
  143.          Result[num] := letrasRandom[num];
  144.        end;
  145.  
  146.      for I := 0 to 5 do
  147.        begin
  148.          cont := Random(6);
  149.  
  150.          letrasRandom[I] := letras2[cont];
  151.  
  152.          while letras2[cont] = '.' do
  153.          begin
  154.                cont := Random(6);
  155.                letrasRandom[I] := letras2[cont];
  156.  
  157.            end;
  158.             letras2[cont] := '.';
  159.              end;
  160.      for num := 0 to 5 do
  161.             begin
  162.               Result[num + 6] := letrasRandom[num];
  163.             end;
  164.      for I := 0 to 11 do
  165.             begin
  166.  
  167.                  botao := TButton.Create(Self);
  168.                  botao.Parent := Form1;
  169.                  botao.Height := 90;
  170.                  botao.Width  := 90;
  171.                  botao.Top    := coluna;
  172.                  botao.Left   := linha;
  173.  
  174.                  botao.Hint := Result[I];
  175.                  botao.Name := 'btn' + IntToStr(I);
  176.                  botao.Caption := '';
  177.                  botao.OnClick := Clique();
  178.  
  179.                  if ((I+1) mod 3 = 0) then
  180.                      begin
  181.                        coluna := coluna + 90;
  182.                        linha := 30;
  183.                      end
  184.                  else
  185.                      linha := linha + 90;
  186.                     end;
  187.  
  188. end;
  189.  
  190. procedure TForm1.FormCreate(Sender: TObject);
  191. begin
  192.  
  193. end;
  194.  
  195. end.    
                                 

Handoko

  • Hero Member
  • *****
  • Posts: 2991
  • My goal: build my own game engine using Lazarus
Re: Jogo da memória
« Reply #1 on: April 11, 2019, 07:00:05 am »
I tested, fixed and improved your source code. I saw you didn't properly format the source code, the indentation was bad, lots of empty lines, and you used the name FormDblClick for the form's onCreate event. Sorry if it sounds bad but this is for your own good.

All the bad habits mentioned above make your code harder to debug. After fixing them, the error becomes easy to be solved. Below is the fixed and improved version:

Code: Pascal  [Select]
  1. unit Unit1;
  2.  
  3. {$mode Delphi}
  4.  
  5. interface
  6.  
  7. uses
  8.   Classes, SysUtils, Forms, Controls, Graphics, Dialogs, StdCtrls;
  9.  
  10. type
  11.  
  12.   { TForm1 }
  13.  
  14.     TForm1 = class(TForm)
  15.     procedure FormCreate(Sender: TObject);
  16.   private
  17.     procedure Clique(Sender: TObject);
  18.   end;
  19.  
  20. var
  21.   Form1        : TForm1;
  22.   CartaVirada1 : TButton;
  23.   CartaVirada2 : TButton;
  24.   Viradas      : Integer;
  25.  
  26. implementation
  27.  
  28. {$R *.lfm}
  29.  
  30. { TForm1 }
  31. procedure TForm1.Clique(Sender: TObject);
  32. var
  33.   Current: TButton;
  34. begin
  35.  
  36.   if not(Sender is TButton) then Exit; // Exit if it is not a TButton
  37.  
  38.   Current := Sender as TButton;
  39.  
  40.   if Current.Caption = 'OK' then // Exit if it is already been turned
  41.   begin
  42.     ShowMessage('Esta carta já foi virada');
  43.     Exit;
  44.   end;
  45.  
  46.   if Current.Caption = '' then
  47.     Current.Caption := Current.Hint
  48.   else
  49.     Current.Caption := '';
  50.  
  51.   Viradas := Viradas + 1;
  52.  
  53.   if (Viradas mod 2 = 1) then
  54.   begin
  55.     CartaVirada1 := Current;
  56.     Exit;
  57.   end;
  58.  
  59.   if (Viradas mod 2 = 0) then
  60.   begin
  61.     CartaVirada2 := Current;
  62.     if(CartaVirada1.Name = CartaVirada2.Name) then
  63.     begin
  64.       CartaVirada1.Caption := '';
  65.       CartaVirada2.Caption := '';
  66.     end
  67.     else
  68.       if(CartaVirada2.Caption = CartaVirada1.Caption) then
  69.       begin
  70.         CartaVirada1.Caption := 'OK';
  71.         CartaVirada2.Caption := 'OK';
  72.       end;
  73.  
  74.     end;
  75.     if (CartaVirada2.Caption <> CartaVirada1.Caption) then
  76.     begin
  77.       ShowMessage('Tente Novamente');
  78.       CartaVirada1.Caption := '';
  79.       CartaVirada2.Caption := '';
  80.     end;
  81.  
  82.     CartaVirada1 := nil;
  83.     CartaVirada2 := nil;
  84.  
  85. end;
  86.  
  87. procedure TForm1.FormCreate(Sender: TObject);
  88. var
  89.   i            : Integer;
  90.   cont         : Integer;
  91.   linha        : Integer;
  92.   coluna       : Integer;
  93.   botao        : Tbutton;
  94.   letras       : array[0..5] of char = ('A', 'B', 'C', 'D', 'E', 'F');
  95.   letras2      : array[0..5] of char = ('A', 'B', 'C', 'D', 'E', 'F');
  96.   letrasRandom : array[0..5] of char = ('.', '.', '.', '.', '.', '.');
  97.   Result       :
  98.     array[0..11] of char = ('.','.','.','.','.','.','.','.','.','.','.','.');
  99. begin
  100.  
  101.   Randomize;
  102.   cont   := 0;
  103.   linha  := 30;
  104.   coluna := 30;
  105.  
  106.   for i := 0 to 5 do
  107.   begin
  108.     cont := Random(6);
  109.     letrasRandom[i] := letras[cont];
  110.     while letras[cont] = '.' do
  111.     begin
  112.       cont := Random(6);
  113.       letrasRandom[i] := letras[cont];
  114.     end;
  115.     letras[cont] := '.';
  116.   end;
  117.  
  118.   for i := 0 to 5 do
  119.     Result[i] := letrasRandom[i];
  120.  
  121.   for i := 0 to 5 do
  122.   begin
  123.     cont := Random(6);
  124.     letrasRandom[i] := letras2[cont];
  125.     while letras2[cont] = '.' do
  126.     begin
  127.       cont := Random(6);
  128.       letrasRandom[i] := letras2[cont];
  129.     end;
  130.     letras2[cont] := '.';
  131.   end;
  132.  
  133.   for i := 0 to 5 do
  134.     Result[i+6] := letrasRandom[i];
  135.  
  136.   for i := 0 to 11 do
  137.   begin
  138.     botao         := TButton.Create(Self);
  139.     botao.Parent  := Form1;
  140.     botao.Height  := 90;
  141.     botao.Width   := 90;
  142.     botao.Top     := coluna;
  143.     botao.Left    := linha;
  144.     botao.Hint    := Result[i];
  145.     botao.Name    := 'btn' + IntToStr(I);
  146.     botao.Caption := '';
  147.     botao.OnClick := Clique;
  148.     if ((i+1) mod 3 = 0) then
  149.     begin
  150.       coluna := coluna + 90;
  151.       linha := 30;
  152.     end
  153.     else
  154.       linha := linha + 90;
  155.   end;
  156.  
  157. end;
  158.  
  159. end.

  • You should put your own procedure/function in the private/public section. See line #17. It lets you know that the procedure/function is not automatically generated by double clicking the related event on the Object Inspector.
  • See line #36. It is good to check and exit if the sender is not the thing we want.
  • You use too many levels of if-then-else block. With any additional if-then-else block, the code becomes harder to maintain. Depends on the situation, sometimes we can to minimize the level by using exit instead of else begin. See line #40.
  • Don't use extra variable is it is not needed. See line #89, I removed the variable "num". You use num for looping but actually you already has i and that is enough. For your information, the variables i, j, k are usually written in lower case.
  • See line #87. Previously you used the name FormDblClick for the event. That causes confusion, so I renamed it to FormCreate.
And now it the most important thing you're interested to know.
Why you got that error?

That happened because CartaVirada2 is not initialized when the process reaches the line #75. How to fix it? It can be solved by using an exit, see line #56.
« Last Edit: April 11, 2019, 07:01:50 am by Handoko »