Autor Beitrag
klassiknerd
Hält's aus hier
Beiträge: 9
Erhaltene Danke: 5

Win 7 Ult., OS X 10.10.5
Delphi 7 Ent., Lazarus 1.6.2, QtCreator 3.6.1
BeitragVerfasst: Mo 24.11.14 18:08 
Hallo,

in der Schule wurde im Informatik-Unterricht der StringGrid durchgekaut und als Anwendung der Theorie das Spiel "Licht Aus!" programmiert. Dort muss man Figuren, die durch den Computer zufällig erzeugt werden, so bearbeiten, dass alle Lichter aus sind. Man klickt dabei auf ein Feld, dann ändert sich der Zustand des Feldes, aber nicht nur das, sondern die Felder, die über eine Kante mit dem geklickten Feld verbunden sind ändern sich auch. In meinen Fall ist dann kein Licht aus oder an, sondern das @ weg oder da.

Dabei war, so glaube ich, nur in meiner Programm-"Fassung" einer, dem Informatik-Lehrer und mir unerklärbarer, Fehler.

So sieht das Programm im Anfangszustand aus:
erstes
Natürlich ohne roten Kreis :wink:

Nach klicken des oben rot markierten Feldes, erscheint aber, wie im nächsten Bild zu sehen ist, auch ein "Licht" im oberen mittleren Feld, was nicht sein dürfte.
zweites

So ähnlich ist das auch, wenn man das untere mittlere Feld drückt. Dann wird fälschlicherweise das obere rechte "Licht" aktiviert. Die ist mir auf die schnelle aufgefallen, es kann jedoch noch sein, dass es noch andere "spukende Lampen" gibt.

Dem Phänomen konnte ich auch mit Variablen-Überwachung auf die schliche kommen, aber sowohl der Delphi-7-Personal-Compiler, als auch mein Delphi-7-Enterprise-Compiler, zeigen keine unterschiedlichen Ergebnisse. Deshalb vermute ich, dies liegt am Array: Ich glaube nämlich nicht, dass diesem egal ist, wenn man außerhalb des Arrays befüllen will. Den Schülern und Schülerinnen wurde zwar erzählt, dass diese falschen Eingaben Delphi abfängt, was ich aber nicht glaube. Natürlich gibt es das Programm inklusive Quellcode im Anhang zu laden.

Beste Grüße
klassiknerd
Einloggen, um Attachments anzusehen!
_________________
Wer all seine Ziele erreicht hat, hat sie sich als zu niedrig ausgewählt.
- H. v. Karajan


Zuletzt bearbeitet von klassiknerd am Sa 09.01.16 17:37, insgesamt 2-mal bearbeitet
Mathematiker
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 2622
Erhaltene Danke: 1447

Win 7, 8.1, 10
Delphi 5, 7, 10.1
BeitragVerfasst: Mo 24.11.14 18:40 
Hallo klassiknerd,
genau die Abfrage der Feldgrenzen ist die Fehlerursache, d.h. mit
ausblenden Delphi-Quelltext
1:
2:
3:
4:
  if y>0 then playground[X,Y-1]:=NOT(playground[X,Y-1]);
  if x>0 then playground[X-1,Y]:=NOT(playground[X-1,Y]);
  if y<2 then playground[X,Y+1]:=NOT(playground[X,Y+1]);
  if x<2 then playground[X+1,Y]:=NOT(playground[X+1,Y]);

wird es richtig.
Da ich(!) der Blödmann von Informatiklehrer war :autsch: , kann ich nur um Entschuldigung bitten, dass ich es nicht gleich gesehen habe.

Beste Grüße
Mathematiker

_________________
Töten im Krieg ist nach meiner Auffassung um nichts besser als gewöhnlicher Mord. Albert Einstein


Zuletzt bearbeitet von Mathematiker am Di 25.11.14 17:42, insgesamt 1-mal bearbeitet
Horst_H
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1652
Erhaltene Danke: 243

WIN10,PuppyLinux
FreePascal,Lazarus
BeitragVerfasst: Mo 24.11.14 18:44 
Hallo,

es wird überhaupt nicht getestet, ob der zulässige Bereich überschritten wird.
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
procedure TLichtAus.gridClick(Sender: TObject);
var x,y: Integer;
begin
  x:=grid.Col;
  y:=grid.Row;
  playground[X,Y]:=NOT(playground[X,Y]);
  playground[X,Y-1]:=NOT(playground[X,Y-1]);
  playground[X-1,Y]:=NOT(playground[X-1,Y]);
  playground[X,Y+1]:=NOT(playground[X,Y+1]);
  playground[X+1,Y]:=NOT(playground[X+1,Y]);
  drawplayground(sender);
end;

Wichtig sind nur die Randfelder.Hier x= 0 oder 2 und y = 0 oder 2
Wenn X = 0 ist darf x-1 nicht genutzt werden.
Wenn X = 2 ist darf x+1 nicht genutzt werden. Analog mit Y
Um das einfacher zu testen gibt es in Pascal schöne Möglichekeiten über die Typdefinitionen:
Dann fragt man nur nach x > Low(tXindex) und x < High(tXindex) so spart man sich festkodierte Zahlen.
Das Feld wird dann in tXindex und tYindex festgelegt.
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:
type
  tXindex = 0..2;
  tYindex = 0..2;  
var
  LichtAus: TLichtAus;
  playground: array[tXindex,tYindex] of boolean;
...
procedure TLichtAus.gridClick(Sender: TObject);
var x,y: Integer;
begin
  x:=grid.Col;
  y:=grid.Row;
  playground[X,Y]:=NOT(playground[X,Y]);
  IF Y > Low(tYindex)  then
     playground[X,Y-1]:=NOT(playground[X,Y-1]);
  IF X > Low(tXindex)  then  
    playground[X-1,Y]:=NOT(playground[X-1,Y]);
  IF Y < High(tYindex)  then
    playground[X,Y+1]:=NOT(playground[X,Y+1]);
  IF X < High(tXindex)  then
    playground[X+1,Y]:=NOT(playground[X+1,Y]);
  drawplayground(sender);
end;


Gruß Horst

Für diesen Beitrag haben gedankt: klassiknerd