Autor Beitrag
Angry
Hält's aus hier
Beiträge: 3



BeitragVerfasst: Di 13.11.07 17:20 
Hallo,
habe ein kleines Programm(zu Übungszwecken) geschrieben, welches Kästen in einem 3x3 Feld je nach Klick schwarz oder weiß färben soll.

Hier erstmal der Quelltext:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
//Färbt die Kästen je nach Eintrag im Array. lo steht dabei z.B. für LinksOben
procedure check;
begin
if (feld[1,1]=0then (form1.lo.Color:=clwhite) else (form1.lo.Color:=clblack);
if (feld[1,2]=0then (form1.mo.Color:=clwhite) else (form1.mo.Color:=clblack);
if (feld[1,3]=0then (form1.ro.Color:=clwhite) else (form1.ro.Color:=clblack);
if (feld[2,1]=0then (form1.lm.Color:=clwhite) else (form1.lm.Color:=clblack);
if (feld[2,2]=0then (form1.mm.Color:=clwhite) else (form1.mm.Color:=clblack);
if (feld[2,3]=0then (form1.rm.Color:=clwhite) else (form1.rm.Color:=clblack);
if (feld[3,1]=0then (form1.lu.Color:=clwhite) else (form1.lu.Color:=clblack);
if (feld[3,2]=0then (form1.mu.Color:=clwhite) else (form1.mu.Color:=clblack);
if (feld[3,3]=0then (form1.ru.Color:=clwhite) else (form1.ru.Color:=clblack);
end;

//Verändert das Array, also das angeklickte Kästen und die Anliegenden
procedure klick (i,j : integer);
begin
if (feld[i,j]=0then feld[i,j]:=1 else feld[i,j]:=0;
if (i>1and (feld[i-1,j]=0then feld[i-1,j]:=1 else feld[i-1,j]:=0;
if (i<3and (feld[i+1,j]=0then feld[i+1,j]:=1 else feld[i+1,j]:=0;
if (j>1and (feld[i,j-1]=0then feld[i,j-1]:=1 else feld[i,j-1]:=0;
if (j<3and (feld[i,j+1]=0then feld[i,j+1]:=1 else feld[i,j+1]:=0;
end;



Mein Problem:

Der Debugger gibt kein Problem aus und wenn ich auf die Kästchen, außer links oben und rechts oben klicke geht auch alles super!
Wenn ich eines der beiden Kästchen links oder rechts oben anklicke, also im Array feld[1,1] und feld[1,3] kommt folgende Fehlermeldung.

Zitat:
Benachrichtigung über Debugger-Exception

Im Projekt 3x3.exe ist eine Exception der Klasse EAccessViolation aufgetreten. Meldung: Zugriffsverletzung bei Adresse 0044EFBF in Modul '3x3.exe' Lesen von Adresse 000002F8.Prozess wurde angehalten.
Fortsetzen mit Einzelne Anweisung oder Start.


Die angebotene Delphi-Hilfe hat mich auch nicht weitergebracht. Ich hoffe hier kann mir jemand helfen!

Mit freundlichen Grüßen
Angry

Moderiert von user profile iconNarses: Quote- durch Delphi-Tags ersetzt
Narses
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Administrator
Beiträge: 10183
Erhaltene Danke: 1256

W10ent
TP3 .. D7pro .. D10.2CE
BeitragVerfasst: Di 13.11.07 18:57 
Moin und :welcome: im Forum!

Leider ist der vorgestellte Code zu knapp, um da was zu erkennen. :nixweiss: Zeig doch mal das ganze Programm! ;)

cu
Narses

_________________
There are 10 types of people - those who understand binary and those who don´t.
Sinspin
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1335
Erhaltene Danke: 118

Win 10
RIO, CE, Lazarus
BeitragVerfasst: Di 13.11.07 18:57 
Hallo und :welcome: ,

zeig mal die Deklaration deines Feldes und die Procedure die Klick(i,j) aufruft.

_________________
Wir zerstören die Natur und Wälder der Erde. Wir töten wilde Tiere für Trophäen. Wir produzieren Lebewesen als Massenware um sie nach wenigen Monaten zu töten. Warum sollte unser aller Mutter, die Natur, nicht die gleichen Rechte haben?
Angry Threadstarter
Hält's aus hier
Beiträge: 3



BeitragVerfasst: Di 13.11.07 22:05 
Okay dann hier die komplette Unit:

ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
113:
114:
115:
116:
117:
118:
119:
120:
121:
122:
123:
124:
125:
126:
127:
128:
129:
130:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ExtCtrls;

type
  TForm1 = class(TForm)
    lo: TPanel;
    mu: TPanel;
    mo: TPanel;
    ro: TPanel;
    rm: TPanel;
    ru: TPanel;
    mm: TPanel;
    lm: TPanel;
    lu: TPanel;
    Label1: TLabel;
    procedure FormCreate(Sender: TObject);
    procedure loClick(Sender: TObject);
    procedure moClick(Sender: TObject);
    procedure lmClick(Sender: TObject);
    procedure mmClick(Sender: TObject);
    procedure roClick(Sender: TObject);
    procedure rmClick(Sender: TObject);
    procedure ruClick(Sender: TObject);
    procedure muClick(Sender: TObject);
    procedure luClick(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;
  feld : array[1..3of array[1..3of integer;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
VAR i,j : integer;
begin
for i:=1 to 3 do begin
for j:=1 to 3 do
feld[i,j]:=0;
end;
end;

procedure check;
begin
if (feld[1,1]=0then (form1.lo.Color:=clwhite) else (form1.lo.Color:=clblack);
if (feld[1,2]=0then (form1.mo.Color:=clwhite) else (form1.mo.Color:=clblack);
if (feld[1,3]=0then (form1.ro.Color:=clwhite) else (form1.ro.Color:=clblack);
if (feld[2,1]=0then (form1.lm.Color:=clwhite) else (form1.lm.Color:=clblack);
if (feld[2,2]=0then (form1.mm.Color:=clwhite) else (form1.mm.Color:=clblack);
if (feld[2,3]=0then (form1.rm.Color:=clwhite) else (form1.rm.Color:=clblack);
if (feld[3,1]=0then (form1.lu.Color:=clwhite) else (form1.lu.Color:=clblack);
if (feld[3,2]=0then (form1.mu.Color:=clwhite) else (form1.mu.Color:=clblack);
if (feld[3,3]=0then (form1.ru.Color:=clwhite) else (form1.ru.Color:=clblack);
end;

procedure klick (i,j : integer);
begin
if (feld[i,j]=0then feld[i,j]:=1 else feld[i,j]:=0;
if (i>1and (feld[i-1,j]=0then feld[i-1,j]:=1 else feld[i-1,j]:=0;
if (i<3and (feld[i+1,j]=0then feld[i+1,j]:=1 else feld[i+1,j]:=0;
if (j>1and (feld[i,j-1]=0then feld[i,j-1]:=1 else feld[i,j-1]:=0;
if (j<3and (feld[i,j+1]=0then feld[i,j+1]:=1 else feld[i,j+1]:=0;
end;

procedure TForm1.loClick(Sender: TObject);
begin
klick (1,1);
check;
end;

procedure TForm1.moClick(Sender: TObject);
begin
klick (1,2);
check;
end;

procedure TForm1.lmClick(Sender: TObject);
begin
klick (2,1);
check;
end;

procedure TForm1.mmClick(Sender: TObject);
begin
klick (2,2);
check;
end;

procedure TForm1.roClick(Sender: TObject);
begin
klick (1,3);
check;
end;

procedure TForm1.rmClick(Sender: TObject);
begin
klick (2,3);
check;
end;

procedure TForm1.ruClick(Sender: TObject);
begin
klick (3,3);
check;
end;

procedure TForm1.muClick(Sender: TObject);
begin
klick (3,2);
check;
end;

procedure TForm1.luClick(Sender: TObject);
begin
klick (3,1);
check;
end;

end.
Narses
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Administrator
Beiträge: 10183
Erhaltene Danke: 1256

W10ent
TP3 .. D7pro .. D10.2CE
BeitragVerfasst: Di 13.11.07 23:44 
Moin!

user profile iconAngry hat folgendes geschrieben:
Wenn ich eines der beiden Kästchen links oder rechts oben anklicke, also im Array feld[1,1] und feld[1,3] kommt folgende Fehlermeldung.
Ich muss gestehen, ich kann nicht erklären, warum diese Exception auftritt (IMHO sollte das nicht passieren :nixweiss:), aber wenn du die Prozedur checkzu einer Methode der Formularklasse machst, dann kommt zumindest keine Exception mehr... :gruebel:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
type
  TForm1 = class(TForm)  
    lo: TPanel;
    //...
    procedure luClick(Sender: TObject);
    procedure check;
  private
    //...

var
  Form1: TForm1;
  feld : array[1..3,1..3of integer;

implementation

procedure TForm1.FormCreate(Sender: TObject);
//...

procedure TForm1.check;
begin
  if (feld[1,1]=0then lo.Color:=clwhite else lo.Color:=clblack;
  if (feld[1,2]=0then mo.Color:=clwhite else mo.Color:=clblack;
  if (feld[1,3]=0then ro.Color:=clwhite else ro.Color:=clblack;
  if (feld[2,1]=0then lm.Color:=clwhite else lm.Color:=clblack;
  if (feld[2,2]=0then mm.Color:=clwhite else mm.Color:=clblack;
  if (feld[2,3]=0then rm.Color:=clwhite else rm.Color:=clblack;
  if (feld[3,1]=0then lu.Color:=clwhite else lu.Color:=clblack;
  if (feld[3,2]=0then mu.Color:=clwhite else mu.Color:=clblack;
  if (feld[3,3]=0then ru.Color:=clwhite else ru.Color:=clblack;
end;

Allerdings ist dein Code noch nicht sehr effizient, daran solltest du noch arbeiten. ;)

cu
Narses

_________________
There are 10 types of people - those who understand binary and those who don´t.
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19322
Erhaltene Danke: 1749

W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Mi 14.11.07 10:05 
Das ist relativ einfach ;-).

user profile iconAngry hat folgendes geschrieben:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
//Verändert das Array, also das angeklickte Kästen und die Anliegenden
procedure klick (i,j : integer);
begin
if (feld[i,j]=0then feld[i,j]:=1 else feld[i,j]:=0;
if (i>1and (feld[i-1,j]=0then feld[i-1,j]:=1 else feld[i-1,j]:=0;
if (i<3and (feld[i+1,j]=0then feld[i+1,j]:=1 else feld[i+1,j]:=0;
if (j>1and (feld[i,j-1]=0then feld[i,j-1]:=1 else feld[i,j-1]:=0;
if (j<3and (feld[i,j+1]=0then feld[i,j+1]:=1 else feld[i,j+1]:=0;
end;
Wenn j größer als Eins ist und das Feld Null ist, dann wird 1 zugewiesen. Das ist ja auch ok.
Wenn aber j NICHT größer als Eins ist (else), dann wird dem Feld 0 zugewiesen. Leider gibts das Feld [i, 0] aber gar nicht.

Da bei statischen Arrays AFAIK keine Indexprüfung zur Laufzeit stattfindet, merkt Delphi das nicht. Und an dieser Stelle wird dann an eine Stelle im Speicher geschrieben, wo lieber nix geschrieben werden sollte, mit dem Ergebnis, dass Form1 nil ist. Und da Form1 jetzt nil ist, gibts natürlich Fehler beim Zugriff auf Elemente darin.

Lösung: Das "and" durch ein "then if" ersetzen, dann gilt das else nur für das innere if.
Narses
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Administrator
Beiträge: 10183
Erhaltene Danke: 1256

W10ent
TP3 .. D7pro .. D10.2CE
BeitragVerfasst: Mi 14.11.07 10:35 
Moin!

user profile iconjaenicke hat folgendes geschrieben:
Das ist relativ einfach ;-).
...allerdings! :autsch: (ich hätte diesen Teil des Codes als nächstes "renoviert", deshalb hab ich mir das gar nicht genauer angesehen... :roll:)

cu
Narses

_________________
There are 10 types of people - those who understand binary and those who don´t.
Angry Threadstarter
Hält's aus hier
Beiträge: 3



BeitragVerfasst: Mi 14.11.07 22:08 
:oops: da hätt ich auch selber drauf komm könn..

naja fang ja grad erst an...
Logikmensch
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 390

Win XP
Delphi 2007 Prof., XE2, XE5
BeitragVerfasst: Do 15.11.07 06:55 
Ja, da bist Du dem "Hanging else problem" aufgesessen. Oben mein Vorschlag zur Vermeidung unnötiger Abfragen (und selbst das ließe sich noch erheblich optimieren).

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
procedure klick (i,j : integer);  
begin  
  feld[i,j] := 1-feld[i,j];  
  if i>1 then feld[i-1,j] := 1-feld[i-1,j];
  if i<3 then feld[i+1,j] := 1-feld[i+1,j];  
  if j>1 then feld[i,j-1] := 1-feld[i,j-1];  
  if j<3 then feld[i,j+1] := 1-feld[i,j+1];  
end;

_________________
Es gibt keine Probleme - nur Lösungen!