AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Programmieren allgemein [oop] funktion einer oberklasse von einer unterklasse aus
Thema durchsuchen
Ansicht
Themen-Optionen

[oop] funktion einer oberklasse von einer unterklasse aus

Ein Thema von neomic · begonnen am 9. Aug 2007 · letzter Beitrag vom 10. Aug 2007
Antwort Antwort
Seite 1 von 2  1 2      
neomic
(Gast)

n/a Beiträge
 
#1

[oop] funktion einer oberklasse von einer unterklasse aus

  Alt 9. Aug 2007, 23:27
guten abend,

zerbreche mir hier schon seid gut 2 stunden den kopf wie ich mein problem lösen kann...

ich programmiere gerade das berühmte spiel memory nach. dabei ist folgendes problem entstanden:

die hierarchi der klassen sieht ungefähr so aus (C für class und F für form):

CMemory -> CManager -> CCardField -> CCard
-> FField

zür erklärung:

- memory ist das hauptprogramm das die regeln des spiels steuert
- manager verwaltet cardfield (alles wo karten angezeigt werden können)
- cardfield verwaltet die cards

die cards bestehen bei mir aus TImages mit OnClick Ereigniss
dieses muss bei memory eine funktion ausführen (die eine variable "clicks" erhöht)

problem dabei: geht nicht weil ich in cards nicht memory definieren kann wegen überkreuzung der units durch use

use in implementation kann ich auch net benutzen weil ich die typdeklarationen brauche :'(


hat da jemand vll eine idee oder vorschläge für ein neues konzept?

ich wäre da sehr dankbar!


greetz neomic
  Mit Zitat antworten Zitat
Dax
(Gast)

n/a Beiträge
 
#2

Re: [oop] funktion einer oberklasse von einer unterklasse au

  Alt 9. Aug 2007, 23:30
Pack alles in eine Unit. Was besseres wirst du nicht tun können.
  Mit Zitat antworten Zitat
neomic
(Gast)

n/a Beiträge
 
#3

Re: [oop] funktion einer oberklasse von einer unterklasse au

  Alt 9. Aug 2007, 23:36
die idee hatte ich auch schon...


type TCCard=class(TObject)
private
hImage:TImage;
zID:Integer;
kMemory:TCMemory;
public
constructor Create(pWinControl:TWinControl;pMemory:TCMemory;pI D,pXPos,pYPos:Integer);
procedure Click(Sender:TObject);
procedure Draw(pBitmap:TBitmap);
function GetID:Integer;
end;

type TCManager=class(TObject)
private
zCards:Integer;
hField:TField;
hCard:TCCard;
public
constructor Create(pWinControl:TWinControl;pCards:Integer);
end;

type TCMemory=class(TObject)
private
hBitmap:array[0..1] of TBitmap;
hManager:TCManager;
zClicked:Integer;
public
constructor Create(pForm:TForm;pPlayers,pCards,pKinds:Integer) ;
procedure Click(pID:Integer);
end;


dann sag mir mal bitte wie ich das anordnen soll...
  Mit Zitat antworten Zitat
Dax
(Gast)

n/a Beiträge
 
#4

Re: [oop] funktion einer oberklasse von einer unterklasse au

  Alt 9. Aug 2007, 23:43
Delphi-Quellcode:
type
  TCCard=class;
  
  TCManager=class;
  
  TCMemory=class(TObject)
  private
    hBitmap:array[0..1] of TBitmap;
    hManager:TCManager;
    zClicked:Integer;
  public
    constructor Create(pForm:TForm;pPlayers,pCards,pKinds:Integer);
    procedure Click(pID:Integer);
  end;

  TCManager=class(TObject)
  private
    zCards:Integer;
    hField:TField;
    hCard:TCCard;
  public
    constructor Create(pWinControl:TWinControl;pCards:Integer);
  end;

  TCCard=class(TObject)
  private
    hImage:TImage;
    zID:Integer;
    kMemory:TCMemory;
  public
    constructor Create(pWinControl:TWinControl;pMemory:TCMemory;pID,pXPos,pYPos:Integer);
    procedure Click(Sender:TObject);
    procedure Draw(pBitmap:TBitmap);
    function GetID:Integer;
  end;
  Mit Zitat antworten Zitat
Benutzerbild von Die Muhkuh
Die Muhkuh

Registriert seit: 21. Aug 2003
7.332 Beiträge
 
Delphi 2009 Professional
 
#5

Re: [oop] funktion einer oberklasse von einer unterklasse au

  Alt 9. Aug 2007, 23:44
Delphi-Quellcode:
//Stichwort: Forward Decs:

type
  TCCard = class;
  TCManager = class;
  TCMemory = class;

TCCard=class(TObject)
private
hImage:TImage;
zID:Integer;
kMemory:TCMemory;
public
constructor Create(pWinControl:TWinControl;pMemory:TCMemory;pID,pXPos,pYPos:Integer);
procedure Click(Sender:TObject);
procedure Draw(pBitmap:TBitmap);
function GetID:Integer;
end;

TCManager=class(TObject)
private
zCards:Integer;
hField:TField;
hCard:TCCard;
public
constructor Create(pWinControl:TWinControl;pCards:Integer);
end;

TCMemory=class(TObject)
private
hBitmap:array[0..1] of TBitmap;
hManager:TCManager;
zClicked:Integer;
public
constructor Create(pForm:TForm;pPlayers,pCards,pKinds:Integer);
procedure Click(pID:Integer);
end;
  Mit Zitat antworten Zitat
neomic
(Gast)

n/a Beiträge
 
#6

Re: [oop] funktion einer oberklasse von einer unterklasse au

  Alt 9. Aug 2007, 23:49
das ist mir ehrlich gesagt neu^^

aber danke das ich wenigstens jetzt mal einen fixpunkt habe wie es auf jeden fall geht (:
  Mit Zitat antworten Zitat
Benutzerbild von idontwantaname
idontwantaname

Registriert seit: 31. Aug 2004
Ort: Traiskirchen
575 Beiträge
 
Turbo Delphi für Win32
 
#7

Re: [oop] funktion einer oberklasse von einer unterklasse au

  Alt 10. Aug 2007, 00:51
Was du noch machen könntest, was jedoch relativ umständlich aber sauberer/korrekter wäre, ist ein Event auszulösen CCard und dieses durch alle klassen bis an CMemory zu leiten.
Oliver Hanappi
Besucht meine neue Homepage: http://oli.hux.de
  Mit Zitat antworten Zitat
Hansa

Registriert seit: 9. Jun 2002
Ort: Saarland
7.554 Beiträge
 
Delphi 8 Professional
 
#8

Re: [oop] funktion einer oberklasse von einer unterklasse au

  Alt 10. Aug 2007, 01:52
Zitat von neomic:
..oder vorschläge für ein neues konzept?
Zwischen den Zeilen liest man da Zweifel am eigenen Konzept. Und die sind auch durchaus berechtigt. OOP-mäßig fängt man doch nicht bei Null an. TObject ist so gut wie nichts. Sinnvollerweise sollte man vorhandene Methoden verwenden oder erweitern. Und zwar aus vorhandenem heraus. Gehe doch hin und bilde das Memory-Spiel logisch 1:1 im Programm ab. Für mich ist das ein quadratisches Array. Da bietet sich ein Array [1..MaxX,1..MaxY] of TImage; an.
Gruß
Hansa
  Mit Zitat antworten Zitat
Benutzerbild von Luckie
Luckie

Registriert seit: 29. Mai 2002
37.621 Beiträge
 
Delphi 2006 Professional
 
#9

Re: [oop] funktion einer oberklasse von einer unterklasse au

  Alt 10. Aug 2007, 02:39
Zitat von Hansa:
Zwischen den Zeilen liest man da Zweifel am eigenen Konzept. Und die sind auch durchaus berechtigt. OOP-mäßig fängt man doch nicht bei Null an. TObject ist so gut wie nichts. Sinnvollerweise sollte man vorhandene Methoden verwenden oder erweitern. Und zwar aus vorhandenem heraus. Gehe doch hin und bilde das Memory-Spiel logisch 1:1 im Programm ab. Für mich ist das ein quadratisches Array. Da bietet sich ein Array [1..MaxX,1..MaxY] of TImage; an.
Und mit dem Array hätten wir dann den OOP Pfad wieder verlassen.

Es war schon richtig sich eine Klasse TCard zu erstellen und diese in einem Container TField zu verwalten. Eine Kart kennt ihren Zustand und ihren Wert, ob umgedreht oder nicht. TField kennt jede Position jeder Karte und deren Wert, den sie sich von dem Objekt TCard geben lässt. Ich drehe ein Karte um und TField fragt TCard: "Was hast du für einen Wert?" Dann wird die zweite Karte umgedreht und TField fragt auch diese Karte: "Was hast du für einen Wert?" TMemory fragt dann TField: "Sind die Karten gleich?" In Abhängigkeit der Antworte kann dann TMemory entscheiden was passieren muss. Entweder sagt es TField: "Dreh die Karten wieder um." (Sie waren nicht gleich.) Und TField sagt den Karten, dass sie wieder ihren Zuständ ändern sollen und zwar in den umgedrehten. Oder TMemory sagt TField: "Nimm die Karten vom Spielfeld. (Sie waren gleich und TField löscht die betreffenden Karten-Objekte aus der Liste und stellt deren Plätze entsprechend dar.)

Manchmal fällt es leichter, wenn man sich so einen Ablauf mit handelnden Peronen vorstellt. Hier haben wir einen Spielleiter, TMemory, der die Regeln kennt und entscheidet, was passieren muss. Dann haben wir einen Spielfeldverwalter, TField, der die Anweisungen an die Akteure, TCard, weitergibt. Man überlegt, welche Personen brauche ich und wie arbeiten diese Personen zusammen, welche Informationen benötigen sie (das sind dann die Attribute der Klasse) und welche Informationen übermitteln sie (das sind dann die Methoden). Hinzu kommen Ereignisse, die entsprechende Reaktionen bei den handelnden Personen auslösen.

Beispiel:
Wird eine Karte umgedreht, wird das Ereignis OnFlip ausgelöst und TField zählt mit. So bald TField festgestellt hat, dass zwei mal dieses Ereignis eingetreten ist, fragt es die Karten, welche Werte sie haben und löst dann das Ereignis OnEndTurn aus. Im Ereignis OnEndTurn teilt es dem Spielleiter TMemory mit, ob die Karten gleich sind oder nicht. TMemory weist dann TField an, was mit den Karten passieren soll.

Hm, eigentlich habe ich gerade dein Programm geschrieben. Das jetzt umzusetzen, ist eigentlich nur noch reine Tipparbeit.

@Hansa: Und die Klassen TMemory und TField würde ich von TObject ableiten. Die Klasse TCard dann je nach dem entweder von TImage oder sonst einer grafischen Komponente.
Michael
Ein Teil meines Codes würde euch verunsichern.
  Mit Zitat antworten Zitat
Benutzerbild von Luckie
Luckie

Registriert seit: 29. Mai 2002
37.621 Beiträge
 
Delphi 2006 Professional
 
#10

Re: [oop] funktion einer oberklasse von einer unterklasse au

  Alt 10. Aug 2007, 05:02
Ich konnte nicht schlafen.

Im Anhang mein Memory. Eigentlich ist es nur eine Memory-Klasse mit einer Demo-Anwendung. Man müsste noch an zwei Punkten etwas verbesser: Die Anordnung der Felder, die sind in einer Reihe im Moment und an der Zuweisung der Werte, obwohl das ist egal, nur eben die Beschriftung der Felder sollte man noch mal etwas verschönern. Ansonsten kommt man mit 200 Codezeilen hin inklusive der Leerzeilen.

Als Spielleiter habe ich die Form genommen.

@Hansa: Ein zwei dimensionales Array ist natürlich Blödsinn. Wo die Karten liegen auf der Oberfläche kann der Klasse egal sein.

Für die Download-Faulen hier die Code:
Delphi-Quellcode:
(******************************************************************************
*                                                                            *
*  Project: Memory, Klassen für das Spiel Memory                            *
*  File  : Memory, Klassen TMemoryField, TCard                              *
*                                                                            *
*  Copyright (c) Michael Puff  [url]http://www.michael-puff.de[/url]                    *
*                                                                            *
******************************************************************************)


unit Memory;

interface

uses
  SysUtils,
  Controls,
  ExtCtrls,
  Graphics,
  Classes;

type
  TCardStatus = (csBlind, csRevealed);

type
  TCard = class;

  TOnFlip = procedure(Card: TCard) of object;
  TCard = class(TPanel)
  private
    FValue: Integer;
    FStatus: TCardStatus;
    FOnFlip: TOnFlip;
    function GetValue: Integer;
    procedure SetValue(Value: Integer);
    function GetStatus: TCardStatus;
    procedure SetStatus(Value: TCardStatus);
    procedure Click(Sender: TObject); reintroduce;
    property OnFlip: TOnFlip read FOnFlip write FOnFlip;
  public
    constructor Create(Owner: TComponent); override;
    property Value: Integer read GetValue write SetValue;
    property Status: TCardStatus read GetStatus write SetStatus;
  end;

  TOnEndTurn = procedure(FirstCard, SecondCard: TCard) of object;
  TOnGameOver = procedure of object;
  TMemoryField = class(TObject)
  private
    FCards: TList;
    FCountCards: Integer;
    FParent: TWinControl;
    FFirstCard: TCard;
    FSecondCard: TCard;
    FCountFlips: Integer;
    FOnEndTurn: TOnEndTurn;
    FOnGameOver: TOnGameOver;
    procedure Add(Card: TCard);
    procedure IniTMemoryField;
    procedure OnFlip(Card: TCard);
  public
    constructor Create(CountCards: Integer; Parent: TWinControl);
    destructor Destroy; override;
    property OnEndTurn: TOnEndTurn read FOnEndTurn write FOnEndTurn;
    property OnGameOver: TOnGameOver read FOnGameOver write FOnGameOver;
    procedure HideCard(Card: TCard);
  end;

implementation

constructor TCard.Create(Owner: TComponent);
begin
  inherited Create(Owner);
  Self.OnClick := Click;
end;

function TCard.GetValue: Integer;
begin
  Result := FValue;
end;

procedure TCard.SetValue(Value: Integer);
begin
  FValue := Value;
end;

function TCard.GetStatus: TCardStatus;
begin
  Result := FStatus;
end;

procedure TCard.SetStatus(Value: TCardStatus);
begin
  FStatus := Value;
  if FStatus = csBlind then
  begin
    Self.Font.Color := clBlack;
    Self.Enabled := True;
  end
  else
  begin
    Self.Font.Color := clBlue;
    Self.Enabled := False;
  end;
end;

procedure TCard.Click(Sender: TObject);
begin
  Status := csRevealed;
  if Assigned(OnFlip) then
    OnFlip(Self);
end;

constructor TMemoryField.Create(CountCards: Integer; Parent: TWinControl);
begin
  inherited Create;
  FCards := TList.Create;
  FCountCards := CountCards;
  FParent := Parent;
  FCountFlips := 0;
  IniTMemoryField;
end;

destructor TMemoryField.Destroy;
var
  i : Integer;
begin
  if FCards.Count > 0 then
  begin
    for i := FCards.Count - 1 downto 0 do
    begin
      TObject(FCards.Items[i]).Free;
    end;
  end;
  FCards.Free;
  inherited;
end;

procedure TMemoryField.IniTMemoryField;
var
  i : Integer;
  Card : TCard;
begin
  for i := 0 to FCountCards - 1 do
  begin
    Card := TCard.Create(nil);
    Card.Parent := FParent;
    Card.Font.Style := [fsBold];
    Card.Font.Size := 14;
    Card.OnFlip := OnFlip;
    Card.Width := 50;
    Card.Left := (Card.Width * i) + 50;
    if not Odd(i) then
      Card.Caption := IntToStr(i)
    else
      Card.Caption := IntToStr(i - 1);
    Card.Value := StrToInt(Card.Caption);
    Add(Card);
  end;
end;

procedure TMemoryField.Add(Card: TCard);
begin
  FCards.Add(Card);
end;

procedure TMemoryField.OnFlip(Card: TCard);
begin
  Inc(FCountFlips);
  if FCountFlips = 1 then
    FFirstCard := Card
  else
    FSecondCard := Card;
  if FCountFlips = 2 then
  begin
    if Assigned(OnEndTurn) then
      OnEndTurn(FFirstCard, FSecondCard);
    FCountFlips := 0;
  end;
end;

procedure TMemoryField.HideCard(Card: TCard);
begin
  Card.Visible := False;
  Dec(FCountCards);
  if FCountCards = 0 then
  begin
    if Assigned(OnGameOver) then
      OnGameOver;
  end;
end;

end.

Delphi-Quellcode:
procedure TForm1.OnEndTurn(FirstCard, SecondCard: TCard);
begin
  if FirstCard.Value = SecondCard.Value then
  begin
    Field.HideCard(FirstCard);
    Field.HideCard(SecondCard);
  end
  else
  begin
    FirstCard.Status := csBlind;
    SecondCard.Status := csBlind;
  end;
end;

procedure TForm1.OnGameOver;
begin
  ShowMessage('Game over');
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  if Assigned(Field) then
    FreeAndNil(Field);
  Field := TMemoryField.Create(4, Form1);
  Field.OnEndTurn := OnEndTurn;
  Field.OnGameOver := OnGameOver;
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  Field.Free;
end;
@neomic : Ich hoffe, ich habe jetzt keine Hausaufgaben für dich gemacht. Wenn doch, dann solltest du möglichst verstehen, was ich gemacht habe, sonst könnte es etwas peinlich werden, wenn der Lehrer Fragen zum Code stellt.
Angehängte Dateien
Dateityp: zip memory_118.zip (198,1 KB, 26x aufgerufen)
Michael
Ein Teil meines Codes würde euch verunsichern.
  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 09:29 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