AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

TicTacToe - Frage zum Programmablauf

Ein Thema von ShadowDeath · begonnen am 11. Apr 2017 · letzter Beitrag vom 12. Apr 2017
Antwort Antwort
Seite 3 von 3     123   
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
Benutzerbild von DeddyH
DeddyH

Registriert seit: 17. Sep 2006
Ort: Barchfeld
27.625 Beiträge
 
Delphi 12 Athens
 
#22

AW: TicTacToe - Frage zum Programmablauf

  Alt 12. Apr 2017, 16:30
Zitat:
TSpeedButton( Self.Controls[Y * 10 + X ] ).Caption := '';
Das wären bei X=3 und Y=3 ja 34 Controls (Index beginnt bei 0), und alle müssen Speedbuttons sein. Das erscheint mir ein wenig viel.
Detlef
"Ich habe Angst vor dem Tag, an dem die Technologie unsere menschlichen Interaktionen übertrumpft. Die Welt wird eine Generation von Idioten bekommen." (Albert Einstein)
Dieser Tag ist längst gekommen
  Mit Zitat antworten Zitat
ShadowDeath

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

AW: TicTacToe - Frage zum Programmablauf

  Alt 12. Apr 2017, 16:33
Zitat:
TSpeedButton( Self.Controls[Y * 10 + X ] ).Caption := '';
Das wären bei X=3 und Y=3 ja 34 Controls (Index beginnt bei 0), und alle müssen Speedbuttons sein. Das erscheint mir ein wenig viel.
Also wäre 2 der passende Multiplikator?

EDIT: Habe es grade mit 2 getestet. Leider lässt er 12,13 & 23 so wie sie sind & cleart dafür den Neustart-Speedbutton.
EDIT 2: ich habe vom Produkt nochmal 1 abgezogen, damit der neustart Button bleibt. Jetzt werden nur noch 13 & 23 nicht gecleart.

Geändert von ShadowDeath (12. Apr 2017 um 16:38 Uhr)
  Mit Zitat antworten Zitat
nahpets
(Gast)

n/a Beiträge
 
#24

AW: TicTacToe - Frage zum Programmablauf

  Alt 12. Apr 2017, 16:39
Dashier ist jetzt so nicht mehr richtig:
Delphi-Quellcode:
// 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;
Dashier sollte ausreichen:
Delphi-Quellcode:
  X := (Sender as TSpeedButton).Tag mod 10;
  Y := (Sender as TSpeedButton).Tag div 10;
Wir wollen ja, weil es nicht funktioniert, vom Durchlaufen von Self.Controls weg. Die Nutzung der Eigenschaft Tag dient ja genau der Abschaffung dieser fehleranfälligen Vorgehensweise.

Wir brauchen durch die Änderung auf die Tag-Nutzung nicht mehr abfragen, welcher Button gedrückt wurde. Der Button teilt uns dies durch den Inhalt von Tag selbst mit.

Der Button mit Tag = 11 sagt dadurch letztlich: "Ich bin der Butten von unten links."
Der Button mit Tag = 33 sagt uns: "Ich bin der Button von oben rechts."

Mit Tag mod 10 bzw. Tag div 10 wird der zweistellige Wert von Tag auf X und Y "verteilt", also in die jeweiligen Koordinaten umgerechnet.
  Mit Zitat antworten Zitat
ShadowDeath

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

AW: TicTacToe - Frage zum Programmablauf

  Alt 12. Apr 2017, 16:42
Ist erledigt. Trotzdem wird weiterhin 13 & 23 nicht gecleart.
  Mit Zitat antworten Zitat
nahpets
(Gast)

n/a Beiträge
 
#26

AW: TicTacToe - Frage zum Programmablauf

  Alt 12. Apr 2017, 16:49
Dieses ist so nicht korrekt, die "geographische" Lage der Buttons hat sich durch die Nutzung von Tag und die geänderten Namen nicht verändert.
Delphi-Quellcode:
 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;
Hier würd' ich es mal so versuchen:
Delphi-Quellcode:
  for X := 1 to 3 do for Y := 1 to 3 do Spielfeld[X,Y] := 0;
  for X := 0 to Self.Controls.Count - 1 do
    begin
      if Self.Controls[X] is TSpeedButton then
        begin
          if TSpeedButton(Self.Controls[X]).Tag <> 0 then TSpeedButton(Self.Controls[X]).Caption := '';
        end;
    end;
(Ist jetzt nur ungetestet hingedaddelt. Schreibfehler (wie immer) nicht ausgeschlossen.)
  Mit Zitat antworten Zitat
HolgerX

Registriert seit: 10. Apr 2006
Ort: Leverkusen
972 Beiträge
 
Delphi 6 Professional
 
#27

AW: TicTacToe - Frage zum Programmablauf

  Alt 12. Apr 2017, 16:54
Hmm..


Hab mir deinen Source genommen..
- Den Startbutton aber als TBitBtn
- Den Speedbuttons einen Tag von 0-9 verpasst
- Entsprechende Stellen umgestellt oder bereinigt

Und siehe da dein Basis-Code läuft.
Angehängte Dateien
Dateityp: zip Game_Tic Tac Toe.zip (232,4 KB, 3x aufgerufen)
  Mit Zitat antworten Zitat
ShadowDeath

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

AW: TicTacToe - Frage zum Programmablauf

  Alt 12. Apr 2017, 17:01
@nahpets: Danke, jetzt geht es & nochmals danke für die guten Erklärungen.
@Holger: Danke auch an dich. Ich werde mir den Code gleich anschauen
@ALLE: Danke für eure hilfreichen Antworten und Lösungsansätze.

PS: Ich habe noch ein Problem, um das ihr euch kümmern könnt, zudem ich nachher einen Thread erstellen werde ^^ (Geht um ein anderes Spiel)
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 3 von 3     123   


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 09:48 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz