Einzelnen Beitrag anzeigen

madas

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

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