AGB  ·  Datenschutz  ·  Impressum  







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

Strafzeitenverwaltung in eigener Unit

Offene Frage von "Namenloser"
Ein Thema von torud · begonnen am 18. Jun 2010 · letzter Beitrag vom 21. Jun 2010
Antwort Antwort
torud

Registriert seit: 26. Jul 2002
Ort: Sachsen
1.198 Beiträge
 
Delphi XE5 Professional
 
#1

AW: Strafzeitenverwaltung in eigener Unit

  Alt 18. Jun 2010, 21:00
Moin Philip,

danke für deine umfangreichen Ausführungen. Ich glaube/hoffe, dass ich es nun etwas besser verstehe. Ich habe nun auch den Code so aufgesplittet, dass die eigentliche Zeitstrafe eine Klasse abgeleitet von TObject ist und Penalties eine Klasse abgeleitet von TObjectlist ist.

Der Code sollte nun um einiges besser aussehen.

Zum besseren Verständnis erlaube ich mir aber trotzdem noch ein paar Fragen. Vorher aber schon mal der Code. Ich habe ihn so kurz wie möglich gehalten.

Delphi-Quellcode:
unit unt_penalty;

interface

type
  TPenalty = class
  public
    Team : Char; //character of Team (A or B)
    TTime : String; //total time of penaltie
    CTime : String; //current time of penalty
    Direction : byte; //direction of running time 0:asc;1:desc
    constructor Create;
  end;

implementation

constructor TPenalty.Create;
begin
  inherited;
end;

end.
Delphi-Quellcode:
unit unt_penalties;

interface

uses Contnrs, unt_Penalty;

type
  TPenalties = class(TObjectList)
  public
    constructor Create;
    function AddPenalty(Penalty : TPenalty; PenaltyList : TObjectList): TObjectList; //add a penalty
    function DeletePenalty(Penalty : TPenalty; PenaltyList : TObjectList): TObjectList; //delete a penalty
    function EditPenalty(Penalty : TPenalty; PenaltyList : TObjectList): TObjectList; //edit a penalty
  end;

implementation

uses Classes;

constructor TPenalties.Create;
begin
  inherited;
end;

function TPenalties.AddPenalty(Penalty : TPenalty; PenaltyList : TObjectList): TObjectList;
begin
  //add a penalty
  with PenaltyList do
    begin
      Add(Penalty);
    end;
end;

function TPenalties.DeletePenalty(Penalty : TPenalty; PenaltyList : TObjectList): TObjectList;
begin
  //delete a penalty
  with PenaltyList do
    begin
      Delete(IndexOf(Penalty));
    end;
end;

function TPenalties.EditPenalty(Penalty : TPenalty; PenaltyList : TObjectList): TObjectList;
begin
  //edit a penalty
end;

end.
Und so habe ich es testhalber im MainForm mal eingebunden:

Delphi-Quellcode:
procedure TForm1.FormCreate(Sender: TObject);
var
  MyPenalty : TPenalty;
  MyPenalties : TPenalties;
begin
  //erzeugen des penalty und zuweisen der daten
  MyPenalty := TPenalty.Create;
  MyPenalty.Team := 'A';
  MyPenalty.TTime:= '00:02:00';
  MyPenalty.CTime:= '00:02:00';
  MyPenalty.Direction:= 0;
  //erzeugen der penaltyliste und hinzufügen des penalty
  myPenalties := TPenalties.Create;
  mypenalties.AddPenalty(MyPenalty, MyPenalties);
end;
Es lässt sich kompilieren, aber ich habe natürlich noch das Problem, dass ich nicht weiss, wie ich dann an die einzelnen Penalty-Einträge in der Penaltyliste komme, wenn ich diese z.B.

Löschen, Editieren oder wegen laufenden Uhr updaten möchte...

Die Daten (die einzelnen Zeitstrafen) muss ich natürlich auch im Programm visualiseren, d.h. ich muss natürlich vorher die Daten nach Teams und Höhe der laufenden Uhr sortieren und dann intern (später auch extern) anzeigen.

Hast Du hierfür noch einen Tipp?
Habe ich sonst noch was falsch gemacht?
Danke
Tom
  Mit Zitat antworten Zitat
Benutzerbild von jfheins
jfheins

Registriert seit: 10. Jun 2004
Ort: Garching (TUM)
4.579 Beiträge
 
#2

AW: Strafzeitenverwaltung in eigener Unit

  Alt 18. Jun 2010, 21:12
1. Empfehlung: Du solltest TPenalty einen Kontruktor spendieren, dem man alle Daten übergeben kann.
2. Fehler: function AddPenalty BITTE keinen 2. Parameter. Das ist sinnlos, dafür ist doch gerade das Objekt da.
3. Direction : byte; //direction of running time 0:asc;1:desc ???? Eine Penalty läuft doch immer "ab" oder nicht?
4. Datenhaltung. Strings würde ich hier nicht einsetzen. Viel besser wäre ein Zeitpunkt, zu dem die Strafzteit abläuft. Ich weis jetzt nicht, wie du die Spielzeit intern mitnimmt, aber dementsprechend wäre TTime oder integer angebracht. Daten und Darstellung bitte trennen.

das wäre es erstmal von meiner Seite
  Mit Zitat antworten Zitat
torud

Registriert seit: 26. Jul 2002
Ort: Sachsen
1.198 Beiträge
 
Delphi XE5 Professional
 
#3

AW: Strafzeitenverwaltung in eigener Unit

  Alt 18. Jun 2010, 21:37
Hallo,

also ich habe die Penalty etwas angepasst.

Delphi-Quellcode:
unit unt_penalty;

interface

uses Classes;

type
  TPenalty = class
  public
    Team : Char; //character of Team (A or B)
    TTime : String; //total time of penaltie
    CTime : String; //current time of penalty
    Direction : byte; //direction of running time 0:asc;1:desc
    constructor Create(ATeam:Char; ATTime, ACTime : String; ADirection : byte); overload;
    constructor Create; overload;
  end;

implementation

constructor TPenalty.Create;
begin
  inherited;
end;

constructor TPenalty.Create(ATeam:Char; ATTime, ACTime : String; ADirection : byte);
begin
  inherited Create;
  Team := ATeam;
  TTime := ATTime;
  CTime := ACTime;
  Direction := ADirection;
end;

end.
Das Create ist nun doppelt drin. Vielleicht kann das eine ja nun auch ganz raus!?

Zu Deinen Punkten Julius:
1. erledigt
2. ich bin echt ´n Blinder.
3. Wie sicher bist Du Dir da? Ich habe heute einiges an Zeit verbracht dies auf Offiziellen Seiten nachzulesen. Fakt ist. Die reine Spielzeit kann sowol aufsteigen, als auch absteigend angezeigt werden. Kommt auf die Liga an. Insofern, dachte ich mir, dass es günstig sein könnte diese Eigenschaft zu vergeben...
4. Ja. Das ist aktuell meinem internen Zeitverfahren geschuldet und der Frage, an welcher Stelle ich denn dann nun die Zeiten (aktuell Spielzeit und jede einzelne laufende Strafzeit) intern und später dann auch extern aktualisieren lassen soll. Aktuell läuft auf dem Hauptform einfach nur ein Timer, der die Sekunden und Minuten hoch- oder runterzählt.

Verrückt ist im übrigen auch, dass folgendes nach dem Zuweisen der ersten Testdaten nicht möglich ist:
Delphi-Quellcode:
  //erzeugen des penalty und zuweisen der daten
  MyPenalty := TPenalty.Create;
  MyPenalty.Team := 'A';
  MyPenalty.TTime:= '00:02:00';
  MyPenalty.CTime:= '00:02:00';
  MyPenalty.Direction:= 0;
  //erzeugen der penaltyliste und hinzufügen des penalty
  myPenalties := TPenalties.Create;
  mypenalties.AddPenalty(MyPenalty);
  //erneutes zuweisen des penalty aus der liste, um zugriff zu prüfen
  MyPenalty := mypenalties[0];
  ShowMessage(MyPenalty.Team);
Inkompatible Typen TPenalty und TObject (ein as TObject half auch nicht...)
Danke
Tom
  Mit Zitat antworten Zitat
Namenloser

Registriert seit: 7. Jun 2006
Ort: Karlsruhe
3.724 Beiträge
 
FreePascal / Lazarus
 
#4

AW: Strafzeitenverwaltung in eigener Unit

  Alt 18. Jun 2010, 21:56
Das liegt daran, dass die Eigenschaft Items deiner TPenalties-Klasse (worauf du mit dem []-Operator implizit zugreifst) von TObjectList geerbt ist. TObjectList wurde so konzipiert, dass es Objekte aller Arten speichern kann, deshalb wurde bei der Deklaration der "Urahn" aller Klassen unter Delphi, TObject, gewählt. Da du aber wie gesagt jedes erdenkliche Objekt in dieser Liste speichern kannst, beschwert sich Delphi: Denn es könnte ja etwas völlig anderes als eine TPenalty-Instanz dort gespeichert sein, und das gäbe dann einen Fehler.

Du hast zwei Möglichkeiten: Entweder du machst einen Typecast auf TPenalty, oder du überschreibst gleich in TPenalties die Items-Property. Das geht etwa so:

Delphi-Quellcode:
TPenalties = class(TObjectList)
private
  function GetItem(Index: integer): TPenalty;
  procedure SetItem(Index: integer; AItem: TPenalty);
public
  // Siehe dazu die Online-Hilfe zum Stichwort Properties...
  property Items[Index: integer]: TPenalty read GetItem write SetItem; default;
end;

function TPenalties.GetItem(Index: integer): TPenalty;
begin
  // per inherited wird der gleichnamige Getter von TObjectList aufgerufen,
  // das Ergebnis wird nach TPenalty gecastet
  Result := TPenalty(inherited GetItem(Index));
end;

procedure TPenalties.SetItem(Index: integer; AItem: TPenalty);
begin
  // Hier ist kein Typecast nötig, weil TObject der "Urahn" von allen Klassen
  // und somit auch TPenalty ist, daher also alle Klassen zu den Schnittstellen von
  // TObject kompatibel sind.
  inherited SetItem(Index, AItem);
end;
Natürlich ist es sinnvoll, in dem Zug auch gleich die Methoden Add, Remove etc zu überschreiben, sodass diese ebenfalls typensicher sind, sprich als Parameter TPenalty statt TObject entgegen nehmen. So sicherst du die Klasse auch gegen Bedienfehler von außen ab, denn solange der Nutzer der Klasse es nicht gerade mit Typecasts darauf anlegt, Fehler zu provozieren, schmeißt der Compiler beim Kompilieren jedes mal einen Fehler und bricht den Kompiliervorgang ab, wenn irgendwo ein falsches Objekt zugewiesen wird.

Geändert von Namenloser (18. Jun 2010 um 21:59 Uhr)
  Mit Zitat antworten Zitat
torud

Registriert seit: 26. Jul 2002
Ort: Sachsen
1.198 Beiträge
 
Delphi XE5 Professional
 
#5

AW: Strafzeitenverwaltung in eigener Unit

  Alt 19. Jun 2010, 11:09
Hallo,

vielen Dank für die helfenden Hinweise und das Codebeispiel. Ich denke, dass ich dabei wieder was gelernt habe!

Ich würde nun gern Eure Meinung wissen, wie Ihr die laufenden Uhren verwalten/steuern würdet.
Aktuell ist die laufende Hauptzeit über einen Timer gelöst.

Schön ist sicher anders, aber ich wusste mir nicht anders zu helfen. Soll ich das Increasen/Decreasen der Strafzeitenuhren dann auch hier über den Timer machen, oder wäre das eher nicht so gut!?

Delphi-Quellcode:
//globale Deklaration
var
  original: TSystemTime;

procedure TForm1.int_clockTimer(Sender: TObject);
begin
  //check, how the clock should run
  case rad_direction.ItemIndex of
    0 : begin // clock should run asc
          original.wsecond:= original.wSecond + 1;

          if original.wSecond = 60 then begin
            original.wSecond :=0;
            original.wMinute :=original.wMinute + 1;
          end;
        end;
    1 : begin // clock should run desc
          //stop clock and end case, cause time is up
          if (original.wSecond = 0) and (original.wMinute = 0) then
            begin
              //stop timer
              int_clock.Enabled := false;
            end
          else
            begin
              if original.wSecond = 0 then begin
                original.wSecond := 59;
                original.wMinute := original.wMinute - 1;
              end
              else
                original.wsecond := original.wSecond - 1;
            end;
        end;
  end;
  //show the clock - internal
  lbl_mtime_int.Caption := Format('%.2d:%.2d', [original.wMinute,original.wSecond]);
  btn_set_data.Enabled := not(int_clock.Enabled);
end;
Danke
Tom
  Mit Zitat antworten Zitat
Benutzerbild von alcaeus
alcaeus

Registriert seit: 11. Aug 2003
Ort: München
6.537 Beiträge
 
#6

AW: Strafzeitenverwaltung in eigener Unit

  Alt 19. Jun 2010, 11:41
Hallo,

Ich würde nun gern Eure Meinung wissen, wie Ihr die laufenden Uhren verwalten/steuern würdet.
Aktuell ist die laufende Hauptzeit über einen Timer gelöst.

Schön ist sicher anders, aber ich wusste mir nicht anders zu helfen. Soll ich das Increasen/Decreasen der Strafzeitenuhren dann auch hier über den Timer machen, oder wäre das eher nicht so gut!?
Genauer gesagt musst du das sogar. Im internationalen Eishockey wird die letzte Minute inkl. Zehntelsekunden abgearbeitet - wenn jetzt jemand 52.5 Sekunden vor Schluss nen Penalty kommt darfst du diese halbe Sekunde nicht untern Tisch fallen lassen.
Ich empfehle dir hierfuer uebrigens ein Observer-Pattern. Kurz eine Erklaerung:
Du hast eine Klasse GameClock. Diese Methode kapselt einen Timer und hat eine Start/Stop-Methode. Start startet die Uhr, Stop haelt sie an. Beim Starten der Uhr schickst du dann eine Message an alle registrierten PenaltyClocks, dass diese auch starten. Beim Stop funktioniert das analog.

Bei dieser Gelegenheit noch nen Hinweis: beachte dass du nie mehr als 2 Strafzeiten laufen lassen darfst. Ein kleines Beispiel: Mannschaft A kassiert 2 Minuten. PP beginnt, Mannschaft A kassiert nochmal 2 Minuten. Jetzt laufen beide Strafzeiten und A spielt in doppelter Unterzahl. Wenn jetzt nochmal eine Strafe fuer A ausgesprochen wird, landen die 2 Minuten auf der Uhr, werden aber nicht runtergezaehlt bis nicht eine der vorherigen Strafzeiten abgelaufen sind.
Im Beispiel oben bedeutet das: dein Observer-Pattern darf nur die ersten beiden PenaltyClocks einer Mannschaft starten. Laeuft eine PenaltyClock aus, muss sie die erste nicht laufende PenaltyClock der eigenen Mannschaft starten.

So, ich hoffe das macht noch halbwegs Sinn was ich da geschrieben habe

Greetz
alcaeus
Andreas B.
Die Mutter der Dummen ist immer schwanger.
Ein Portal für Informatik-Studenten: www.infler.de
  Mit Zitat antworten Zitat
torud

Registriert seit: 26. Jul 2002
Ort: Sachsen
1.198 Beiträge
 
Delphi XE5 Professional
 
#7

AW: Strafzeitenverwaltung in eigener Unit

  Alt 19. Jun 2010, 12:43
Hallo,

Hallo, Genauer gesagt musst du das sogar.
Genau die Antwort, die ich brauchte.

Im internationalen Eishockey wird die letzte Minute inkl. Zehntelsekunden abgearbeitet - wenn jetzt jemand 52.5 Sekunden vor Schluss nen Penalty kommt darfst du diese halbe Sekunde nicht untern Tisch fallen lassen.
Ups, dass hatte ich so detailliert nicht auf dem Zettel. Vielleicht macht es hier ja auch Sinn in der Uhrenklasse die Zehntel optional zu halten. Ich müsste dann aber sozusagen aus den 1000ms im Timer eine 100 machen. Sollte ich die 1000 bis zum Erreichen der Minute lassen und dann wenn ich Minute = 0 und Sekunde > 0 ist, den Timer.Interval auf 100 stellen oder grundsätzlich immer?

Ich empfehle dir hierfuer uebrigens ein Observer-Pattern. Kurz eine Erklaerung:
Du hast eine Klasse GameClock. Diese Methode kapselt einen Timer und hat eine Start/Stop-Methode. Start startet die Uhr, Stop haelt sie an. Beim Starten der Uhr schickst du dann eine Message an alle registrierten PenaltyClocks, dass diese auch starten. Beim Stop funktioniert das analog.
Das hier verstehe ich nicht ganz. Der Timer würde dann im private der Uhrenklasse gekapselt werden. So weit ist alles klar. Start-Stop ist auch klar. Was soll aber passieren, wenn ich die Message an die PenaltyClocks (die es ja aktuell noch nicht gibt) sende? Ich dachte, dass der gekapselte Timer alle Uhren "steuert", also die Hauptuhr und die Strafzeituhren zum laufen bringt, indem ER selbst die einzelnen Uhren "zählt". Ist es also so zu verstehen, dass der gekapselte Timer nur die anderen Timer anschieben/anhalten soll???

Bei dieser Gelegenheit noch nen Hinweis: beachte dass du nie mehr als 2 Strafzeiten laufen lassen darfst. Ein kleines Beispiel: Mannschaft A kassiert 2 Minuten. PP beginnt, Mannschaft A kassiert nochmal 2 Minuten. Jetzt laufen beide Strafzeiten und A spielt in doppelter Unterzahl. Wenn jetzt nochmal eine Strafe fuer A ausgesprochen wird, landen die 2 Minuten auf der Uhr, werden aber nicht runtergezaehlt bis nicht eine der vorherigen Strafzeiten abgelaufen sind.
Jo, davon hatte ich was gehört. Mir ist noch nicht ganz klar, wie das bei den 5-10 und 20-Minuten-Strafen ist, wo ja der Ausschluss des Spielers noch hinzukommt. Bei manchen Strafen ist es wohl so, dass DER oder EIN Spieler raus muss, aber natürlich nicht die vollen 10 Minuten absitzt. Dann gibt es da noch die Regel, dass die 2 Minuten-Strafzeit sofort gelöscht wird, wenn das in Unterzahl befindliche Team ein Tor "bekommt", respektive, dass bei einer 2+2-Strafe die ersten 2 Minuten gelöscht werden und direkt die 2. Strafzeit losläuft. Ziemlich irre!

Im Beispiel oben bedeutet das: dein Observer-Pattern darf nur die ersten beiden PenaltyClocks einer Mannschaft starten. Laeuft eine PenaltyClock aus, muss sie die erste nicht laufende PenaltyClock der eigenen Mannschaft starten.
Jep! Eigentlich ist es ja dann auch so, dass die bis dahin aktuell 2. Uhr an 1. Stelle rutschen muss und die neu zu startende Uhr an 2. Stelle => Wenn die Strafzeit grösser ist als die Restzeit der ersten. Das aber nur am Rande, weil ich die Uhren ja auch irgendwann mal rausschicken muss und der Empfänger natürlich grosse Lust drauf hat die Uhr korrekt sortiert zu erhalten.

So, ich hoffe das macht noch halbwegs Sinn was ich da geschrieben habe
Jo, im Grossen und Ganzen scheinst Du nicht nur Ahnung vom Programmieren zu haben, sondern auch einiges über die Regeln im Eishockey zu wissen. Cool!

Die Uhrenklasse habe ich jetzt erstmal so aufgesetzt. Natürlich fehlen da noch die Funktionen "nach aussen hin".
Delphi-Quellcode:
unit unt_game_clock;

interface

uses ExtCtrls;

type
  TGameClock = class
  private
    GameClock : TTimer;
  public
    constructor Create;
    Procedure StartClock;
    Procedure StopClock;
  end;

implementation

constructor TGameClock.Create;
begin
  inherited;
end;

Procedure TGameClock.StartClock;
begin
  GameClock.Enabled := True;
end;

Procedure TGameClock.StopClock;
begin
  GameClock.Enabled := False;
end;

end.
Danke
Tom

Geändert von torud (19. Jun 2010 um 12:56 Uhr)
  Mit Zitat antworten Zitat
schlecki

Registriert seit: 11. Apr 2005
Ort: Darmstadt
148 Beiträge
 
Delphi XE2 Enterprise
 
#8

AW: Strafzeitenverwaltung in eigener Unit

  Alt 20. Jun 2010, 11:56
versuchs mal mit:

Delphi-Quellcode:
type
  TPenalties = class(TObjectList)
  private
    function GetItems(Idx: Integer): TPenalty;
    procedure SetItems(Idx: Integer; Value: TPenalty);
  public
    property Items[Idx: Integer]: TPenalty read GetItems write SetItems;
  end;

...

function TPenalties.GetItems(Idx: Integer): TPenalty;
begin
  Result := (inherited GetItems(Idx)) as TPenalty;
end;

procedure TPenalties.SetItems(Idx: Integer; Value: TPenalty);
begin
  inherited SetItems(Idx, Value);
end;
ungetestet, sollte aber so gehen...


Edit: hm, irgendwie hab ich die letzten Beiträge nicht gesehen... sorry...
  Mit Zitat antworten Zitat
Antwort Antwort


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 04:19 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