Einzelnen Beitrag anzeigen

ShadowDeath

Registriert seit: 11. Apr 2017
10 Beiträge
 
#21

AW: TicTacToe - Frage zum Programmablauf

  Alt 12. Apr 2017, 16:27
Erstmal danke nahpets, dass du dir die Zeit genommen hast mir das zu erklären. Die Gewinn-Abfrage funktioniert jetzt auch. Leider ist ein neues Problem aufgetreten: Der Neustart Button hat den Geist aufgegeben. Beim Klicken sagt er, dass eine Zugriffsverletzung vorliegt? Ich habe aus der 3 eine 10 gemacht, da wir ja weiter oben mit 10 Teilen (Beim Kommentar 'Spiel intern und optisch löschen'). & Sorry für die dämlichen Fragereien, aber ich arbeite noch nicht solange mit Delphi

Aktueller Code:
Delphi-Quellcode:
unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.Buttons;

type
  TForm1 = class(TForm)
    btnX1Y3: TSpeedButton;
    btnX2Y3: TSpeedButton;
    btnX1Y2: TSpeedButton;
    btnX2Y2: TSpeedButton;
    btnX3Y3: TSpeedButton;
    btnX3Y2: TSpeedButton;
    btnX1Y1: TSpeedButton;
    btnX2Y1: TSpeedButton;
    btnX3Y1: TSpeedButton;
    btnNeuesSpiel: TSpeedButton;
    procedure btnX1Y3Click(Sender: TObject);
    procedure btnNeuesSpielClick(Sender: TObject);
    procedure FormCreate(Sender: TObject);

  private
    { Private-Deklarationen }
    Spielfeld: array[1..3, 1..3] of Byte;
    Spieler, Starter, Gewinner: Byte;
    function ErmittelGewinner() : Byte;

  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

// FELD 1 bis Feld 9
procedure TForm1.btnX1Y3Click(Sender: TObject);
var
  X, Y: Byte;
  Index: Byte;
begin
  // Ist der Sender überhaupt ein Speedbutton?
  If not (Sender is TSpeedButton) then Exit;

  // Ist das Spiel schon vorbei?
  If Gewinner <> 0 then
    begin
      ShowMessage( 'Das Spiel ist bereits vorbei. Bitte starte ein neues Spiel.' );
      Exit;
    end;

  // Welcher Button wurde gedrückt?
  X := 90;
  Y := 90;
  for Index := 0 to Self.ControlCount - 1 do
  begin
   If Sender = Self.Controls[ Index ] then
   begin
     X := (Sender as TSpeedButton).Tag mod 10;
     Y := (Sender as TSpeedButton).Tag div 10;
   end;
  end;

  // Wurde der Button gefunden?
  if ( X > 3 ) or ( Y > 3 ) then exit;

  // Ist das gewünschte Feld noch frei?
  If Spielfeld[ X, Y ] <> 0 then
  begin
    ShowMessage( 'Das Feld ist schon besetzt. Bitte wähle ein anderes aus.' );
    Exit;
  end;

  // Zug optisch ausführen
  case Spieler of
    1: TSpeedButton( Sender ).Caption := 'X';
    2: TSpeedButton( Sender ).Caption := 'O';
    else
    begin
      ShowMessage( 'Unerwarteter Fehler!' );
      Exit;
    end;
  end;

  // Zug intern ausführen
  Spielfeld[ X, Y ] := Spieler;

  // Spieler wechseln
  Spieler := Spieler mod 2 + 1;

  // Sieger ermitteln
  Gewinner := ErmittelGewinner();
  //ShowMessage( Format( 'Spieler %d hat gewonnen.', [ Gewinner ] ) );

  // Entsprechend des Siegers eine Meldung ausgeben
  case Gewinner of
    0: Exit;
    1,2: ShowMessage( Format( 'Spieler %d hat gewonnen.', [ Gewinner ] ) );
    3: ShowMessage( 'Das Spiel endet unentschieden.' );
  end;
end;

// NEUES SPIEL
procedure TForm1.btnNeuesSpielClick(Sender: TObject);
var
  X, Y: Byte;
begin
   // Spiel intern und optisch löschen
   for X := 1 to 3 do
   begin
     for Y := 1 to 3 do
     begin
       Spielfeld[ X, Y ] := 0;
       TSpeedButton( Self.Controls[Y * 10 + X ] ).Caption := '';
     end;
   end;

   // Entscheiden, wer die nächste Runde beginnen darf
   case Gewinner of
     1,2: Starter := Gewinner mod 2 + 1; // Der Verlierer startet
     0,3: Starter := Starter mod 2 + 1; // Spieler 2 aus der vorherigen Runde ist nun Spieler 1
   end;

   // Vorbereitungen abschließen
   Spieler := Starter;
   Gewinner := 0;

end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  Spieler := 1;
  Starter := 1;
end;

function TForm1.ErmittelGewinner() : Byte;
var
  X, Y: Byte;
begin
  // Gewinner ermitteln

  // Gibt es einen Gewinner auf der Y-Achse?
  for X := 1 to 3 do
  begin
    Result := Spielfeld[ X, 1 ];
    if ( Result <> Spielfeld[ X, 2 ] ) or ( Result <> Spielfeld[ X, 3 ] ) then Result := 0;
    If Result <> 0 then Exit;
  end;

  // Gibt es einen Gewinner auf der X-Achse?
  for Y := 1 to 3 do
  begin
    Result := Spielfeld[ 1, Y ];
    if ( Result <> Spielfeld[ 2, Y ] ) or ( Result <> Spielfeld[ 3, Y ] ) then Result := 0;
    If Result <> 0 then Exit;
  end;

  // Gibt es diagonal einen Gewinner? (Von Links-Oben nach Rechts-Unten)
  for Y := 1 to 3 do
  begin
    Result := Spielfeld[ 1, 1 ];
    if ( Result <> Spielfeld[ 2, 2 ] ) or ( Result <> Spielfeld[ 3, 3 ] ) then Result := 0;
    If Result <> 0 then Exit;
  end;

  // Gibt es diagonal einen Gewinner? (Von Rechts-Oben nach Links-Unten)
  for Y := 1 to 3 do
  begin
    Result := Spielfeld[ 3, 1 ];
    if ( Result <> Spielfeld[ 2, 2 ] ) or ( Result <> Spielfeld[ 1, 3 ] ) then Result := 0;
    If Result <> 0 then Exit;
  end;

  // Gibt es noch ein freies Feld? (Das Spiel geht dann noch weiter)
  for X := 1 to 3 do
  begin
    for Y := 1 to 3 do
    begin
      if Spielfeld[ X, Y ] = 0 then Exit;
    end;
  end;

  // Es gab bisher keinen Gewinner. Freie Felder gibt es auch nicht mehr.
  // Das Spiel endet also unentschieden.
  Result := 3;

end;

end.
  Mit Zitat antworten Zitat