Also in diesem Fall würde ich folgendermaßen vorgehen:
Als erstes solltest du einen 2-Dimensionalen Array Typ verwenden
Delphi-Quellcode:
type
TMy2DArray = Array[0..3,0..3] of boolean;
// Der Inhalt des Feldes ist entweder Rot oder nicht rot, also sollte Boolean genügen
{ ... }
var // und noch eine Variable, die das Feld darstellt
My2DArray: TMy2DArray;
Als nächstes brauchst du eine Zeichenfläche, die dein Feld darstellt, es ist in diesem fall zwar
möglich, 16 Labels zu nehmen, aber es ist viel schöner, wenn wir das alles auf ein Canvas Objekt zeichnen.
Ein TImage sollte hier genügen. und was Machst du, wenn du nicht 16, sondern 160 Labels hast...
Jetzt sollten wir uns überlegen, wie wir das Ganze zeichnen. Da wir ein zweidimensionales Array haben,
können wir bequem mit zwei For-Schleifen arbeiten.
Delphi-Quellcode:
procedure Zeichne(Arr: TMy2DArray; img: TImage);
var x,
y, // Das sind die beiden Variablen für die Schleifen
breite,
hoehe: integer;
Buffer: TBitmap; // Zunächst auf den Buffer zeichnen;
begin
Buffer := TBitmap.Create; // Den Konstruktor des Buffers aufrufen,
// Damit wir darauf Zeichnen können
Buffer.Width := img.Width;
Buffer.Height := img.Height; // Dem Buffer die Richtige Größe zuweisen
Breite := Buffer.Width div Length(Arr); // Breite und Hoehe eines Feldes
Hoehe := Buffer.Height div Length(Arr[x]); // ausrechnen
for x := low(Arr) to high(Arr) do // Die Schleifen
for y := low(Arr[x]) to high(Arr[x]) do
begin
if Arr[x,y] // Wenn das Feld true ist...
then
Buffer.Canvas.Brush.Color := clred
else
Buffer.Canvas.Brush.Color := clwhite;
Buffer.Canvas.Rectangle(x*breite,y*hoehe,(x+1)*breite,(y+1)*hoehe);
//jetzt zeichnen wir an die Dementsprechende Stelle ein Rechteck
end;
img.Canvas.Draw(0,0,Buffer); //Den Buffer auf das Image zeichnen
Buffer.Free; // Den Buffer wieder freigeben
end;
Aber wie können wir durch klicken den Gewünschten effekt erzielen? Ganz einfach:
Im OnMouseDown Ereignis deines TImage werden die Koordinaten mitübergeben, also können
wir daraus die Position errechnen:
Delphi-Quellcode:
procedure TForm1.Image1MouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
Var PosX,
PosY: integer;
begin
PosX := X div (image1.Width div length(My2DArray));
PosY := Y div (image1.Height div length(My2DArray[x]));
// Die Positionen im Array ausrechnen
if (PosX in [low(My2DArray)..high(My2DArray)]) and
(PosY in [low(My2DArray[PosX])..high(My2DArray[PosY])])
then // Liegen die Werte auch wirklich innerhalb des Arrays?
begin
My2DArray[PosX,PosY] := not My2DArray[PosX,PosY];
// Jeweils überprüfen, ob man sich am Rand befindet
if PosX > low(My2DArray)
then
My2DArray[PosX-1,PosY] := not My2DArray[PosX-1,PosY];
if PosX < high(My2DArray)
then
My2DArray[PosX+1,PosY] := not My2DArray[PosX+1,PosY];
if PosY > low(My2DArray[PosX])
then
My2DArray[PosX,PosY-1] := not My2DArray[PosX,PosY-1];
if PosY < high(My2DArray[PosX])
then
My2DArray[PosX,PosY+1] := not My2DArray[PosX,PosY+1];
end;
Zeichne(My2DArray,image1); // Jetzt nur noch zeichen
if AlleTrue(My2DArray) // Siehe unten
then
showmessage('Geschafft');
end;
Jetzt müssen wir nur noch überprüfen, ob nach dem Klicken alle Felder Rot sind
Delphi-Quellcode:
function AlleTrue(Arr: TMy2DArray): boolean;
var Bool: boolean; // Hilfsvariable
x,
y: integer; // Zählvariablen für die Schleife
begin
Bool := true;
for x := low(Arr) to high(Arr) do // Die Schleifen
for y := low(Arr[x]) to high(Arr[x]) do
if not Arr[x,y]
then
bool := false;
result := bool;
end;
Und schon haben wir das Spiel fertig! Und das beste daran ist: Das Ganze ist so dynamisch gehalten,
dass du einfach die Werte oben in der Arraydeklaration ändern kannst, und es wird weiterhin funktionieren, z.B.:
TMy2DArray = Array[0..5,0..9] of boolean;
So viel Spaß damit und ich hoffe, mein Erklärungen waren ausführlich genug
Gruß Richard
PS: Grob getestet, sollte keine Fehler aufweisen...
Übrigens: Eine Feldgröße von 4*4 würde ich nicht empfehlen, da man in 4 Klicks gewinnen kann...