![]() |
Problem mit Schleifen/Array/??? - Brettspiel Mastermind
Liste der Anhänge anzeigen (Anzahl: 2)
Hallo liebes Forum,
ich bin neu hier, (fachfremd) in Informatik unterrichtender Lehrer und bastele gerade an einem Projekt für meinen Wahlpflichtkurs im Jahrgang 10. Ich möchte das Brettspiel "Mastermind" als Smartphone-App umsetzen und stecke nun seit zwei Tagen fest. Leider weiß ich nicht mal, welche die passende Überschrift für mein Problem ist (siehe Titel). Sorry, hier jedenfalls die Infos ... Ziel d. Spiels: Das Programm generiert fünf Zufallsfarben, der Spieler muss sie mit möglichst wenigen Versuchen erraten. Er erhält nach jedem Versuch eine Rückmeldung, wie viele richtige Farben er hatte etc. Einen Screenshot des (noch im Rohbau befindlichen) Layouts habe ich angehängt. Mein Problem: Ich nutze zur Darstellung 60 TRectangles (12 Reihen mit je 5 Stück), welche dann mit einer Farbe befüllt werden. Ich wollte es vermeiden, 60 Zeilen Code nach dem Schema
Delphi-Quellcode:
zu schreiben. Ich habe mir gedacht, dass das auch einfacher und effektiver gehen muss und es mit einer for-Schleife (und Arrays) nach folgendem (erstmal vereinfachten) Schema probiert:
Form1.Rec1_1.Fill.Color := TAlphaColorRec.Blue;
Form1.Rec1_2.Fill.Color := ... ... Form1.Rec12_5.Fill.Color := ... ;
Delphi-Quellcode:
Soweit funktioniert alles. Sobald ich aber versuche, die im 2. Array gespeicherten und korrekt benannten Rechtecke mit einer Farbe zu versehen (und z.B. die folgende Code-Zeile hinzufüge) ...
...
// Array-Deklaration: rechteckenamen: array[1..5] of String; rechtecke: array[1..5] of TRectangle; ... // Befüllen des 1. Arrays (Namen d. Rectangle zunächst als string): for I := 1 to 5 do rechteckenamen[I] := 'Form1.Rec1_'+inttostr(I) ; // zum Testen die Namen auf nem Label anzeigen (ja, es klappt!) Form1.LbTest.Text := string(rechteckenamen[1])+#13#10 + string(rechteckenamen[2])+#13#10 + string(rechteckenamen[3])+#13#10 + string(rechteckenamen[4])+#13#10 + string(rechteckenamen[5])+#13#10 ; // Befüllen d. 2. Arrays (Umwandlung von string nach TRectangle) for J := 1 to 5 do rechtecke[J] := TRectangle(rechteckenamen[J]) ; // wieder Testen (ja, es klappt) Form1.LbTest2.Text := string(rechtecke[1])+#13#10 + string(rechtecke[2])+#13#10 + string(rechtecke[3])+#13#10 + string(rechtecke[4])+#13#10 + string(rechtecke[5])+#13#10 ;
Delphi-Quellcode:
... dann bekomme ich von RAD Studio zwar keine Fehler angezeigt, aber beim Ausführen des Programms (und Klick auf den entsprechenden Button) eine Fehlermeldung "Zugriffsverletzung bei Adresse ... in Modul ..." (siehe Anhang) angezeigt.
rechtecke[1].Fill.Color := TAlphaColorRec.Blue;
Ich bin hier irgendwie mit meinem Latein (bzw. meinen bescheidenen Programmierkenntnissen) am Ende und wäre daher sehr dankbar über ein paar Tipps ...
Vielen Dank schonmal und viele Grüße Christoph PS.: Ich habe diesen Post nach bestem Wissen und Gewissen erstellt. Auch die hier im Forum zu findenden Beiträge zum Brettspiel Mastermind haben mir bei meinem Problem leider nicht weitergeholfen. |
AW: Problem mit Schleifen/Array/??? - Brettspiel Mastermind
Hallo,
ich hoffe doch, dass dir bewußt ist, dass ein TRectangle ein Objekt ist? Die Objektinstanz muss man erst erzeugen, bevor man diese Verwenden kann. So wie du es machst, greifst du auf Speicher zu, der deinem jeweiligen Rectangle gar nicht gehört. Du schreibst also irgendwo in den Speicher weil die TRectangle Variablen ohne weitere Initialisierung einfach eine zufällige Speicheradresse enthalten. So und wie lösen wir das nun? Hier mal etwas Code der 60 Rectangles erzeugt und in eine Liste packt: Die Liste ist mittels Generics umgesetzt, falls das konzeptionell aber über euren Unterricht hinausgeht kann man das auch ein wenig mehr "OldSchool" umsetzen.
Delphi-Quellcode:
Und falls Generics zu heftig für euch ist:
unit BoardForm;
interface uses [..] // was alles für eine FMX Form usw. nötig ist System.Generics.Collections; type TBoardForm = class(TForm) private FRectangleList : TObjectList<TRectangle>; procedure CreateRectangle(x,y, Width, Height : Single; Color: TAlphaColor); public procedure CreateRectangles; end; implementation procedure TBoardForm.CreateRectangle(x,y, Width, Height : Single; Color: TAlphaColor); var Rectangle: TRectangle; begin Rectangle := TRectangle.Create(self); // Owner ist die eigene Form Rectangle.Position.X := x; Rectangle.Position.Y := y; Rectangle.Width := Width; Rectangle.Height := Height; Rectangle.Fill.Color := Color; FRectangleList.Add(Rectangle); end; procedure TBoardForm.CreateRectangles; var i : Integer; begin // Liste erzeugen inkl. OwnsObjects auf true, damit die hinzugefügten // Rectangles beim späteren Freigeben der Liste auch freigegeben werden. // Bei Desktopprogramm und ab Delphi 10.4 auch bei Smartphone App sonst // sog. Speicherleck. FRectangleList := TObjectList<TRectangle>.Create(true); // 60 Rectangles mal irgendwie erzeugen, X/Y Platzierung kannst du selber gerade ziehen for i := 1 to 60 do CreateRectangle(i*3, i*3, 5, 5, TAlphaColor.claBlue); // Ändern der Farbe eines bestimmten Rectangles (des 6.): FRectangleList[5].Fill.Color := TAlphaColor.claRed; end; Statt TObjectList<TRectangle> eine normale TObjctList; aus System.Contnrs benutzen und beim Lesezugriff typecasten: TRectangle(FRectangleList[5]).Fill.Color := TAlphaColor.claRed; Grüße TurboMagic |
AW: Problem mit Schleifen/Array/??? - Brettspiel Mastermind
Oder, wenn du die Rectangles nicht zur Laufzeit, sondern im Objekt-Inspector erzeugt, dieser Ansatz, den du schon versucht hast:
Statt: Zitat:
Delphi-Quellcode:
Damit speicherst du die Objektinstanzen der automatisch erzeugten Rectangles im deinem rechtecke - Array und kannst später darüber darauf zugreifen. Dein Array Rechteckenamen brauchst du nicht.
For i:=1 to 5 do
rechtecke[i]:=FindComponent('Rec1_'+inttostr(I)); Aber unbedingt das 'Form1' weglassen. Das gehört nicht zum Namen der Komponente, sondern ist der Name des Forms, auf dem die Komponente liegt. Zitat:
Abgesehen davon kann die Umwandlung von String zu TRectangle nicht funktionieren. Du speicherst hier einen String in deinem Rechtecke-Array, aber das ist nur der Name des Rectangles, nicht das Rectangle selbst. |
AW: Problem mit Schleifen/Array/??? - Brettspiel Mastermind
Was mich jetzt am Meisten überrascht, erschreckender Weise, ist,
dass der Compiler hier wirklich keinen Fehler oder zumindestens eine Warnung wirft. :shock: Zitat:
Man konvertiert keine "inkompatiblen" Typen ineinander. TRectangle ist ein TObject und kein string. FindComponent ist eine Methde, die ein Objekt dort findet, wo es über den Owner drin ist.
Delphi-Quellcode:
Was man über den FormDesigner draufgelegt hat, das hat als Owner die Form.
R := TRectangle.Create(TheOwner);
R.Name := 'abc'; ... R := TheOwner.FindComponent('abc'); Drum geht dort Self.FindCompoent() und in Methoden der eigenen Form, da kann man den Owner auch weglassen, daher einfach nur noch FindComponent(). Zitat:
Wenn du von Casts keine Ahnung hast, dann lasst es bitte sein. Und lerne bitte zuerst wie man es richtig macht, denn sonst machst du, so wie hier, nur das Speichermanagement kaputt und freust dich über das "schöne" Ergebnis, ein knallendes Feuerwerk. :firejump: Zitat:
Falls du unbedingt etwas benötigst, dann verwende an diesen Stellen das Self. |
AW: Problem mit Schleifen/Array/??? - Brettspiel Mastermind
Zitat:
rechteckenamen ist kein String, sondern ein Array. rechteckenamen[5] ist ein String. Wenn er keine Ahnung von Casts hat, dann soll er es lernen, aber nicht sein lassen. Was sind das denn für Empfehlungen hier?! |
Alle Zeitangaben in WEZ +1. Es ist jetzt 06:34 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz