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 2 von 3     12 3      
ShadowDeath

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

AW: TicTacToe - Frage zum Programmablauf

  Alt 12. Apr 2017, 12: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
 
#12

AW: TicTacToe - Frage zum Programmablauf

  Alt 12. Apr 2017, 12: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
 
#13

AW: TicTacToe - Frage zum Programmablauf

  Alt 12. Apr 2017, 13: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 13:19 Uhr) Grund: Ok - verstanden, nix Debugger - irgendwie überlesen :-(
  Mit Zitat antworten Zitat
a.def
(Gast)

n/a Beiträge
 
#14

AW: TicTacToe - Frage zum Programmablauf

  Alt 12. Apr 2017, 13: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
445 Beiträge
 
Delphi 10.3 Rio
 
#15

AW: TicTacToe - Frage zum Programmablauf

  Alt 12. Apr 2017, 13: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
 
#16

AW: TicTacToe - Frage zum Programmablauf

  Alt 12. Apr 2017, 13: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
 
#17

AW: TicTacToe - Frage zum Programmablauf

  Alt 12. Apr 2017, 13: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 15:28 Uhr)
  Mit Zitat antworten Zitat
ShadowDeath

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

AW: TicTacToe - Frage zum Programmablauf

  Alt 12. Apr 2017, 14:11
Hab mal die Ausgabe als Screen hochgeladen. Da ist deutlich ersichtlich, dass die Positionen nicht stimmen (wie bereits von euch gesagt). Ich möchte aber nicht einfach copy & pasten, also wäre es super, wenn jemand die Zeit/Lust hätte mir das mit den Tags so zu erklären, dass ich es verstehe & selbst einbauen kann.
Miniaturansicht angehängter Grafiken
tictactoe.png  
  Mit Zitat antworten Zitat
Benutzerbild von DeddyH
DeddyH

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

AW: TicTacToe - Frage zum Programmablauf

  Alt 12. Apr 2017, 14:46
Wenn Du Dein Spielfeld als Array[0..2, 0..2] of TSpeedButton deklarierst und entsprechend befüllst, kannst Du doch direkt auf den jeweiligen SpeedButton zugreifen und dort in dessen Tag-Eigenschaft schreiben bzw. daraus lesen. Das ist zwar das genaue Gegenteil von Trennung von Logik und Darstellung, macht die Sache aber viel einfacher IMO.
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
nahpets
(Gast)

n/a Beiträge
 
#20

AW: TicTacToe - Frage zum Programmablauf

  Alt 12. Apr 2017, 15:17
Hab mal die Ausgabe als Screen hochgeladen. Da ist deutlich ersichtlich, dass die Positionen nicht stimmen (wie bereits von euch gesagt). Ich möchte aber nicht einfach copy & pasten, also wäre es super, wenn jemand die Zeit/Lust hätte mir das mit den Tags so zu erklären, dass ich es verstehe & selbst einbauen kann.
Bitte gib' zuerst den Speedbuttons aussagefähige Namen:

Beispiel:

Der Speedbutton unten links bekommt den Namen btnX1Y1.
Der unten in der Mitte btnX2Y1 und unten rechts der btnX3Y1.

Als Tag gibst Du jeweils die beiden Ziffern aus dem Namen ein, also unten links Tag = 11, unten in der Mitte Tag = 21 und unten rechts Tag = 31.

Analog dann auch die übrigen Speedbuttons.

Den Speedbutton 10 benennst Du z. B. btnNeuesSpiel.

Danach übernimmst Du den Vorschlag von himitsu aus Post #4.

Wenn ich jetzt nicht zusehr um die Ecke gedacht habe, könnte es dann schon funktionieren.

Die Eigenschaft Tag ist eigentlich nichts weiter als ein Integer, der grundsätzlich erstmal für nix benötigt wird.
Die Eigenschaft lässt sich aber gut für die Zuordnung von nummerischen Werten, die im Programmablauf benötigt werden, "missbrauchen". Anstatt abzufragen: "Wurde SpeedbuttonX gedrückt" (oder gar den gedrückten Button erst in einer Liste (Self.Controls) zu suchen), kann man hier halt den nummerischen Wert abfragen. Und wenn man den beim Programmdesign so wählt, dass er sich in die Programmlogik einfügt, kann man sich damit sehr viel Arbeit ersparen.
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 2 von 3     12 3      


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:58 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