Thema: Delphi wiedermal Stringgrid....

Einzelnen Beitrag anzeigen

Sebastian Nintemann
(Gast)

n/a Beiträge
 
#11
  Alt 2. Jan 2003, 11:57
Hallo Madeleine, jetzt kommts erstmal dick
Ich hab dir jetzt mal drei Procedures geschrieben. Ich hatte ja nicht deinen Form Entwurf, dehalb hab ich ne Form gemacht mit folgendem drauf
  • Ein DrawGrid mit dem Namen "DrawGrid" (scheint mir hier sinnvoller, Strings werden ja nicht gebraucht, ansonsten ist es genau das gleiche)
    Ein Edit ("EditW") für die Breite
    Ein Edit ("EditH") für die Höhe
    und ein Button ("ButtonStart") mit dem man das Spiel initialisiert.


Zunächst folgende globale Variablen
Delphi-Quellcode:
var
  Form1 : TForm1;
  w,h : Cardinal; //Höhe und Breite,
                    //Cardinal weil keine negativen Werte erlaubt sind
  field : Array of Array of Integer; //Spielfeld, 0 = leeres Feld, 1 = blau, 2 = gelb
  game : boolean = false; //Wird gespielt?
  Player: integer = 1; //Spieler, 1 = blau, 2 = gelb
Die Kommentare dürften für sich sprechen.
Dann die Initialisierung im OnClick von ButtonStart:
Delphi-Quellcode:
procedure TForm1.ButtonStartClick(Sender: TObject);
var
  i,j: integer;
begin
  try
    begin
      w := StrToInt(EditW.Text);
      h := StrToInt(EditH.Text); //Höhe und Breite (w und h) auslesen
      DrawGrid.ColCount := w;
      DrawGrid.RowCount := h+1; //Höhe und Breite auf das Grid anwenden
      SetLength(field,w); //Array auf die richtige Größe bringen
      for i := 0 to High(field) do
        begin
          SetLength(field[i],h);
          for j := 0 to h-1 do field[i,j] := 0; //alle Felder auf 0,
                                                //nötig wenn mehrmals gespielt wird
        end;
      DrawGrid.Enabled := true;
      DrawGrid.Repaint; //neu zeichnen,
                                                //auch nötig wenn mehrmals gespielt wird
      game := true //jetzt wird gespielt
    end
  except //im Fehlerfall: zurück das Kommando
    begin
      ShowMessage('Fehlerhafte Eingabe');
      EditW.SetFocus;
      exit
    end
  end
end;
Ich hab auch hier alles kommentiert, wenn du Fragen hast nur melden.

Jetzt fehlen nur noch zwei Sachen: Was passiert beim Klick (OnMouseDown) und wie werden die Zellen gezeichnet?

Delphi-Quellcode:
procedure TForm1.DrawGridDrawCell(Sender: TObject; ACol, ARow: Integer;
  Rect: TRect; State: TGridDrawState);
begin
  if (not game) or (ARow = 0) then exit;
  //wenn kein Spiel am laufen ist, oder die Zeile nicht im Feld ist dann abbrechen
  //ab dem zweiten Spiel ist egal ob ein Spiel am laufen ist, vorher gibts aber nen Fehler
  //weil das Array field dann noch nicht initialisiert ist, deshalb die Abfrage

  case field[ACol,ARow-1] of
    1: begin //wenn Spieler = 1 (blau)
         DrawGrid.Canvas.Brush.Color := clBlue; //Dann blaunen Kuller malen
         DrawGrid.Canvas.Ellipse(Rect);
       end;
    2: begin //wenn Spieler = 2 (gelb)
         DrawGrid.Canvas.Brush.Color := clYellow; //Dann gelben Kuller malen
         DrawGrid.Canvas.Ellipse(Rect)
       end
  end
end;
Hier werden die Zellen "gemalt". Wenn es sich nicht um eine Zelle handelt, in der ein Kreis sein soll, wird nichts weiter gemacht.
Jetzt das setzen im OnMouseDown:
Delphi-Quellcode:
procedure TForm1.DrawGridMouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
var
  aCol,aRow,i : integer;
begin
  DrawGrid.MouseToCell(X,Y,aCol,aRow);
  if (aRow <> 0) or (field[aCol,0]<>0) then exit; //Wenn nicht in die 1. Zeile geklickt wurde
                                                  //oder die Spalte schon voll ist aufhören
  i := h-1;
  while field[aCol,i] <> 0 do dec(i); //bestimmen welche die erste freie Zelle ist
  field[aCol,i] := Player; //Zelle mit Spieler besetzen
  if Player = 2 then dec(Player) else inc(Player);//Spielerwechsel
  DrawGrid.Repaint //und neu zeichnen
end;
So, das wars auch schon (fast), zum schluß noch das Array freigeben:
Delphi-Quellcode:
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
var
  i: integer;
begin
  for i := 0 to High(field) do //Array freigeben
    field[i] := nil;
  field := nil
end;
Das Programm funktioniert jetzt soweit, dass man ein spiel starten kann indem man gewünschte Höhe und Breite angibt, und dann auf start klickt. Dann kann man (abwechselnd gelbe und blaue) Kullerdinger auf das Feld werfen. Es prüft jetzt noch nicht auf Sieg und es gibt auch keinen Computerspieler, das müsstest du noch einbauen, oder wir zusammen.
Zum checken auf Sieg hab ich schon was im Kopf, kann ja später mal nen Ansatz posten. Lies dir erstmal den Code durch und guck ob du ihn verstehst, sonnst immer fragen!

Gruß, Sebastian
  Mit Zitat antworten Zitat