Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Zählsystem für Tennis entwickeln (https://www.delphipraxis.net/100047-zaehlsystem-fuer-tennis-entwickeln.html)

torud 21. Sep 2007 13:36


Zählsystem für Tennis entwickeln
 
Hallo Wissende,

da ich derzeit ein manuelle Backup für einen Tennis-Counter erstelle, würde vorher gern wissen, wie Ihr an die Sache rangehen würdet. Also zum einen würde mich dabei dabei interessieren, wie man so eine Routine logisch aufbaut.

Für die jenigen unter Euch hier mal die Regeln:

Dabei wäre folgendes zu wissen. Beim Tennis gibt es Punkte, Spiele und Sätze.

Die Punkte gehen von:
0
15
30
40
und wenn es 40 beide steht, bekommt der nächste Punktgewinner einen sogenannten VOrteil = A

Macht er danach wieder einen Punkt hat er das Spiel gewonnen.

Spielpunkte gibt es, wenn ein Spieler in einem Spiel als erster einen Punkt nach dem Erreichen der 40 gemacht hat, wenn es keinen Einstand gab (40 40).

Wer als erster 6 Spiele gewonnen hat, hat den jeweiligen Satz gewonnen. Dies gilt aber auch nur dann, wenn es einen Mindestabstand von 2 Spielpunkten gibt. Also mit 6-5 gewinnt man keinen Satz. 6-1 bis 6-4 ist korrekt. steht es aber z.b. 5-5 und anschliessend 6-5, gehts weiter. Der Satz würde mit 7-5 enden. Steht es 6-6 ginge es in den sogenannten Tiebreak.

Dort fängt das Zählen dann bei 0-0 an und die Punkte gehen hier in Einerschritten voran, bis einer zuerst 7 Punkte hat. Er gewinnt aber den Tiebreak auch nur dann, wenn es wieder mind. 2 Punkte Abstand gibt. Also 7-6 würde nicht gehen. 8-6 wäre der Regel entsprechend. Für den gewonnenen Tiebrakt gibts dann einen Spielpunkt. Damit würde aus dem 6-6 ein 7-6 werden, wobei man sich auch merken muss, wie der Tiebreak ausgegangen ist, da dies in der Regel angezeigt wird.

Bei den Sätzen ist es so, dass es Best of 3 oder Best of 5 gibt. Wer also als erster 2 oder 3 Sätze gewonnen hat, hat das Match gewonnen.

Nun frage ich mich, wie ich dies elegant und übersichtlich programmieren kann, ohne dafür 1000 Zeilen Code schreiben zu müssen und alles mit if...then...else zu erledigen. ich würde mir also eine Klasse dafür schreiben, die das übernimmt. Wer hat eine Idee, wie ich das Zählen erledigen kann?

Ein weiteres Problem, welches sich mir stellt ist, dass ich auch nachträglich in das Zählen einsteigen können muss, da das manuelle Zählen nur ein Backup ist. Normalerweise kommen die Punkte über ein externes System per UDP. Fällt dies aus, müsste man manuell weiterzählen können. Wenn alles reinkommt, wir eigentlich immer alles sofort in die Controls übergeben. Vielleicht sollte man aber lieber alles in Variablen übergeben!?

Ich wäre für Anregungen und Ideen zur Umsetzung dankbar.

cruiser 21. Sep 2007 16:46

Re: Zählsystem für Tennis entwickeln
 
für die Punkte würde ich eine Enumeration nehmen..

Delphi-Quellcode:
  type TPoints = (tp0, tp15, tp30, tp40, tp40A);
afaik müssten die sich mit Inc() und Dec() wie jeder ordinale Typ behandeln lassen.

Die Punkte würde ich innerhalb eines Spiels für beide Seiten verwalten.. am besten in einer Klasse mit eigener Steuerung.

Die Spiele dann wiederum in einem Satz, wobei dort dann auch das mit dem Tiebreak einfliessen kann.

Die Sätze schliesslich in einem Match.

Macht also ein Spieler einen "Treffer", gibt man die Info an das Match, das gibt es an den akt. Satz weiter und von da in das akt. Spiel wo dann entschieden wird ob, bzw. wer einen Punkt bekommt. Wenn das Spiel sich als "gewonnen erklärt", muss dann der Satz entscheiden, wie es weiter geht, das selbe bei gewonnenem Satz in Richtung Match.

Das ganze in Code fassen ist mir aber ein bisschen zu viel auf die Schnelle ;)

torud 21. Sep 2007 17:06

Re: Zählsystem für Tennis entwickeln
 
Danke fuer die nicht erwartet doch recht ausfuehrliche Antwort. Das sollte mir scon weiterhelfen. Koennte sein, dass ich nochmal wegen des Inc(TPointsA) nachfragen muss, da ich sowas noch nicht gemacht habe.

Ich habe auch nicht erwartet, hier eine sofortige Komplettloesung zu erhalten. Ich melde mich dann einfach wieder, wenn ich die ersten Schritte getan habe. So wie es verstanden habe, sollte es reichen, wenn die Klasse einfach nur erfahrt, ob es einen neuen Pluspunkt oder auch Minuspunkt(wenn man sich verzaehlt hat) fuer Spieler A oder B gibt. Der Rest laeuft dann intern ab.

Wie wuerdest Du/Ihr denn die Functionen sinnvoll benennen?

cruiser 21. Sep 2007 17:25

Re: Zählsystem für Tennis entwickeln
 
Ich würd eine Funktion in jeweils der Match, Satz und Spielklasse machen...

sowas wie:
Delphi-Quellcode:
{...}
  function TMatch.SetPoint(player,point: integer);
  begin
    actSet.SetPoint(player,point);
    // wenn Satz beendet eröffne neues Match bzw. beende Match
  end;

  function TSet.SetPoint(player,point: integer);
  begin
    actGame.SetPoint(player,point);
    // wenn Spiel beendet eröffne neues Spiel, beende Satz oder gehe in den Tiebreak-Modus
  end;


  function TGame.SetPoint(player,point: integer)
  begin
    // wenn player = 1
      // wenn point > 0 erhoehe Spieler1
      // wenn point < 0 senke Spieler1
    // sonst
      // wenn point > 0 erhoehe Spieler2
      // wenn point < 0 senke Spieler2

    // evtl. umstellen wer gerade Vorteil hat
  end;

{...}
Edit: evtl. Lohnt es sich von TPersistent abzuleiten... damit könntest du die einzelnen Sachen für Undo's in Streams ablegen...

torud 22. Sep 2007 14:14

Re: Zählsystem für Tennis entwickeln
 
Hello again,

also ich bin nun an folgendem Punkt angelangt. Ich habe die Klassen te_game, te_set und te_init erstellt mit folgendem Inhalt:

Delphi-Quellcode:
unit te_init;

interface

uses te_game;

  procedure InitVariables;

implementation

procedure InitVariables;
begin
   akt_points_a := 0;
   akt_points_b := 0;
end;

end.
Delphi-Quellcode:
unit te_game;

interface

uses Dialogs,SysUtils;

var
  akt_points_a,akt_points_b:integer;


  function SetPoint(player,point: integer):boolean;

implementation

function SetPoint(player,point: integer):boolean;
begin
  // wenn player = 1
  case player of
    1 : begin
          // wenn point > 0 erhoehe Spieler1
          if point > 0 then inc(akt_points_a);
          // wenn point < 0 senke Spieler1
          if point < 0 then dec(akt_points_a);
        end;
    2 : begin
          // wenn point > 0 erhoehe Spieler2
          if point > 0 then inc(akt_points_b);
          // wenn point < 0 senke Spieler2
          if point < 0 then dec(akt_points_b);
        end;
  end;
  showmessage(inttostr(akt_points_a));
end;
end.
Im FormCreate meiner Applikation rufe ich auf:
Delphi-Quellcode:
procedure TForm1.FormCreate(Sender: TObject);
begin
  InitVariables;
end;
und wenn ich mal einen Testbutton für plus A drücke, passiert folgendes:
Delphi-Quellcode:
SetPoint(1,1);
Also Spieler 1 oder A erhält einen Pluspunkt.

Nun stehe ich vor dem Problem mit dem Zählen in der richtigen Reihenfolge => 0, 15, 30, 40 und wenn akt_points_a schon 40 hat und einer dazukommt, würde ich dann akt_games_a "inc"en...aber wie?

torud 22. Sep 2007 18:48

Re: Zählsystem für Tennis entwickeln
 
Ok, ich habe mir noch ein paar Gedanken gemacht und die SetPoint erweitert, nachdem ich mir in der Hilfe inc/dec nochmals angesehen habe. Das ist zwar jetzt noch nicht die Endversion, aber ein Zählen von 0 -40 und andersrum ist nun drin. 4 Probleme/Fragen habe ich derzeit. Sicher nicht die letzten. :oops:

1. Ich habe noch nicht herausgefunden, wie ich das mit dem Vorteil lösen soll, da ja die Punkte in den Variablen akt_point_a und akt_point_b, welche vom Typ her integer sind, geschrieben und auch hochgezählt werden. Also wie soll ich da ein A für Vorteil reinschreiben, bzw. wie kann ich das händeln?

2. Den Code finde ich schon jetzt ziemlich aufgebläht. Geht das auch anders? Ich denke meist nach Schema F und würde gern über den Tellerrand hinausblicken.

3. Ich würde gern das Befüllen der Controls, den die Inhalte sollen ja dann dem Programm auch sichtbar zugeführt werden, bzw. rausgeschickt werden, extra abhandeln. Anwelcher Stelle würdet Ihr das zentral lösen? Zur Zeit tue ich dies per DUmmy mit dem Showmessage am Ende von SetPoint, aber eigentlich kanns das nicht sein, weil ich diese Routine auch in Richtung SetGame verlassen muss, wenn ein Spieler mit dem aktuell gewonnenen Punkt ein Spiel gewonnen hat.

4. Desweiteren müsste ich dann nachdem ich ein gewonnenes Spiel erkannt habe akt_point_a und akt_point_b wieder auf 0 zurücksetzen. Sollte das in Setpoint geschehen oder besser in SetGame, respektive SetSetWin (gibts noch nicht)...

Hier mein Code von SetPoint:
Delphi-Quellcode:
function SetPoint(player,point: integer):boolean;
var
  n : integer;
begin
  // wenn player = 1
  case player of
    1 : begin
          // wenn point > 0 erhoehe Spieler1
          if point > 0 then
            begin
              //festlegen, um wieviel ge-inc-t wird
              case akt_points_a of
                0,15  : n := 15;
                30,40 : n := 10;
                else exit;
              end;
              inc(akt_points_a,n);
            end;
          // wenn point < 0 senke Spieler1
          if point < 1 then
            begin
              //festlegen, um wieviel ge-dec-t wird
              case akt_points_a of
                15,30  : n := 15;
                40     : n := 10;
                else exit;
              end;
              dec(akt_points_a,n);
            end;
        end;
    2 : begin
          // wenn point > 0 erhoehe Spieler2
          if point > 0 then
            begin
              //festlegen, um wieviel ge-inc-t wird
              case akt_points_b of
                0,15  : n := 15;
                30,40 : n := 10;
                else exit;
              end;
              inc(akt_points_b,n);
            end;
          // wenn point < 0 senke Spieler2
          if point < 1 then
            begin
              //festlegen, um wieviel ge-dec-t wird
              case akt_points_b of
                15,30  : n := 15;
                40     : n := 10;
                else exit;
              end;
              dec(akt_points_b,n);
            end;
        end;
  end;
  showmessage(inttostr(akt_points_a));
end;

cruiser 23. Sep 2007 05:08

Re: Zählsystem für Tennis entwickeln
 
Liste der Anhänge anzeigen (Anzahl: 1)
Vieles würde sich erschlagen, wenn du wie ich oben schon schrieb, eine Enumeration nimmst:

Delphi-Quellcode:
type
  Te_points = (tp0, tp15, tp30, tp40, tp40a);

{...}

var
  pnt_a: Te_points; // kein integer... dadurch bläht es so auf!

{...}

pnt_a := tp0; // initialisieren

Inc(pnt_a); // pnt_a hat jetzt den Status tp15

pnt_a := tp40a; // initialisieren

Dec(pnt_a); // pnt_a hat jetzt den Status tp40
Was das A angeht, würde ich ein constantes Array mit den Ausgabewerten definieren:

Delphi-Quellcode:
const
  _tearr_points : array of string = ('0', '15', '30', '40', 'A');

{...}

Zugriff über z.B.:
string_a := _tearr_points[ord(pnt_a)];
zu 4.: Wenn ein Spieler bei tp40a oder tp40 steht und einen Punkt bekommt ist das Spiel abgeschlossen. Entsprechend kannst du guten gewissens die werte wieder auf tp0 setzen und der in der Logik nächst höheren Klasse (Satz) mitteilen, wer denn denn das Spiel gutgeschrieben bekommt. Wichtig ist, dass du dir merkst, wer im Ballbesitz ist!

zu 3.: Ich würde eine Zeichenklasse baun, die das auf ein Canvas(oder was auch immer) ausgibt. Diese Klasse kannst du ja beim erzeugen der Instanzen an jene jeweils immer weiter geben. Somit gibt jede Logik-Klasse der Zeichenklasse die Infos, was sich denn geändert hat.

Edit: mh... ich hab mal den Anfang gemacht und das ein wenig strukturiert... mit bisschen Struktur wird es immer weniger aufgebläht ;) Siehe Anhang. Evtl. kannst du darauf ja aufbaun

alzaimar 23. Sep 2007 09:08

Re: Zählsystem für Tennis entwickeln
 
Das stimmt aber so nicht, denn wenn ein Spieler 'tp40a' Punkte hat, under andere auch, dann ist bei dem Gewinn eines weiteren Punktes ja noch lange nicht schluss. Ich würde die Punkte einfach addieren (Punkte = Integer, wieso nicht?), und nur die Ausgabe (Visualisierung) dem im Tennis üblichen Gehopse von 0 auf 15 auf 30 auf 40 etc. anpassen, etwa so:

Delphi-Quellcode:
Function ShowPoints (aPointsA, aPointsB : Integer) : String;
Var
  sScoreA, sScoreB : String;

  Function Score (aPoints : Integer) : String;
  Begin
    Case aPoints Of
      0 : Result := '0';
      1 : Result := '15';
      2 : Result := '30';
      3 : Result := '40';
      else Result :='Advantage'
    End;
  End;

Begin
  sScoreA := Score (aPointsA);
  sScoreB := Score (aPointsB);
  Case max (aPointsA, aPointsB) Of
    0,1,2,3 :
      Result sScoreA+':'sScoreB        
    Else
      If Abs (aPointsA-aPointsB)>1 Then // Jemand gewinnt
        If aPointsA>aPointsB Then
          Result := 'Spieler A gewinnt'
        else
          Result := 'Spieler B gewinnt'
      else If aPointsA>aPointsB Then
        Result := sScoreA+' A'
     else
        Result := sScoreA+' B'
   End
End;

Function IsAWin (aPointsA, aPointsB : Integer) : Boolean;
Begin
  Result := (Max (aPointsA, aPointsB)>3) And (Abs (aPointsA-aPointsB)>1)
End;
Gewonnen hat der, der zuerst mehr als 3 Punkte gemacht und dabei mindestens 2 Punkte mehr als der Gegner hat.

Der Nachteil einer Enumeration ist ja der, das man beim Stand von 'tp45A' nicht weiter erhöhen kann. Das muss aber möglich sein, denn viele Spiele sind hart umkämpft...

torud 23. Sep 2007 09:31

Re: Zählsystem für Tennis entwickeln
 
Hier ist noch ein kleiner Fehler drin, denn in Deinem Code - lieber alzaimar, wird noch nicht so recht berücksichtigt, was denn passiert, wenn nach einem A:40 wieder ein 40:40 wird. Das steht dann naemlich leider immernoch Advantage...Habe ich nur gerade beim Testen festgestellt. Also ich will nicht übertreiben, aber einfach ist es nicht wirklich... :wink:

Hier nochmal ein eventuelles Szenario:

30:40
40:40 ((oder deuce) dies wird optional sein, da es da diverse vorlieben gibt)
A:40 (Spieler A hat Vorteil)
40:40 (üblicherweise wird hier sogar folgendes gezeigt => "#2 Deuce") damit wissen alle, wie umkämpft dieses Spiel ist
40:B (Spieler B hat Vorteil)
40:40 (oder Deuce oder #3 Deuce)
40:B (Spieler B hat wieder Vorteil)
Pluspunkt B

Spieler B hat nun dieses Spiel gewonnen. Sein Punktestand im aktuellen Satz wird um 1 erhöht.

cruiser 23. Sep 2007 10:00

Re: Zählsystem für Tennis entwickeln
 
@Alzaimar
nuja... bei A:40 und B macht einen Punkt muss man ja nich B weiter erhöhen sondern kann entsprechend A niedriger setzen.

In meinem Code ist sicher nicht alles berücksichtigt. Wollt halt aufzeigen, dass es auch ohne Bläh-Code mit x cases und Ifs geht

torud 23. Sep 2007 10:22

Re: Zählsystem für Tennis entwickeln
 
Habe gerade gesehen, dass in Alzaimar´s Beispiel der Tiebreak noch nicht mit drin war. Ich werde mal ein kleines Beispiel-Projekt "bauen", welches ich hier dann hochladen. Jeder der will, kann ja mitmachen und verbessen...denn es gibt schon einige Optionen im Tennis, die es zu berücksichtigen gibt...

torud 23. Sep 2007 11:29

Re: Zählsystem für Tennis entwickeln
 
Liste der Anhänge anzeigen (Anzahl: 1)
habe gerade versucht die tennis.pas mit ins Projekt einzubinden, damit zu spielen und sie zu verstehen. ich band die Unit also ein und wollte dann TE_Spiel.SetPoint aufrufen, aber leider geht das nicht. Warum nur?

Im Anhang mal ein kleines Beispiel-Projekt

torud 23. Sep 2007 12:58

Re: Zählsystem für Tennis entwickeln
 
Ich habe den Code der Tennis.pas nun mit in meine Unit kopiert und rufe SetPoint so über nen Button auf:

Delphi-Quellcode:
TE_Spiel.SetPoint(ts1,false);
Leider geht das scheinbar nicht so, da mir Delphi meldet, dass "Die Form des Methodeaufrufs nur für Klassenmethoden erlaubt ist."

Was bedeutet das?
Und muss ich wirklich den gesamten Code mit in meine HauptUnit aufnehmen?

cruiser 23. Sep 2007 16:54

Re: Zählsystem für Tennis entwickeln
 
Du musst auch den Interface-Teil mitnehmen, da ich bereits angefangen habe Klassen zu bauen :mrgreen:

torud 23. Sep 2007 18:22

Re: Zählsystem für Tennis entwickeln
 
Liste der Anhänge anzeigen (Anzahl: 1)
Ich habe den Code der Tennis.pas nun mit in meine Unit kopiert und rufe SetPoint so über nen Button auf:

Delphi-Quellcode:
TE_Spiel.SetPoint(ts1,false);
Leider geht das scheinbar nicht so, da mir Delphi meldet, dass "Die Form des Methodeaufrufs nur für Klassenmethoden erlaubt ist."

Was bedeutet das?
Und muss ich wirklich den gesamten Code mit in meine HauptUnit aufnehmen?

Zu meiner Schande muss ich gestehen, dass ich so was noch nie gemacht habe. Weshalb ich dann auch gleich an dem oben genannten Problem gescheitert bin. Ich habe daraufhin die Klassendeklarationen entfernt. Dann kommen schon mal keine Fehler mehr, aber ich konnte einfach nicht durch den Code steigen, verstehe nicht, wozu Drawer da sein soll und vieles mehr.

Ich habe nun einfach mal statisch in SetPoint aufgerufen:

Delphi-Quellcode:
lbl_pointsA.Caption := TE_PunktStrings[ord(2)];
Ich habe es auch anders versucht, aber ich weiss einfach nicht, wie ich an den aktuellen Punktestand rankomme...Tricky. Ich hänge hier ans Post mal noch die aktuelle Version mit an. Vielleicht hast Du ja Nerven es Dir mal anzusehen...!? Ansonsnten würde ich auch den Code der Unit posten, wenn Dir das lieber wäre...

Bin zur Zeit fast schon am überlegen, ob ich nicht lieber doch meine 1000 Zeilen längere Version nehmen sollte, weil ich da wenigsten den Code verstehe... :shock:

cruiser 23. Sep 2007 19:27

Re: Zählsystem für Tennis entwickeln
 
lass den Code doch wo er ist, binde die tennis.pas in die uses ein und erzeug ein Objekt TE_Spiel.

torud 23. Sep 2007 19:36

Re: Zählsystem für Tennis entwickeln
 
Du hast natürlich recht!

Für, die es auch wissen wollen: Ich habe global mySpiel als Variable angelegt und im FormCreate dann einfach das Objekt erzeugt.

Delphi-Quellcode:
  mySpiel := TE_Spiel.Create(nil);
Ging nur mit Nil, obwohl mir TE_Drawer vorgeschlagen wurde. Werde nun mal Deinen Code weiter verfolgen. Habe schon gefunden, dass SetPoint sogar soo clever ist und mir nen Boolean zurückgibt, falls das Spiel zu Ende ist. Sehr geil!

cruiser 23. Sep 2007 19:48

Re: Zählsystem für Tennis entwickeln
 
Sag ich doch ;) Der Klassen-Ansatz ist nicht zu kompliziert und du hast jedes logische Element für sich gekapselt... und ja, weil der Drawer ja nur als dummy da ist geht durchaus auch nil

torud 23. Sep 2007 20:14

Re: Zählsystem für Tennis entwickeln
 
Ok, leider hänge ich derzeit wieder mal etwas.

Ich komme nicht weiter mit der Ausgabe, sprich das, was Du mit dem Drawer machen wolltest. Zum einen muss ich die Ergebnisse im Tool selbst in Edits und Labels anzeigen und zum anderen werden sie später nach draussen übergeben. Das heisst, ich werde wohl die Variablen Public machen müssen, um auch aus dem Hauptprogramm darauf zugreifen zu können.

Oder Du erklärst mir noch, wie ich das mit dem Drawer machen könnte...?

cruiser 23. Sep 2007 20:30

Re: Zählsystem für Tennis entwickeln
 
naja der Drawer stellt im Prinzip die verbindung nach aussen dar. In der Drawer-Klasse baust du einige Funktionen, die die Werte entgegen nehmen und eben ausgeben. Ob das nun auf der basis von Edits, in einem Canvas oder per Serieller Schnittstelle an Anzeigetafeln ausgegeben wird spielt ja keine Rolle. Denkbar wär auch, den Drawer so zu gestalten, dass er gleich einen Weiteren Drawer ansteuern kann. So wäre es möglich für jede Ausgabe eine spezielle Zeichner/Ausgabeklasse zu erstellen. Das einzigewas zu beachten ist, wäre, dass du halt immer das selbe Interface nutzt.

torud 23. Sep 2007 20:35

Re: Zählsystem für Tennis entwickeln
 
und wie creiere ich den Drawer? Von was leite ich ab? Habe sowas noch nicht gemacht. *Schäm*

Ich frage halt, weil ich ja hier

Delphi-Quellcode:
  mySpiel := TE_Spiel.Create(nil);
den Drawer nicht angeben konnte. Liegt das daran, dass ich ihn selbst noch nicht creiert habe?

cruiser 23. Sep 2007 20:37

Re: Zählsystem für Tennis entwickeln
 
Genau. zudem fehlt dem Drawer auch noch jegliche Funktionalität...

Nur ein Hinweis am Rande... das Erzeugen des TE_Spiel sollte später auch aus TE_Satz heraus erfolgen und nicht direkt im Code.

Zum Schluss brauchst du nur noch eine Match-Klasse zu initiieren und die verschiedenen Ausgabeklassen.

u.U. kann man den Drawer auch noch anders machen... mh... ich lass mir mal was einfallen.

torud 23. Sep 2007 20:41

Re: Zählsystem für Tennis entwickeln
 
Ok das ist schon klar, aber wie muss ich nun vorgehen? Ich muss ja den Drawer irgendwo erzeugen und er muss ja auch wissen wohin er schreiben soll. Ich würde dem Drawer einfach ne Funktion geben, wie ShowStandings, die dann immer alles rausschickt...

cruiser 23. Sep 2007 20:46

Re: Zählsystem für Tennis entwickeln
 
siehe edit oben... kannst du mal anhängen, was du hast, ich würd mir das noch mal ansehn, aber nich jetzt ;)

torud 23. Sep 2007 20:52

Re: Zählsystem für Tennis entwickeln
 
Liste der Anhänge anzeigen (Anzahl: 1)
So hier im Anhang ist nun die aktuelle Version.

Ich habe mal eine Routine reingebastelt, die zumindest die Punkte mal in die Labels schreibt. Der aktuelle Aufschläger wird sich leider noch nicht gemerkt.

Folgendes habe ich noch gefunden, was nicht ganz passt.

Wenn ich direkt zu Beginn einen Minus-Button drücke erscheint eine 15 für A und eine 30 für B. Gebe ich dann wieder einen Plauspunkt springt die Anzeige wieder auf 0 zurück.

Wenn ich Deuce (40:40) simuliere und dann A einen Punkt gebe, erscheint für A ein A. Das ist korrekt. Gebe ich dann B wieder einen Punkt, wäre wieder Deuce (40:40). Stattdessen erscheint aber A:A. Gebe ich dann wieder A einen Punkt, beendet er das Spiel, obwohl das eigentlich nicht korrekt ist. Richtig wäre A:40

cruiser 24. Sep 2007 15:46

Re: Zählsystem für Tennis entwickeln
 
Null-Prüfung, Advantage Regelung, Deuce-Zähler und Aufschlagwechsel waren auch noch nich implementiert ;)
ich hab mir was zu der Ausgabe überlegt. Ist wohl besser, wenn Spiel und Satz-Klassen nur ihre Match-Klasse kennen. Diese dann aber eine Liste von Ausgabeklassen kennt, die sie nach und nach ansprechen kann. Auf die Weise kannst du die Ausgabe auf so viele Art und weisen umlenken wie du brauchst/willst. Werd das versuchen im Code schon mal vorzubereiten, inkl. einer Basisklasse/Interface für Ausgaben von der du ableiten kannst

torud 24. Sep 2007 18:07

Re: Zählsystem für Tennis entwickeln
 
You are my hero!

Falls Du regeltechnisch noch was wissen musst, lass es mich wissen...

cruiser 25. Sep 2007 08:23

Re: Zählsystem für Tennis entwickeln
 
Liste der Anhänge anzeigen (Anzahl: 2)
Sooooo... hab ein wenig gefrickelt:

1.) Dem Spiel (später dem Satz/Match) wird jetzt eine Liste von Ausgabe-Objekten übergeben

2.) Die einzelnen Ausgabe-Objekte müssen von einem Interface abgeleitet werden (wg. der Typsicherheit)

3.) Ich hab eine Wrapperklasse auf Basis des Interfaces für Objektmethoden gebaut. Damit ist Cross-Referencing überflüssig

4.) Die Regeln für ein Spiel müssten jetzt soweit funktionieren incl. Advantage, Deucezähler, Aufschlagwechsel und Nullprüfung

5.) ich hab dein Demo-Projekt an die neuen Klassen angepasst

6.) Gibt es jetzt folgende Hilfsfunktionen:
PunkteToStr(TE_Punkte):string
SpielerToStr(TE_Spieler):string
Gegenspieler(TE_Spieler):TE_Spieler

Ich hoffe mal das ist dir sauber genug.

Edit: Bekomm ich nen Credit im fertigen Prog? ;)

Edit 2: Ich hab mal einen groben Strukturplan angehängt, der evtl. eher aufzeigt, wie ichs mir gedacht hab

torud 25. Sep 2007 15:43

Re: Zählsystem für Tennis entwickeln
 
Hallo Ronny,

erst einmal vielen Dank und grosses Lob für Deine Mitarbeit. Ich denke, dass dies nicht nur für mich wichtig ist, sondern, dass damit sicher auch einige Spieleprogrammierer was anfangen können.

Ich habe leider erst übermorgen Zeit den Code zu testen, da ich gerade beruflich unterwegs bin. Ich habe mir den Code aber schon mal in Notepad angesehen. Dabei habe ich mich gefragt, ob ich richtig gesehen habe, dass Du den Aufschlag bei einem Punkt von Spieler_B wechselst, wenn Spieler_A den Aufschlag hatte!? Aber das kann auch nur ein Missverständnis sein, dem ich beim Überfliegen unterlegen war, denn der Aufschlag und das weisst Du sicher, wird nur nach jedem Spiel gewechselt.

So, um die ganze Sache noch abzurunden und ich denke, dass alle Mitleser und Nutznießer dies sicher schon fragend in sich bemerkt haben, noch 2 Punkte.

Im Tennis gibt es noch 2 wichtige Regeln.

1. Es gibt Doppel-Spiele, bei denen die sogaenannte No-Ad-Regel zum tragen kommt. Wie sieht diese Regel aus? Ganz einfach. Um das Spiel attraktiver für die Zuschauer zu machen, gibt es Turniere, wo es KEINEN Vorteil bei Doppelspielen gibt. Die trägt dazu bei, dass die Spiele schneller entschieden werden. Ich habe leider vergessen diese Checkbox in mein Beispielprogramm einzubinden und diese Erläuterung im Eingangsposting mit einzubinden. Sicher, weil es einfach zu viel auf einmal gewesen wäre. Das bedeutet, dass das Team, welches bei 40:40 den nächsten Punkt macht den Spielpunkt erhält.

2. Bei bestimmten Turnieren und Veranstaltungen ist es so, dass die Advantage-Final-Set-Regel zum tragen kommt. Das heisst, dass bei einem Best-of-3 der dritte Satz, wenn die vorhergehenden 2 Sätze 1:1 ausgegangen sind OHNE Tiebreak gespielt werden. Bei einem Stand von 6:6 geschieht nun folgendes. Es wird solange weiter gespielt, bis ein Spieler 2 Spielpunkte Abstand vom anderen hat. Also wäre der 3 Satz gewonnen, wenn der Spielstand zum Beispiel 6:8 wäre. Ein 11:9 wäre aber auch gültig. Hierfür müsste ich auch noch eine Checkbox einpflegen. Ich werde mal versuchen in Deinen Code, der so herrlich übersichtlich ist, einzusteigen, um dies umzusetzen.

Solltest DU noch Lust und Laune haben, könntest Du mir ja noch nen Hinweise geben, falls ich was wichtiges dabei zu beachten habe.

Einen Credit im Tool? Den sollst Du unbedingt haben. Wird ein FETTER!!! Definitv. Wenn es so weit ist, werde ich Dir nen Screenshot senden. Ist mit Sicherheit ne gute Referenz. Ok?

Noch eine Frage:
Wie kann ich es händeln, dass die Klassen auch den aktuellen Spielstand erfahren, wenn die Daten von externer Schnittstelle kommen? Es ist ja nur so, dass die Steuerung von Hand vorgenommen werden soll, wenn die externe Steuerung versagt, aussetzt oder nicht schnell genug ist, weil sich zum Beispiel der Chair Umpire Zeit lässt oder vergessen hat den Punkt ins System zu geben. Das bedeutet, dass die Klssen im Laufenden Betrieb den Inhalt erfahren müssen, um aktuell zu sein. Köönte ich die nun auch von AUSSEN befüttern?

cruiser 25. Sep 2007 17:32

Re: Zählsystem für Tennis entwickeln
 
Liste der Anhänge anzeigen (Anzahl: 1)
Zitat:

Zitat von torud
der Aufschlag und das weisst Du sicher, wird nur nach jedem Spiel gewechselt.

:oops: nein, wusst ich nicht.

Nachtrag: Aber jetzt isses nich mehr drin, statt dessen eine Eigenschaft zum ansteuern: TE_Spiel.Service:TE_Spieler

Zitat:

Zitat von torud
... Das bedeutet, dass das Team, welches bei 40:40 den nächsten Punkt macht den Spielpunkt erhält.

lässt sich nachrüsten... kein Ding.

Nachtrag: Eingebaut. aktivierbar über die Eigenschaft: TE_Spiel.NoAdRegel:Boolean

Zitat:

Zitat von torud
Advantage-Final-Set-Regel zum tragen kommt.

Das gehört für mich logisch in die Satz-Klasse, wenn nicht gar in die Match-Klasse.

Nachtrag: Genau genommen in beide. Das Match muss wissen, dass diese Regel gilt. Und der Satz erst wenn es der letzte Satz ist.

Zitat:

Zitat von torud
Solltest DU noch Lust und Laune haben, könntest Du mir ja noch nen Hinweise geben, falls ich was wichtiges dabei zu beachten habe.

Das Thema ist recht interessant.. jedenfalls für mich, also wenns Probleme gibt...

Zitat:

Zitat von torud
Einen Credit im Tool? Den sollst Du unbedingt haben. Wird ein FETTER!!! Definitv. Wenn es so weit ist, werde ich Dir nen Screenshot senden. Ist mit Sicherheit ne gute Referenz. Ok?

supi :mrgreen:

Zitat:

Zitat von torud
Wie kann ich es händeln, dass die Klassen auch den aktuellen Spielstand erfahren, wenn die Daten von externer Schnittstelle kommen?

Recht simpel... eine Klasse baun, die diese Schnittstelle abfragt und kapselt. Eventuell regelmässig über einen extra Thread abfragt. Ein Objekt von so einer Klasse muss halt das Match-Objekt kennen um die Befehle dahin zu senden.

Mit einer externen Ausgabe läufts ja ähnlich: eine Klasse baun, die ITE_Ausgabe kapselt, da dann halt die steuerung für das externe System kapseln und ab gehts.

Wird das irgendwann auf nem Platz in Sachsen laufen? Kann mans in Aktion erleben? :mrgreen:

Nachtrag: Mal die neue Version angehangen ;)

torud 26. Sep 2007 14:50

Re: Zählsystem für Tennis entwickeln
 
Hallo Ronny,

ich bin wie schon erwähnt noch immer unterwegs, werde mir aber morgen Vormittag den Code ansehen und testen. Wenn ich noch Zeit finde, schaue ich hier nochmals im Notepad in den Code. Was mir gerade noch einfällt und es tut mir leid, dass das hier so kleckerweise kommt, ist der Aufschlag im Tiebreak.

Sicher stöhnst Du jetzt schon das erste mal, aber auch da gibt es eine spezielle Regel, die allerdings immer im Tiebreak zum Tragen kommt. Nehmen wir an, dass der Spieler A Aufschlag hat und das es derzeit 5:6 im ersten Satz steht. Er gewinnt das Spiel zum Spielstand 6:6.

Nun hat normalerweise Spieler B Aufschlag. Er tätigt auch den ersten Aufschlag. Danach hat Spieler A wieder Aufschlag. Der Aufschlag wechselt nach dem 1. Aufschlag von Spieler B immer im 2er Rythmus. Also B 1 mal, dann A 2 mal, dann B 2 mal und dann wieder A 2 mal, solange bis der Tiebreak ausgespielt wurde und der Satz damit entschieden ist. Ich könnte nun den Aufschlag auch manuell vom Code her wechsln lassen, aber mir wäre es lieber, wenn die Tennisklasse das tut.

Ich schau also morgen mal in Deinen Code. Weitere Details zur Verwendung werde ich dann auch noch bekanntgeben. Es wird jedenfalls KEINE Verkaufslösung.

cruiser 26. Sep 2007 15:21

Re: Zählsystem für Tennis entwickeln
 
Das ist aber Tie-Break und kommt damit erst in der Satz-Klasse zum tragen laut Logik, also kein Grund zum Stöhnen, weil die Satzklasse immer noch ein leerer Dummy ist. ;)

Edit: evtl. kann man auch ähnlich der Spiel-Klasse eine TieBreak-Klasse anlegen, die die Regeln und evtl. Sonderregeln des TieBreak beinhaltet.

torud 26. Sep 2007 15:43

Re: Zählsystem für Tennis entwickeln
 
Hello Again,

ich habe gerade folgenden Code gefunden:

Delphi-Quellcode:
 TieBreak: array[1..2] of Byte;
Sachmal, wenn die Tiebreak-Punkte vom Typ Byte sind, wäre doch bei 7 Schluss, oder!? Also ich glaube, dass ein Byte nur von 0-7 geht. Oder? Aber ein Tiebreakt kann doch auch auch 11:9 enden, oder was zählt Du damit?


Habe gerade weiter im Code gesehen, dass ja, wie von Dir geschrieben nur die Punkte derzeit gezählt werden und die Games noch nicht, was dazu führt, dass die Tiebreak-Regel noch gar keine Anwedung findet. Aber trotzdem. Was soll mit Tiebreak gezählt werden. Die Tiebreak-Stände? Von 0:0 bis z.B. 13:11?

DeddyH 26. Sep 2007 15:45

Re: Zählsystem für Tennis entwickeln
 
Zitat:

Zitat von torud
Also ich glaube, dass ein Byte nur von 0-7 geht

Du hast da was verwechselt: ein Byte hat 8 Bit. Daraus ergeben sich 2^8 Möglichkeiten, also von 0 bis 255.

cruiser 26. Sep 2007 15:52

Re: Zählsystem für Tennis entwickeln
 
Exakt... von 0-255 wenn das nicht reicht könnt man über Word (0-65535) nachdenken.

Ja... in dem Record sollen die Daten eines Satzes erfasst werden. Das heißt Spielpunkte + TieBreak letztlich fließt ein Array dieser Satz-Stände in das Record der Ausgabedaten mit ein.

Ob und wie man das noch abändern sollte/kann werden wir ja sehn, sobald wir es brauchen.. :drunken:

torud 26. Sep 2007 17:27

Re: Zählsystem für Tennis entwickeln
 
Man ist das peinlich. Da habe ich wohl wirklich was durcheinander gebracht...Sorry.

Von daher muss der Datentyp für den Tiebreak nicht geändert werden...

torud 27. Sep 2007 11:18

Re: Zählsystem für Tennis entwickeln
 
So, also ich wollte ja nun eigentlich etwas weitermachen. Erstmal ein Lob, da bisher alles super funzt.

Nun zu meinen Problemen, weil ich ja eigentlich auch was an der Klasse machen wollte. Ich habe also folgendes der Tennis.Unit hinzugefügt:

Delphi-Quellcode:
  // Satz-Klasse
  TE_Satz = class
  private
    FGames : array[1..2] of Byte; //für die spielpunkte in einem satz
    FActSet : Byte;              //um zu wissen, in welchem satz ich bin...
  public
    // setzt GamePunkte und gibt zurück, ob dar Satz beendet ist
    function SetGamePoint(const Spieler: TE_Spieler; const Undo: Boolean) : Boolean;
  end;

function TE_Satz.SetGamePoint(const Spieler: TE_Spieler; const Undo: Boolean) : Boolean;
begin
  if Spieler = tskein then Exit;

  // Nullprüfung:
  if (FGames[Ord(Spieler)] = 0) and Undo then
    Exit;

  if Undo then
    Dec(FGames[Ord(Spieler)])
  else
    Inc(FGames[Ord(Spieler)]);

end;
Nun habe ich im Hauptprogramm mal versucht, nicht mehr nur die Punkte zu setzen, sondern auch auf das Boolean von SetPoint zu reagieren, da wir ja in dem Fall einen Punktgewinner haben und wollte eigentlich nur mal ganz stupide den Punktestand hochzählen. Allerdings ist dem Hauptprogramm die Funktion SetGamePoint nicht bekannt, obwohl ich diese als Public deklariert habe. Warum das eigentlich? Fehlt mir hier der Create?

cruiser 27. Sep 2007 15:09

Re: Zählsystem für Tennis entwickeln
 
Dein Problem ist ein wenig das Verständnis des Klassenkonzepts, und das mein ich nicht abwertend.
Du musst immer die in der Logik höchste Klasse erzeugen. Die erzeugt dann die nächst niedrigere.

Code:
TE_Match --erzeugt--> TE_Satz --erzeugt--> TE_Spiel
                                           TE_TieBreak
Mal ein Bespiel für die spätere Verwendung:

Du erzeugst eine TE_AusgabeListe und fügst alle nötigen Objekte basierend auf ITE_Ausgabe da ein.

Du erzeugst ein TE_Match mit eben diser Ausgabeliste.

Du setzt die zu verwendenden (Sonder)regeln

Du initiierst ein Match mit n Sätzen.

> TE_Match erzeugt jetzt ein Array mit n TE_Satz Objekten, welche auch gleich erzeugt werden.
> TE_Match setzt den ersten Satz als aktuellen
> TE_Satz(0) erzeugt daraufhin seine TE_Spiel Klasse

Du Sendest nun einen Kommando an die TE_Match Klasse

> TE_Match prüft ob es damit etwas anfangen kann, wenn nicht geht es weiter an TE_Satz(aktuell)
> TE_Satz(aktuell) prüft ob es etwas damit anfangen kann wenn nicht geht es weiter an die TE_Spiel oder TE_TieBreak Klasse

-----------------------

Das ganze könnte man in der Tat auch innerhalb nur einer Klasse lösen. Aber so hat jede Klasse nur einen teil der Funktionalität. In deinem speziellen Fall müsstest du also dafür sorgen, dass TE_Satz sauber erzeugt wird und schon einmal ein Spiel vorbereitet. Auch die Durchleitung der Befehle muss implementiert sein. Dass dein SetGamePoint nicht mit mySpiel funktioniert ist klar. mySpiel ist ein Objekt vom Typ TE_Spiel und nicht TE_Satz.

torud 27. Sep 2007 19:29

Re: Zählsystem für Tennis entwickeln
 
Ähm, also ich glaube, ich lass es lieber, denn das einzige, was ich verstanden habe, waren Deine letzten 2 Sätze. Du lagst also gar nicht soo verkehrt mit Deiner Vermutung mit meinem Verständnis...Ist mir wahrscheinlich alles zu abstrakt...Ich werde sicher nicht gleich komplett aufgeben, aber ich denke nicht, dass ich den Weg so gehen werde, nachdem ich feststellen musste, dass ich zwar Deinen bisherigen Code verstanden habe, aber den Weg über Match=>Set=>Game nicht finden werde. Die ist nun keine Bettelei um weiteren Code, denn der würde mir sicher nichts bringen, wenn ich später weitere Anpassungen vornehmen müsste. Der ganze Kram, bitte nicht falsch verstehe, mit der TE_AusgabeListe scheint mir logisch, aber ich verstehe einfach nicht, was wo und wie mit dem Created werden muss und und und...PEIN komme über mich!

cruiser 27. Sep 2007 19:45

Re: Zählsystem für Tennis entwickeln
 
Na soooo schnell würd' ich nicht aufgeben... ich glaub, wenn die Satz-Logik steht kriegst du den Rest auch selbst hin ;)

OOP ist halt dahingehend übersichtlicher, dass immer kleine Logikstücke gekapselt sind.


Alle Zeitangaben in WEZ +1. Es ist jetzt 23:55 Uhr.
Seite 1 von 2  1 2      

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