Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Herausfinden ob Breakpoint ist oder nicht - Wie? (https://www.delphipraxis.net/168831-herausfinden-ob-breakpoint-ist-oder-nicht-wie.html)

torud 13. Jun 2012 10:26

Delphi-Version: 7

Herausfinden ob Breakpoint ist oder nicht - Wie?
 
Hallo Wissende,

ich habe zur Verfügung den Punktestand von Spieler A (30) und B (40) und weiss wer den Aufschlag (A) hat.

In dem konstruierten Fall hat Spieler A den Aufschlag und nur 30 Punkte und Spieler B hat 40 Punkte. Somit haben wir die Situation, dass wir einen Breakball haben.

Breakball ist immer, wenn der Aufschlagsempfänder 40 Punkte oder Vorteil hat und der Aufschlagende weniger Punkte als der andere hat. Bei 0 - 40 hätte man zum Beispiel 3 Breakballe, weil man 3 mal die Chance hat mit dem nächsten Punkt das Spiel zu gewinnen.

Ich bin nun am Rätseln, wie ich eine Funktion schreiben kann, die möglichst kurz ist, die mir als Ergebnis einfach nur einen boolschen Wert True zurückgibt, wenn wir einen Breakball haben.

Wenn ich jetzt einfach nur nach Strings vergleichen würde, wäre die Routine ewig lang. Geht das auch einfacher?

Für die, die nicht wirklich Ahnung vom Tennis haben.
Es gibt folgende Punkte innerhalb eines Punktspieles:

0,15,30,40 der danach erungene Punkt würde den Spielpunkt erbringen.

Stünde es 40 - 40 wäre Einstand
Danach Käme dann 40 - A -> Spieler B hat Vorteil und wenn Spieler A Aufschlag hätte, wäre Breakball und umgekehrt.

Ich bin am grübeln, ob es sinnvoll wäre da nen eigenen Typen für die Punkte zu deklarieren, weiss aber noch nicht genau wie.
Habt Ihr Ideen dazu?

himitsu 13. Jun 2012 10:53

AW: Herausfinden ob Breakpoint ist oder nicht - Wie?
 
Du hast doch Zahlen, wieso willst du da Strings vergleichen?


- Fasse doch erstmal die Bedingungen in kurze Sätze. (hast du schon, ber mehr so im rießigen Text verteilt)
- gruppiere diese (Teil)Sätze ordentlich, nach ihren Zusammenhängen
- wandle alle Sätze in Formeln um
- und fertig

Zitat:

Breakball ist immer,
wenn der Aufschlagsempfänder 40 Punkte
oder
Vorteil hat
und
der Aufschlagende weniger Punkte als der andere hat.
A = Aufschlagende
B = Aufschlagsempfänder

Delphi-Quellcode:
Breakball :=
(
  (PunkteB = 40)
  or
  ( was war nochmal vorteil? )
)
and
(PunkteA < PunkteB)
;
oder, da ich in deinem Satz nicht erkennen konnte, wie die Zusammenhänge sind, bzw. wie die Klammersetzung wäre. :stupid:
[edit] ich glaub Ersteres klingt besser/richtiger [/edit]
Delphi-Quellcode:
Breakball :=
(PunkteB = 40)
or
(
  ( was war nochmal vorteil? )
  and
  (PunkteA < PunkteB)
)
;

torud 13. Jun 2012 10:58

AW: Herausfinden ob Breakpoint ist oder nicht - Wie?
 
Hallo,

folgende Punkte gibt es:

0,15,30,40

Mit dem folgenden Punkt erhält ein Spieler den Spielpunkt, wenn der andere < 40 Punkte hat.

Folgende Breakballsituation gibt es:

Aufschlag hat Spieler A
Spielstand ist A - B
0 - 40 -> 3 breakbälle B*
15 - 40 -> 2 breakbälle B*
30 - 40 -> 1 breakball B*
40 - 40 -> 0 breakbälle B
40 - A -> 1 breakball B*

* Macht Spieler B den nächsten Punkt, gewinnt er das Spiel

Aufschlag hat Spieler B
Spielstand ist A - B
40 - 0 -> 3 breakbälle A*
40 - 15 -> 2 breakbälle A*
40 - 30 -> 1 breakball A*
40 - 40 -> 0 breakbälle A
A - 40 -> 1 breakball A*

* Macht Spieler A den nächsten Punkt, gewinnt er das Spiel

Wichtig ist also, WER Aufschlag hat.

Da es zu einer Vermischung von Datentypen kommt (0,15,30,40,A), dachte ich, dass es vielleicht sinnvoll wäre einen eigenen Datentypen einzusetzen.

Ich hoffe, das macht es leichter, die Breakball-Situation einzuschätzen.

BUG 13. Jun 2012 11:06

AW: Herausfinden ob Breakpoint ist oder nicht - Wie?
 
Zitat:

Zitat von torud (Beitrag 1170622)
Ich hatte über einem eigenen Typen nachgedacht, weil es Punkte 0,15,30 und 40 gibt und der Vorteil als A (wie Advantag) kommt. Es liegt hier also eine Vermischung von Datentypen vor.

Was du vermutlich suchst, sind zusammengesetzte Datentypen:
Delphi-Quellcode:
type
  TTennisMatchPunktZahlDingens = record
    punkte: integer;
    advantag: boolean;
  end.
Wenn du dir überlegst, welche Datentypen du zur Laufzeit benutzt, dann ist "Ich packe einfach alles in einen String." fast immer die falsche Entscheidung.

torud 13. Jun 2012 11:17

AW: Herausfinden ob Breakpoint ist oder nicht - Wie?
 
Ich hatte vermutet, dass so was hier aus SInn machen könnte:

Delphi-Quellcode:
TMatchStatus = (p0, p15, p30, p40, pA);
Aber wenn ich´s wüsste, hätte ich nicht gefragt.

Aphton 13. Jun 2012 13:58

AW: Herausfinden ob Breakpoint ist oder nicht - Wie?
 
Nur aus Neugier:
Wenn einer Breakball hat, jedoch die Runde verliert, ists dann (sozusagen) wieder Gleichstand? Dh. kann man nur gewinnen, wenn man bei einem Breakball punktet?

A - B - (* Breakball)
30 - 40* - B punktet, gewinnt Match/Runde
30 - 40* - A punktet -> neuer Stand:
40 - 40 - A punktet nochmal -> ...
40* - 40 - entweder A punktet und gewinnt oder B punktet (neuer Stand:)
40 - 40

läuft das so ständig hin und her?

torud 13. Jun 2012 14:32

AW: Herausfinden ob Breakpoint ist oder nicht - Wie?
 
Hallo,

hier mal ein möglicher Verlauf:

* schlägt auf

A* - B
0 - 15 durch Punkt B
0 - 30 durch Punkt B
0 - 40 = 3BP durch Punkt B
15 - 40 = 2BP durch Punkt A
30 - 40 = 1BP durch Punkt A
40 - 40 = Einstand durch Punkt A
40 - A = Vorteil B = 1BP Punkt durch B
40 - 40 = Einstand nach Punkt durch A
A - 40 = Vorteil A nach Punkt A

Der Spielpunkt könnte vergeben werden, wenn B bei Breakball einen weiteren Punkt macht. Dann erhält B einen Spieltpunkt und die Gamepunkte werden wieder auf 0 resetet.
Der Spielpunkt kann auch vergeben werden, wenn A einen Punkt macht und es A - 40 steht. In dem Falle liegt aber keine Breakball vor, da ein BP nur der Aufschlagsemüfänger haben kann. Kann ein Aufschlagender Spieler einen Spielpunkt mit dem nächsten Punkt erringen, nennt man das Spielpunkt.

Der Wechsel von 40 - 40 nach A - 40 oder 40 - A kann ewig hin und her gehen. Solange, bis einer den entscheidenden Punkt macht.

Ein zu 0-Spiel würde so verlaufen.

Stand Spiele = 0-0

A schlägt auf
0 - 0 danach Punkt A
15 - 0 danach Punkt A
30 - 0 danach Punkt A
40 - 0 danach Punkt A

Stand Spiele = 1-0
aktueller Stand im nachfolgenden Spiel ist wieder 0-0

Aphton 13. Jun 2012 14:46

AW: Herausfinden ob Breakpoint ist oder nicht - Wie?
 
Ok, glaube es verstanden zu haben. Liefere demnächst ein Codefetzen...

Luckie 13. Jun 2012 14:52

AW: Herausfinden ob Breakpoint ist oder nicht - Wie?
 
Argh, hättest du das Wort Tennis nicht am Anfang gleich nennen können? Ich habe mich die ganze Zeit gefragt, von was du da überhaupt redest. Erst als du die Regeln erklärt hast, habe ich verstanden um was es eigentlich geht.

Sagt man bei 40:40 nicht eigentlich Deuce?

Aber lös dich doch mal von den krummen Punkten vom Tennis:

0 entspricht 0
15 entspricht 1
30 entspricht 2
40 entspricht 3

Steht es also 0:40 im Tennis hast du 0:3 -> 3-0=3 Breakpunkte.
steht es 15:40 im Tennis hast du 1:3 -> 3-1=2 Breakpunkte.

Wenn du jetzt den Datentyp Enum nimmst kannst du mit den Ordinalwerten der Einträge rechnen. So meine Idee. Eine konkrete Umsetzung mit Code kann ich dir leider nicht anbieten.

Aphton 13. Jun 2012 14:56

AW: Herausfinden ob Breakpoint ist oder nicht - Wie?
 
Delphi-Quellcode:
type
  TTennisPunkte = (tp0 = 0, tp15 = 15, tp30 = 30, tp40 = 45, tpA = 60); // in 15er Schritten, da es programmintern evt. besser zu handhaben ist
  PTennisSpieler = ^TTennisSpieler;
  TTennisSpieler = record
    Punkte: TTennisPunkte;
    Aufschlag: Boolean;
    {...}
  end;

function istBreakBall(SpielerA, SpielerB: TTennisSpieler): Boolean;
  { Zitat
      Breakball ist immer, wenn der Aufschlagsempfänder 40 Punkte oder Vorteil hat
      und der Aufschlagende weniger Punkte als der andere hat. Bei 0 - 40 hätte
      man zum Beispiel 3 Breakballe, weil man 3 mal die Chance hat mit dem
      nächsten Punkt das Spiel zu gewinnen.
  }
var
  Aufschlagender, AufschlagEmpfänger: PTennisSpieler;
begin
  if not (SpielerA.Aufschlag xor SpielerB.Aufschlag) then
    raise Exception.Create('Ungültige Aufschlagsituation.');
  if SpielerA.Aufschlag then
  begin
    Aufschlagender := @SpielerA;
    AufschlagEmpfänger := @SpielerB;
  end else
  begin
    Aufschlagender := @SpielerB;
    AufschlagEmpfänger := @SpielerA;
  end;
  Result := (AufschlagEmpfänger.Punkte >= tp40) and (Aufschlagender.Punkte < AufschlagEmpfänger.Punkte);
end;

torud 14. Jun 2012 12:30

AW: Herausfinden ob Breakpoint ist oder nicht - Wie?
 
Hallo,

und sorry für das späte Feedback!

Vielen Dank für Deine Mühe. Ich bau´s mal bei mir ein und teste es. Ich melde mich dann mit einem abschließenden Feedback.

himitsu 14. Jun 2012 13:58

AW: Herausfinden ob Breakpoint ist oder nicht - Wie?
 
Zitat:

Zitat von Aphton (Beitrag 1170682)
Delphi-Quellcode:
TTennisPunkte = (tp0 = 0, tp15 = 15, tp30 = 30, tp40 = 45, tpA = 60); // in 15er Schritten, da es programmintern evt. besser zu handhaben ist

Dann doch besser ohne Nummernwerte ... lieber "keine" Werte, als "falsche" Werte.

Delphi-Quellcode:
TTennisPunkte = (tp0, tp15, tp30, tp40, tpA);

PS: Bei ENUMs mit vordefinierten Werten gibt es keine Namen in der RTTI ... man kann sich sowas leider nie wieder in Strings umwandeln lassen :cry:

Aphton 15. Jun 2012 14:23

AW: Herausfinden ob Breakpoint ist oder nicht - Wie?
 
Aha? Nun, ich bin immer den umständlichen Weg gegangen und habe es so gemacht:

Delphi-Quellcode:
type
  TTennisPunkte = (tp0 = 0, tp15 = 15, tp30 = 30, tp40 = 45, tpA = 60);

const
  strTennisPunkte: Array[TTennisPunkte] of String = ('0', '15', '30', '40', 'A');
Ist hässlich, jedoch ists kaum schöner mit RTTI (RTTI - sofern ich das richtig in Erinnerung habe - bläst sie ja die Echsen so auf..)

DeddyH 15. Jun 2012 14:30

AW: Herausfinden ob Breakpoint ist oder nicht - Wie?
 
Tröste Dich, ich mache das auch oft so. Das kommt ohne RTTI aus und ist noch einigermaßen übersichtlich und somit IMO verständlich.

Aphton 15. Jun 2012 14:35

AW: Herausfinden ob Breakpoint ist oder nicht - Wie?
 
Danke, ist beruhigend zu wissen, dass Pros das auch so machen =P
Aber unschön finde ichs trotzdem =/

DeddyH 15. Jun 2012 15:09

AW: Herausfinden ob Breakpoint ist oder nicht - Wie?
 
Was findest Du daran unschön? Wenn man auf RTTI verzichten will, könnte man das auch mit einer case-Abfrage in einer Funktion machen und auf die Konstante verzichten.
Delphi-Quellcode:
type
  TMeinTyp = (mtEins, mtZwei, mtDrei);

function TMyClass.GetTypeAsString(Typ: TMeinTyp): string;
begin
  case Typ of
    mtEins:
      Result := 'Typ Eins';
    mtZwei:
      Result := 'Typ Zwei';
    else
      Result := 'Typ Drei';
  end;
end;
Aber: wenn man den Typ einmal erweitert, weil ein neuer Zustand hinzugekommen ist, darf man nicht vergessen, die Funktion auch zu erweitern. Dem Compiler ist das schnurz, ob sie im Fall des neuen Zustandes auch das richtige Ergebnis liefert. Hat man aber wie von Dir gezeigt eine entsprechende Array-Konstante deklariert, muss diese im genannten Fall auch erweitert werden, sonst wird nicht kompiliert, da das Array nicht die richtige Elementanzahl aufweist.

Delphi-Quellcode:
type
  TMeinTyp = (mtEins, mtZwei, mtDrei);

const
  MYTYPESTRINGS: array[TMeinTyp] of string = ('Typ Eins', 'Typ Zwei', 'Typ Drei');

function TMyClass.GetTypeAsString(Typ: TMeinTyp): string;
begin
  Result := MYTYPESTRINGS[Typ];
end;
Ist doch prima, so kann man sich vor der eigenen Schusseligkeit schützen.

Aphton 15. Jun 2012 15:15

AW: Herausfinden ob Breakpoint ist oder nicht - Wie?
 
Klar, deshalb mache ich das ja auch so.. Nur kommt mir eine weitere (Hilfs-)Definition ein bisschen redundant vor.

torud 16. Jun 2012 13:40

AW: Herausfinden ob Breakpoint ist oder nicht - Wie?
 
Hallo,

ich klink mich mal wieder hier ein. Die Funktion funzt prima. Leider habe ich vergessen zu erwähnen, dass ich die Funktion auch für isSetPoint oder isMatchPoint benutzen will.

Dafür muss ich sicher eine andere funktion erstellen. Ich habe das mit den beiden Funtkionen schon hinbekommen, hadere aber noch ein wenig mit der Tiebreak-Situation.

In diesem Sonderfall, gibt es ja keine 0,15,30,40,A mehr, sondern es wird immer in 1er-Schritten gezählt und wartet, bis einer der Spieler 7 Punkte und mindesten eine Differenz von 2 Punkten hat.

Tiebreak kommt immer dann zum Einsatz, wenn der Spielstand in einem Satz 6-6 ist.
Dann wird für das kommende Spiel der Spieltstand auf 0-0 gesetzt.

Macht einer der Spieler einen Punkt, erhält der dafür einen Punkt und es steht 1-0.
Das geht dann immer weiter, bis es zb. 6-0 steht. Dann hat der Spieler mit den 6 Punkten 6 Satzbälle, weil die 6 mal die Chance hat seinen 7. Punkt zu erreichen.
Würde der andere Spieler in dem konstruierten Fall 6 Punkte aufholen, müsste mindesten für 2 weitere Punkte weiter gespielt werden. Alco bis es z.b. 8-6 steht. Das kann rein theoretisch ewig so weitergehen. Rekord war letztes Jahr in Wimbledon, als 2 Spieler fast 2 Tage den letzten Satz bis ca. 55-53 gespielt haben.

Nun die Frage. Ich kann ja nicht für alle Fälle so einen Riesen Enum aufbauen. Wie kann man dieses Problem lösen?

Aphton 16. Jun 2012 14:46

AW: Herausfinden ob Breakpoint ist oder nicht - Wie?
 
Ich weiß momentan nicht, ob es derselbe Spielmodus ist oder etwas ganz anderes.. für den Fall dass es derselbe ist, wäre folgendes machbar:
Delphi-Quellcode:
type
  TTennisPunkte = (tp0 = 0, tp15 = 15, tp30 = 30, tp40 = 45, tpA = 60, tp5 = 75, tp6 = 90, tp7 = 105);

var
  tp: TTennisPunkte
nun liefert dir Ord(tp) div 15 die Werte 0, 1, 2, ..., 7

Edit: Ansonsten steck dahinter mehr oder weniger dieselbe Logik - außer dass man, sobald es zum Tiebreak kommt, alles reseten muss..

Edit2: Ahh.. interessante Spiellogik.
Zum Tiebreak kann es doch auch kommen, wenn die Punkte weit über 6 sind und es ein Tie gibt, nicht? Dh. es muss min. solange gepielt werden, bis man 6 erreicht und ab da, sobald es zum Tie kommt, werden die Punkte zurückgesetzt und alles beginnt von vorne (sorgt dafür, dass wieder min 6 Punkte erreicht werden müssen)
Da es ein anderer Spielmodus ist (nicht?) würde ich da auch nen anderen EnumTyp verwenden Verwende einfach eine Zahl für den Score, kein Enum

torud 16. Jun 2012 17:19

AW: Herausfinden ob Breakpoint ist oder nicht - Wie?
 
Genau,

steht es 6-6 Games muss ein weiteres Spiel gespielt werden, um einen Satzgewinner zu ermitteln.

IN dem noch zu absolvierenden Spiel, wird anders gezählt - in Einer-punkten.

Wer zuerst mind. 7 Punkte und mind. 2 Punkte mehr als der Gegner hat, hat das Spiel und damit den Satz gewonnen.
Der Satz endet dann in der Regel mit 7/6 oder 6/7. Steht dahinter noch eine Zahl in Klammern, ist das in der Regel der Punktestand des Verlierers im Tiebreak.

Also sowas hier 7/6 (2) bedeutet, dass Spieler A den Tiebreak (das letzte Spiel eines Satzes bei Stand von 6/6) mit 7 / 2 gewonnen hat.

Also zusammenfassend kann man sagen, dass Satz- oder Matchball ist, wenn
Spieler A Games im aktuellen Satz > 5 hat und Spieler B Games < 6 UND Spieler A 40 Punkte oder Vorteil hat und Spieler B 40 Punkte oder weniger hat.
Haben beide Spieler 6 Games, muss einer von beiden wenigstens 6 Punkte und der andere max. 5 Punkte haben. Der Mindestabstand von Punkten muss 2 betragen und man benötigt mind. 2 Punkte

Ich grübel mal, dass sollte sich eigentlich auch über ne if then else machen lassen. Sieht nicht schön aus, aber sollte gehen.

himitsu 16. Jun 2012 18:06

AW: Herausfinden ob Breakpoint ist oder nicht - Wie?
 
Zitat:

Delphi-Quellcode:
type
  TTennisPunkte = (tp0 = 0, tp15 = 15, tp30 = 30, tp40 = 45, tpA = 60);

const
  strTennisPunkte: Array[TTennisPunkte] of String = ('0', '15', '30', '40', 'A');

Hast du das mal ausprobiert?

Ich bin mir ganz sicher, daß es so nicht funktioniert, denn das Array wird 61 Felder groß sein und nicht nur 5. :angle2:



Das ist auch der Grund, warum es keine RTTI dafür gibt, da man irgendwie immernoch nicht auf die Idee gekommen ist, dort einfach mit DummyWerten aufzufüllen.

Aphton 16. Jun 2012 18:11

AW: Herausfinden ob Breakpoint ist oder nicht - Wie?
 
Nöp, danke.
Ginge aber ohne Zuweisungen..

BUG 17. Jun 2012 13:04

AW: Herausfinden ob Breakpoint ist oder nicht - Wie?
 
Auch wenn das nicht (ganz) zu den bisherigen Lösungen passt: Es wäre eigentlich sinnvoll den Spielzustand explizit als Zustandsautomaten zu modellieren und dazu noch die Punkte zählen. Dann wird das nicht so eine Frickelei.

Das Ganze könnte man auch gut in eine Klasse kapseln.

Furtbichler 18. Jun 2012 07:37

AW: Herausfinden ob Breakpoint ist oder nicht - Wie?
 
Ich würde mich von der Aussprache ('0','15','30','40', 'Vorteil') freimachen, denn das ist die Darstellung. Und was haben wir gelernt? Genau, Darstellung und Funktion trennen.

Also wird beim Tennis einfach von 0 beginnend nach oben gezählt.
Wer zuerst 4 Punkte hat und mindestens 2 Punkte mehr als der andere, hat den Punkt, oder wie das heißt.

Die Anzahl der Breakpoints ist also PunktB-PunktA, wenn PunktB >= 3 und 0 sonst.

Und? Wieviel stehts?
Delphi-Quellcode:
Function SpielStand (PunkteA, PunkteB : Integer) : String;
Const
  PunkteName : Array [0..3] of string = ('00','15','30','40');
 
Begin
  if (PunkteA<=3) and (PunkteB<=3) Then
  if PunkteA = PunkteB then
    Result := PunkteName[PunkteA]+' beide'
  else
    Result := PunkteName[PunkteA]+'-'+PunkteName[PunkteB]
  else if PunkteA > PunkteB + 1 Then
    Result := 'Punktgewinn A'
  else if PunkteB > PunkteA + 1 Then
    Result := 'Punktgewinn B'
  else if PunkteA > PunkteB Then
    Result := 'Vorteil A'
  else if PunkteB > PunkteA Then
    Result := 'Vorteil B'
  else
    Result := 'Gleichstand'
 
End;


Alle Zeitangaben in WEZ +1. Es ist jetzt 20: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