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 1 von 2  1 2      
ShadowDeath

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

AW: TicTacToe - Frage zum Programmablauf

  Alt 12. Apr 2017, 09:27
Also, erstmal danke für die zahlreichen Antworten. Ich habe erst einmal die falschen Tags korrigiert, damit es übersichtlicher ist. Zum Punkt, was den nun nicht funktioniert: Er erkennt nie den Gewinner, egal welche Gewinn Konstellation ich teste (sei es diagonal, vertikal oder horizontal). Gewünscht ist, dass er eine Message mit dem Gewinner ausgibt.

Delphi-Quellcode:
 // Sieger ermitteln
  Gewinner := ErmittelGewinner();

  // 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;
Und bezüglich der Tags von VCL-Komponenten: Ich war mir bewusst, dass es diese Eigenschaft für VCL Komponente gibt. Doch leider habe ich mich vorher nie damit auseinander gesetzt, deswegen nahm ich die 'unsaubere' Methoden anhand der Erstellungsreihenfolge (1-9 gehören zum Spielfeld, 10 ist der Neustart Button). Also dürfte es da keine Probleme geben (außer die Unsauberkeit des Codes).
Ich werde versuchen weitgehend alles Überflüssige zu entfernen (For-Schleifen) bzw. zu optimieren (Tags). Dennoch bin ich überzeugt, dass der Fehler woanders liegt. Ich würde mich sehr freuen, wenn ich noch ein paar Lösungsansätze finden würdet bzw. mit mir teilen würdet.
  Mit Zitat antworten Zitat
a.def
(Gast)

n/a Beiträge
 
#2

AW: TicTacToe - Frage zum Programmablauf

  Alt 12. Apr 2017, 09:58
Delphi-Quellcode:
case Gewinner of
    0: Exit;
Das ist überflüssig, da nach dem Case ja eh kein Code mehr kommt.
  Mit Zitat antworten Zitat
Whookie

Registriert seit: 3. Mai 2006
Ort: Graz
450 Beiträge
 
Delphi 10.3 Rio
 
#3

AW: TicTacToe - Frage zum Programmablauf

  Alt 12. Apr 2017, 10:11
1. Die Lösung steht doch vermutlich schon in #4
2. Verwende den Debugger und schau dir deine Variablen an
3. Wozu soll die angehängte .exe im Zipfile gut sein? Wenn du möchtest das sich das jemand hier ansieht dann häng das Projekt an, so das man es compilen kann (.exe erstellen kann hier sogut wie jeder )
Whookie

Software isn't released ... it is allowed to escape!
  Mit Zitat antworten Zitat
ShadowDeath

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

AW: TicTacToe - Frage zum Programmablauf

  Alt 12. Apr 2017, 11:45
Ich habe es jetzt nochmal ausführlich getestet. Dabei ist mir aufgefallen, dass es manchmal funktioniert und manchmal nicht. Leider bin ich nicht in der Lage die Ursache zu finden, die fürs funktionieren/nicht funktionieren verantwortlich ist. Ich denke aber es liegt an gesagtem ControlCount. Leider weiß ich nicht, wie ich das Programm debuggen soll. In der Starter Edition ist die Debug Option leider nicht enthalten :/
  Mit Zitat antworten Zitat
a.def
(Gast)

n/a Beiträge
 
#5

AW: TicTacToe - Frage zum Programmablauf

  Alt 12. Apr 2017, 11:48
Dann setz doch mal zur Überprüfung an verschiedenen Stellen Showmessage()-Boxen, welche die aktuellen Variableninhalte oder sonst was ausgeben.
So mache ich das immer, obwohl ich einen Debugger habe.
  Mit Zitat antworten Zitat
nahpets
(Gast)

n/a Beiträge
 
#6

AW: TicTacToe - Frage zum Programmablauf

  Alt 12. Apr 2017, 12:06
Nachdem ich jetzt mal 'ne Weile mit der EXE rumgespielt habe, bin ich mir fast sicher, dass das interne Spielfeld hier  Spielfeld[ X, Y ] := Spieler; anders befüllt wird, als die optische Darstellung der Captions suggeriert.

Um das zu prüfen, solltest Du zuerst mal mit dem Debugger schauen, was genau passiert. (Sorry, hatte den Hinweis, auf des Fehlen des Debuggers, irgendwie nicht wahrgenommen )

Dort, wo Du dem Anwender das Ergebnis per ShowMessage anzeigst, könntest Du auch mal das Spielfeld ausgeben. Das könnte mit 'nem weiteren ShowMessage passieren:
Delphi-Quellcode:
ShowMessage(Format('%d %d %d',[SpielFeld[0,0],SpielFeld[1,0],SpielFeld[2,0]) + #13
+ Format('%d %d %d',[SpielFeld[0,1],SpielFeld[1,1],SpielFeld[2,1]) + #13
+ Format('%d %d %d',[SpielFeld[0,2],SpielFeld[1,2],SpielFeld[2,2]));
(Hoffentlich hab' ich hier jetzt nicht X und Y vertauscht.)
Die Anzeige sollte mit der Darstellung der Speedbutton-Captions übereinstimmen.
Wenn nicht, stimmt die erwartete Reichenfolge der Speedbuttons in Self.Controls nicht mit der tatsächlichen überein.
Anders kann ich mir die etwas chaotische Ergebnisermittlung, mit kaum einem richtigen Ergebnis, nicht vorstellen.

Geändert von nahpets (12. Apr 2017 um 12:19 Uhr) Grund: Ok - verstanden, nix Debugger - irgendwie überlesen :-(
  Mit Zitat antworten Zitat
a.def
(Gast)

n/a Beiträge
 
#7

AW: TicTacToe - Frage zum Programmablauf

  Alt 12. Apr 2017, 12:12
Zitat:
Um das zu prüfen, solltest Du zuerst mal mit dem Debugger schauen, was genau passiert.
Seine IDE hat keinen Debugger
  Mit Zitat antworten Zitat
Whookie

Registriert seit: 3. Mai 2006
Ort: Graz
450 Beiträge
 
Delphi 10.3 Rio
 
#8

AW: TicTacToe - Frage zum Programmablauf

  Alt 12. Apr 2017, 12:31
Nimm einfach die Tag-Eigenschaft und schreib da die Koordinaten rein so wie das in #4 steht!
Die Erstellreihenfolge hat genau NICHTS mit deiner Anordnung der Buttons zu tun...
Whookie

Software isn't released ... it is allowed to escape!
  Mit Zitat antworten Zitat
SProske

Registriert seit: 16. Feb 2015
Ort: Halle/S.
116 Beiträge
 
Delphi 10.2 Tokyo Enterprise
 
#9

AW: TicTacToe - Frage zum Programmablauf

  Alt 12. Apr 2017, 12:43
Sofern ich mich nicht ganz falsch erinnere, hat die Starter durchaus einen Debugger, nur wurden einem Variableninhalte nicht beim Mouseover angezeigt, sondern diese mussten zu den überwachten Ausdrücken hinzugefügt werden. Haltepunkte setzen, durchsteppen etc. funktionierte aber ganz normal.
Sebastian
  Mit Zitat antworten Zitat
madas

Registriert seit: 9. Aug 2007
207 Beiträge
 
#10

AW: TicTacToe - Frage zum Programmablauf

  Alt 12. Apr 2017, 12:58
Schnellschuss ins Blaue:

Delphi-Quellcode:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TPlayer = (pX = -1, pNobody = 0, pO = 1);

  TForm1 = class(TForm)
    Button11: TButton;
    Button12: TButton;
    Button13: TButton;
    Button21: TButton;
    Button22: TButton;
    Button23: TButton;
    Button31: TButton;
    Button32: TButton;
    Button33: TButton;
    ButtonNewGame: TButton;
    LabelCurrentPlayer: TLabel;

    procedure ButtonClick(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure ButtonNewGameClick(Sender: TObject);
  private
    fCurrentPlayer, fLastWinner: TPlayer;
    dFrom13To31, dFrom11To33, FMoves: Integer;
    fZeilen, fSpalten: array[1..3] of Integer;

    procedure NewGame;
    procedure NextPlayer;
    procedure ResetPlayground;
    procedure UpdateStatus;

    function IsGameOver: Boolean;
    procedure DisablePlayground;
  public
  end;

var
  Form1: TForm1;

implementation

uses TypInfo;

{$R *.dfm}

procedure TForm1.ButtonClick(Sender: TObject);
var
  btn: TButton;
  x, y: Integer;
begin
  if (Assigned(Sender)) and (Sender is TButton) then
  begin
    Inc(FMoves);

    btn := TButton(Sender);

    case fCurrentPlayer of
      pX: btn.Caption := 'X';
      pO: btn.Caption := 'O';
    end;

    btn.Enabled := false;

    x := btn.Tag mod 10;
    y := btn.Tag div 10;

    Inc(fSpalten[x], Ord(fCurrentPlayer));
    Inc(fZeilen[y], Ord(fCurrentPlayer));

    if (x = y) then
    begin
      Inc(dFrom11To33, Ord(fCurrentPlayer));
      if (x = 2) then
        Inc(dFrom13To31, Ord(fCurrentPlayer));
    end else
    begin
      if (Abs(x - y) = 2) then
        Inc(dFrom13To31, Ord(fCurrentPlayer));
    end;

    // Gewinner ermitteln
    if (IsGameOver) then
    begin
      DisablePlayground;
      case fLastWinner of
        pX: ShowMessage('Winner is X');
        pO: ShowMessage('Winner is O');
        pNobody: ShowMessage('draw');
      end;
      Exit;
    end;

    NextPlayer;
  end;
end;

function TForm1.IsGameOver: Boolean;
var
  i: Integer;
begin
  Result := False;
  for i := 1 to 3 do
  begin
    Result := Result or (Abs(fSpalten[i]) = 3) or (Abs(fZeilen[i]) = 3);
  end;
  Result := Result or (Abs(dFrom13To31) = 3) or (Abs(dFrom11To33) = 3);
  if (Result) then
  begin
    fLastWinner := fCurrentPlayer
  end else
  if (FMoves = 9) then
  begin
    Result := True;
    fLastWinner := pNobody;
  end;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  fCurrentPlayer := pX;
  fLastWinner := pNobody;
  NewGame;
end;

procedure TForm1.NewGame;
begin
  ResetPlayground;
  NextPlayer;
end;

procedure TForm1.DisablePlayground;
var
  i: Integer;
begin
  for i := 0 to Self.ControlCount - 1 do
  begin
    if (Self.Controls[i] is TButton) and
       (TButton(Self.Controls[i]).Tag > 0) then
    begin
      TButton(Self.Controls[i]).Enabled := false;
    end;
  end;
end;

procedure TForm1.ResetPlayground;
var
  i: Integer;
begin
  FMoves := 0;
  for i := 0 to Self.ControlCount - 1 do
  begin
    if (Self.Controls[i] is TButton) and
       (TButton(Self.Controls[i]).Tag > 0) then
    begin
      TButton(Self.Controls[i]).Caption := EmptyStr;
      TButton(Self.Controls[i]).Enabled := true;
    end;
  end;

  for i := Low(fSpalten) to High(fSpalten) do
    fSpalten[i] := 0;
  for i := Low(fZeilen) to High(fZeilen) do
    fZeilen[i] := 0;
  dFrom13To31 := 0;
  dFrom11To33 := 0;
end;

procedure TForm1.NextPlayer;
begin
  if (fLastWinner = pNobody) then
  begin
    fCurrentPlayer := TPlayer(Ord(fCurrentPlayer) * -1)
  end else
  begin
    fCurrentPlayer := TPlayer(Ord(fLastWinner) * -1);
    fLastWinner := pNobody;
  end;
  UpdateStatus;
end;

procedure TForm1.UpdateStatus;
begin
  case fCurrentPlayer of
    pX: LabelCurrentPlayer.Caption := 'current player: X';
    pO: LabelCurrentPlayer.Caption := 'current player: O';
  end;
end;

procedure TForm1.ButtonNewGameClick(Sender: TObject);
begin
  NewGame;
end;

end.
Delphi-Quellcode:
object Form1: TForm1
  Left = 414
  Top = 203
  BorderStyle = bsToolWindow
  Caption = 'TicTacToe'
  ClientHeight = 264
  ClientWidth = 201
  Color = clBtnFace
  Font.Charset = DEFAULT_CHARSET
  Font.Color = clWindowText
  Font.Height = -11
  Font.Name = 'MS Sans Serif'
  Font.Style = []
  OldCreateOrder = False
  OnCreate = FormCreate
  PixelsPerInch = 96
  TextHeight = 13
  object LabelCurrentPlayer: TLabel
    Left = 8
    Top = 8
    Width = 67
    Height = 13
    Caption = 'current player:'
  end
  object Button11: TButton
    Tag = 11
    Left = 8
    Top = 32
    Width = 57
    Height = 57
    TabOrder = 0
    OnClick = ButtonClick
  end
  object Button12: TButton
    Tag = 12
    Left = 72
    Top = 32
    Width = 57
    Height = 57
    TabOrder = 1
    OnClick = ButtonClick
  end
  object Button13: TButton
    Tag = 13
    Left = 136
    Top = 32
    Width = 57
    Height = 57
    TabOrder = 2
    OnClick = ButtonClick
  end
  object Button21: TButton
    Tag = 21
    Left = 8
    Top = 96
    Width = 57
    Height = 57
    TabOrder = 3
    OnClick = ButtonClick
  end
  object Button22: TButton
    Tag = 22
    Left = 72
    Top = 96
    Width = 57
    Height = 57
    TabOrder = 4
    OnClick = ButtonClick
  end
  object Button23: TButton
    Tag = 23
    Left = 136
    Top = 96
    Width = 57
    Height = 57
    TabOrder = 5
    OnClick = ButtonClick
  end
  object Button31: TButton
    Tag = 31
    Left = 8
    Top = 160
    Width = 57
    Height = 57
    TabOrder = 6
    OnClick = ButtonClick
  end
  object Button32: TButton
    Tag = 32
    Left = 72
    Top = 160
    Width = 57
    Height = 57
    TabOrder = 7
    OnClick = ButtonClick
  end
  object Button33: TButton
    Tag = 33
    Left = 136
    Top = 160
    Width = 57
    Height = 57
    TabOrder = 8
    OnClick = ButtonClick
  end
  object ButtonNewGame: TButton
    Left = 8
    Top = 224
    Width = 185
    Height = 25
    Caption = 'neues Spiel'
    TabOrder = 9
    OnClick = ButtonNewGameClick
  end
end

Geändert von madas (12. Apr 2017 um 14:28 Uhr)
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


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 21:20 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-2025 by Thomas Breitkreuz