AGB  ·  Datenschutz  ·  Impressum  







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

Neue Komponente mit 2 TEdit Komponenten

Ein Thema von Optiplex · begonnen am 28. Mai 2009 · letzter Beitrag vom 15. Jun 2009
Antwort Antwort
Seite 4 von 5   « Erste     234 5      
oki

Registriert seit: 30. Dez 2002
Ort: Brandshagen
1.819 Beiträge
 
Delphi 2007 Professional
 
#31

Re: Neue Komponente mit 2 TEdit Komponenten

  Alt 5. Jun 2009, 11:41
Also, ich hab noch mal nachgedacht. Du solltest die PlayList nicht den Playern zuordnen, sondern die Player den PlayClasses. Das macht mehr Sinn.

Wenn du Hilfe bei der Erstellung der Klassen brauchst sag bescheid, dann mach ich das (brauch mal ne kleine Ablenkung mit ner leichten Aufgabe).

Gruß oki
42
  Mit Zitat antworten Zitat
Optiplex

Registriert seit: 5. Mär 2008
131 Beiträge
 
Delphi 2005 Personal
 
#32

Re: Neue Komponente mit 2 TEdit Komponenten

  Alt 5. Jun 2009, 13:12
Puuu Oki, das ist harte Kost für mich.
Mit Klassen habe ich mich noch nicht so viel beschäftigt und kenne deren Vor- und Nachteile überhaupt nicht. Ich habe auch noch nicht geschnallt, wie du das mit den Verknüpfungen, wann und wo welcher spieler weiterspielt oder ausscheidet über die Klassen regeln willst. Das mit einer kompletten Teilnehmerliste ist OK die hätte ich sowieso gebraucht auch schon wegen der eventuellen Namensänderung.

Du schreibst das so als wäre das alles kein Problem. Für mich sind da ein paar böhmische Dörfer schon dabei, werde allerding versuchen mich am Wochenende schlau zu machen, und wie gesagt fehlen dir noch ein paar Infos die ich am Wochenende zusammenschreiben werde, nur damit du nicht unnötig zeit investierst und sagst das hättest du mir gleich sagen sollen.

Datenmodel erstellen ? wie ? aber ich bin lernbereit, denn wie gesagt ich bin Hobbyprogrammierer.

Leider habe ich am Wochenende kein Inet, es kann daher sein, dass ich mich erst am Montag wieder melde.(bin aber heute bis 16 Uhr erreichbar und schaue nochmal hier vorbei.

Zitat von oki:
Vertrau mir, ich wies was ich tu( kennst du den Spruch? stammt aus einer alten Serie)
Den Spruch kenne ich, weis nur die Serie nicht mehr.

Gruss Dieter
  Mit Zitat antworten Zitat
oki

Registriert seit: 30. Dez 2002
Ort: Brandshagen
1.819 Beiträge
 
Delphi 2007 Professional
 
#33

Re: Neue Komponente mit 2 TEdit Komponenten

  Alt 5. Jun 2009, 13:37
Slatch Hammer (ob richtig geschrieben, keine Ahnung?), das war der Bulle, der in seine Knarre verliebt war und ständig mit der rumgeballert hat (z.B. Fliegen von der Wand ).
das zum wichtigen Teil der der Nachricht.

So, nun zum Datenmodell. das ist gar nicht so schwer. Fangen wir mal ganz vorne an; die Player.

Hier mal auf die Schnelle die Klassen für die Spieler und die Spielerliste. Alle Funktionen für die Statistiken usw. die direkt die Spieler betreffen generieren wir dann in der PlayerList.

Delphi-Quellcode:
unit Player_Classes;

interface

type
  // Forward
  TPlayerList = class;

  // Der ShowMode definiert, wie der Name des Spielers ausgegeben wird
  TShowNameMode = (snm_FullName,         // Vorname und Name anzeigen
                   snm_Name,               // nur Nachname anzeigen
                   snm_ShortFirstName // Vorname abgekürzt, Nachname voll
                   );

 (*
  Klasse eines einzelnen Spielers. Der Member PlayerList gibt die übergeordnete Liste
  an, die den Spieler hält.
*)

  TPlayerClass = class(TObject)
  private
    FBirthday: TDateTime;
    FFirstName: String;
    FName: String;
    FPlayerList: TPlayerList;
    FShowNameMode: TShowNameMode;
    function GetFullName: String;
    procedure SetBirthday(const Value: TDateTime);
    procedure SetFirstName(const Value: String);
    procedure SetName(const Value: String);
    procedure SetShowNameMode(const Value: TShowNameMode);
  public
    property PlayerList : TPlayerList read FPlayerList write FPlayerList;

    property Birthday : TDateTime read FBirthday write SetBirthday;
    property FirstName : String read FFirstName write SetFirstName;
    property Name : String read FName write SetName;
    property ShowNameMode : TShowNameMode read FShowNameMode write SetShowNameMode;

    property FullName : String read GetFullName;
  end;

  TPlayerList = class(TObjectList)
  private
  protected
     function GetItem(Index: Integer): TPlayerClass;
     procedure SetItem(Index: Integer; AObject: TPlayerClass);
  public
     function Add(AObject: TPlayerClass): Integer;
     function Extract(Item: TPlayerClass): TPlayerClass;
     function Remove(AObject: TPlayerClass): Integer;
     function IndexOf(AObject: TPlayerClass): Integer;
     procedure Insert(Index: Integer; AObject: TPlayerClass);
     function First: TPlayerClass;
     function Last: TPlayerClass;

    procedure PlayerChanged;

     property Items[Index: Integer]: TPlayerClass read GetItem write SetItem; default;
  end;

implementation

{ TPlayerClass }

function TPlayerClass.GetFullName: String;
begin
  case FShowNameMode of
    snm_FullName: Result := Format('%s %s', [FFirstName, FName]);
    snm_Name: Result := FName;
    snm_ShortFirstName: Result := Format('%s. %s', [FFirstName[1], FName]);
  end;
end;

procedure TPlayerClass.SetBirthday(const Value: TDateTime);
begin
  if FBirthday = Value then
    Exit;
  FBirthday := Value;
  if Assigned(FPlayerList) then
    FPlayerList.PlayerChanged;
end;

procedure TPlayerClass.SetFirstName(const Value: String);
begin
  if FFirstName = Value then
    Exit;
  FFirstName := Value;
  if Assigned(FPlayerList) then
    FPlayerList.PlayerChanged;
end;

procedure TPlayerClass.SetName(const Value: String);
begin
  if FName = Value then
    Exit;
  FName := Value;
  if Assigned(FPlayerList) then
    FPlayerList.PlayerChanged;
end;

procedure TPlayerClass.SetShowNameMode(const Value: TShowNameMode);
begin
  if FShowNameMode = Value then
    Exit;
  FShowNameMode := Value;
  if Assigned(FPlayerList) then
    FPlayerList.PlayerChanged;
end;

{ TPlayerList }

function TPlayerList.Add(AObject: TPlayerClass): Integer;
begin
  AObject.FPlayerList := self;
  Result := inherited Add(AObject);
end;

function TPlayerList.Extract(Item: TPlayerClass): TPlayerClass;
begin
  Result := TPlayerClass(inherited Extract(Item));
  result.FPlayerList := nil;
end;

function TPlayerList.First: TPlayerClass;
begin
  Result := TPlayerClass(inherited First);
end;

function TPlayerList.GetItem(Index: Integer): TPlayerClass;
begin
  Result := TPlayerClass(inherited GetItem(Index));
end;

function TPlayerList.IndexOf(AObject: TPlayerClass): Integer;
begin
  Result := inherited IndexOf(AObject);
end;

procedure TPlayerList.Insert(Index: Integer; AObject: TPlayerClass);
begin
  AObject.FPlayerList := self;
  inherited Insert(Index, AObject);
end;

function TPlayerList.Last: TPlayerClass;
begin
  Result := TPlayerClass(inherited Last);
end;

{-----------------------------------------------------------------------------
  Procedure:  PlayerChanged
  Author:      Dipl. Ing. Olaf Keitsch
  Date:        05-Jun-2009
  Arguments:  None
  Result:      None
  Describtion: Diese Methode wird von den Settern der Player aufgerufen. An dieser
              Stelle kann die Aktualisierung des anzeigenden Controls aufgerufen werden.
-----------------------------------------------------------------------------}

procedure TPlayerList.PlayerChanged;
begin
  // do it
end;

function TPlayerList.Remove(AObject: TPlayerClass): Integer;
begin
  AObject.FPlayerList := nil;
  Result := inherited Remove(AObject);
end;

procedure TPlayerList.SetItem(Index: Integer; AObject: TPlayerClass);
begin
  AObject.FPlayerList := self;
  inherited SetItem(Index, AObject);
end;

end.
Alles, was die Spiele betrifft kommt dann in die PlayList. Das später.
In der Klasse PlayerList kannst du jetzt in den Propertys noch ergänzen, was du direkt zu den Spielern an Angaben erfassen willst. Hier kommt aber nichts zu den Spielen rein.

Gruß oki
42
  Mit Zitat antworten Zitat
Optiplex

Registriert seit: 5. Mär 2008
131 Beiträge
 
Delphi 2005 Personal
 
#34

Re: Neue Komponente mit 2 TEdit Komponenten

  Alt 5. Jun 2009, 15:33
Hallo Oki,
Mensch du bist schneller als die Polizei erlaubt, hast du das alles fertig in der Schublade? Hab dir schnell mal zusammengeschrieben, damit du alle Infos hast die du brauchst.

Da ein Dart Event aus mehreren Turnieren (Einzel Doppel in den jeweiligen Klassen) besteht die meist gleichzeitig laufen, habe ich mich entschlossen einen Eventmanager (Eigenständiges Programm) zu programmieren

Im Manager sollen alle wichtigen eingaben die alle Turniere Betreffen erfolgen

-Eingabe der Anzahl der vorhandenen Automaten
-Sperrung eines Automaten
-Eingabe der Spieler zum jeweiligen Turnier
-starten eines Turniers (eigenständiges Programm je nach Anzahl der Spieler hier sind wir gerade mit unserer Komponente.)
-unterbrechen eines Turniers
-Turnier wieder aufnehmen.
-ein Spieler gibt auf weil er dringend weg muss dann soll der Spieler an allen Turnieren an denen er angemeldet ist praktisch als Freilos weitergeführt werden, bis das Freilos ausgeschieden ist.

Alles was alle Turniere betrifft wird in einer zentralen Datei gespeichert. hier rufen die einzelnen Turniere ihre Daten ab oder schreiben hinein. Ist wichtig bei Stromausfall, damit der Event an diesem Punkt weitergeführt werden kann. (sonst kann es passieren dass eine Horde über mich herfällt)

Ablauf Erstellung eines Events

Eingabe der Anzahl der vorhandenen Automaten
Eingabe des Event namens = Dateiname der Ini
Speicherung des Events in einem Verzeichnis. Anlegen einer INI - Datei mit den Grundeinstellungen

Belegung der Automaten (Überwachung)
jeder Automat an dem gespielt wird muss als belegt gekennzeichnet werden, damit er zur Auswahl in den Turnieren nicht mehr zur Verfügung steht.

Automatenausfall
Es muss möglich sein einen Automaten zu sperren (defekt) wird gerade dort gespielt muss eine Info zur Partie gehen, damit dort ein neuer Automat ausgewählt werden kann.

Freilose(Überwachung)
ist eine Partie mit einem Freilos komplett so wird sofort das Freilos als Verlierer gewertet und wird dementsprechend weitergereicht bzw. scheitet aus dem Turnier aus.

Spieler spielt bereits in einem anderen Turnier (Überwachung)
Jeder Spieler der gerade eine Partie spielt muss gekennzeichnet werden, damit er nicht nochmals zu einer Partie aufgerufen werden kann.

Ein Spieler beendet vorzeitig das Turnier.
gibt ein Spieler das Turnier vorzeitig auf so wird er ab dieser Runde behandelt wie ein Freilos.

So nun hast du denke ich alle Infos die du brauchst. Ich hab dir ja gesagt dass das ganze ziemlich komplex ist. (Hoffentlich habe ich dich jetzt nicht verjagt)
Wenn du willst kannst du dir ja ein Paar Gedanken machen.

Ich werde mich mal mit deinen Klassen beschäftigen, scheint auf den zweiten Blick die Lösung für einige Probleme zu sein, bin aber noch nicht ganz durchgestiegen.

Richtig ! An die Serie kann ich mich noch erinnern.

Gruss bis Montag Dieter.
  Mit Zitat antworten Zitat
oki

Registriert seit: 30. Dez 2002
Ort: Brandshagen
1.819 Beiträge
 
Delphi 2007 Professional
 
#35

Re: Neue Komponente mit 2 TEdit Komponenten

  Alt 5. Jun 2009, 16:32
Hallo Dieter,

Dank für deine Erläuterungen. Bin zwar noch nicht ganz durchgestiegen bei den Themen Automaten, Events usw., fehlt mir die Praxis. Trotzdem sehe ich das alles nicht so wild. Entscheidend ist hier einfach nur der intelligente Klassenaufbau für die Spiele. Da hab ich das Thema Turniere usw. noch nicht ganz geschnallt. Vorallem die Abhängikeiten usw. Das ignoriere ich jetzt aber mal geflissentlich. Hat in der Ebene in der wir gerade stecken wohl noch keine Auswirkungen. Ich versuche gerade herauszubekommen, was wir alles für die PlayClass an Eigenschafen brauchen. Auf deutsch, was ist alles für ein Spiel (Paar) an Informationen relevant. Die beiden Spieler ist sicher klar. Dann der Spielstand. Was gehört noch alles zu einem Spiel? Der Automat vielleicht? Da musst du mal paar Angaben machen. Die PlayList hält dann zwar die einzelnen Spiele eines Turniers (denke ich), muss dann aber sicher noch einige Funktionen haben. Da musst du wieder helfen.
Ich hatte mir das Händling dafür so vorgestellt. Die PlayList hält die PlayClass'es. wird in einer PlayClass ein Spielstand gespeichert, so wird die Playlist davon informiert (so wie das mit den Änderungen bei den Playern). Dabei wird dann aber das PlayObject mitgeliefert (Methode ChangePlayClass der PlayList). Das die PlayList dann weis, in welchem Spiel sich der Spielstand wie geändert hat, kann sie automatisch ermitteln, in welche weiteren Play-Objekte seiner Liste die entsprechenden Spieler eingetragen werden müssen. Ein Status für das entsprechende Spiel zum Sperren usw. kann dann die Playlist mit vergeben. Dazu kann man der PlayClass eine entsprechende Eigenschaft verpassen. Das alles ist schon mit Sicht auf die spätere Anzeige gedacht. Da machen sich solche Statusflags immer toll um die Anzeige anzupassen.

Naja, ich denk mir da mal was aus.

bis die Tage,

Gruß oki
42
  Mit Zitat antworten Zitat
oki

Registriert seit: 30. Dez 2002
Ort: Brandshagen
1.819 Beiträge
 
Delphi 2007 Professional
 
#36

Re: Neue Komponente mit 2 TEdit Komponenten

  Alt 7. Jun 2009, 11:03
Hi,

ich hab mal die Klassen für die Spieler, Spielerliste, Spiele und Spielliste fertig gestellt. Leider hab ich das System für den Eintrag eines Spielers in ein neues Spiel noch nicht ganz durchschaut. Für die Gewinner ist das ja recht einfach. Bei den Verlierern hab ich da so meine Probleme. Ich pack hier mal die Procedure rein.
Delphi-Quellcode:
procedure TPlayList.ChangePlay(APlayClass: TPlayClass; AProperty : String);
var AWinner, ALooser : TPlayerClass;

  procedure PlayerinGame(APlayer : TPlayerClass; AOldPlay : TPlayClass; winning : Boolean);
  var NewPlay : TPlayClass;
  begin
    if winning then begin
      // Spieler ist Gewinner des alten Spieles
      case ORD(AOldPlay.FGame) of
        ORD('R') : begin
          // Gewinner der ersten Runde
          if Odd(AOldPlay.Number) then begin
            NewPlay := GetPlay('G', 1, (AOldPlay.Number+1) div 2);
            if Assigned(NewPlay) then
              NewPlay.FPlayer1 := APlayer;
          end else begin
            NewPlay := GetPlay('G', 1, (AOldPlay.Number) div 2);
            if Assigned(NewPlay) then
              NewPlay.FPlayer2 := APlayer;
          end;
        end;
        ORD('G') : begin
          if Odd(AOldPlay.Number) then begin
            NewPlay := GetPlay('G', AOldPlay.FRound+1, (AOldPlay.FNumber+1) div 2);
            if Assigned(NewPlay) then begin
              NewPlay.FPlayer1 := APlayer;
            end else begin
              // das war das letzte Gewinnerspiel, ab ins Filale
              NewPlay := GetPlay('F', 0, 0);
              if Assigned(NewPlay) then
                NewPlay.Player1 := APlayer;
            end;
          end else begin
            NewPlay := GetPlay('G', AOldPlay.FRound+1, (AOldPlay.FNumber) div 2);
            if Assigned(NewPlay) then begin
              NewPlay.FPlayer2 := APlayer;
            end else begin
              // das war das letzte Gewinnerspiel, ab ins Filale
              NewPlay := GetPlay('F', 0, 0);
              if Assigned(NewPlay) then
                NewPlay.Player1 := APlayer;
            end;
          end;
        end;
        ORD('V') : begin
          NewPlay := GetPlay('V', AOldPlay.Round + 1, 1);
            if Assigned(NewPlay) then begin
              NewPlay.FPlayer1 := APlayer;
            end else begin
              // das war das letzte Gewinnerspiel, ab ins Filale
              NewPlay := GetPlay('F', 0, 0);
              if Assigned(NewPlay) then
                NewPlay.Player2 := APlayer;
            end;
        end;
      end;
    end else begin
      // Spieler ist Verlierer des alten Spieles
      case ORD(AOldPlay.FGame) of
        ORD('R') : begin
          // Gewinner der ersten Runde
          if Odd(AOldPlay.Number) then begin
            NewPlay := GetPlay('V', 1, (AOldPlay.Number+1) div 2);
            if Assigned(NewPlay) then
              NewPlay.FPlayer1 := APlayer;
          end else begin
            NewPlay := GetPlay('V', 1, (AOldPlay.Number) div 2);
            if Assigned(NewPlay) then
              NewPlay.FPlayer2 := APlayer;
          end;
        end;
        ORD('G') : begin
          // jo, da hab ich noch kein System entdeckt ???????????

        end;
        ORD('V') : begin
          // das wars dann, kein weiteres Spiel :-(
          // oder doch? :-) hab ich das System aber auch noch nicht durchschaut
        end;
      end;
    end;
  end;

begin
  // ein Spieler ist ein Freilos?
  if ((AProperty = 'Player1') or (AProperty = 'Player2')) and
     (Assigned(APlayClass.Player1) and Assigned(APlayClass.Player2)) and
     ((APlayClass.Player1.FPlayerType = pt_Looser) or (APlayClass.Player2.FPlayerType = pt_Looser)) then begin
    if APlayClass.Player1.FPlayerType = pt_Looser then begin
      // Player2 hat gewonnen
      AWinner := APlayClass.FPlayer2;
      ALooser := APlayClass.FPlayer1;
    end else begin
      // Player1 hat gewonnen
      AWinner := APlayClass.Player1;
      ALooser := APlayClass.Player2;
    end;
    // neues Spiel für Gewinner ermitteln
    PlayerinGame(AWinner, APlayClass, True);
    // neues Spiel für Verlierer ermitteln
    PlayerinGame(ALooser, APlayClass, False);

    // Counter der gespielten Spiele der Spieler erhöhen
    AWinner.PlayCount := AWinner.PlayCount + 1;
    ALooser.PlayCount := ALooser.PlayCount + 1;

    // aktuelle Platzierung der Spieler setzen
    AWinner.Position := FPlayerList.Count - AWinner.PlayCount;
    ALooser.Position := FPlayerList.Count - ALooser.PlayCount - 1;

    // Spielstatus auf beendet
    APlayClass.Status := ps_finish;
    Exit;
  end;

  // der Spielstand hat sich geändert
  if AProperty = 'PlayResultthen begin
    if (APlayClass.FPlayResult.Player1 <> 0) or (APlayClass.FPlayResult.Player2 <> 0) then begin
      // es gibt einen Spielstand <> 0
      if APlayClass.FPlayResult.Player1 > APlayClass.PlayResult.Player2 then begin
        // Player1 hat gewonnen
        AWinner := APlayClass.Player1;
        ALooser := APlayClass.Player2;
      end else begin
        // Player2 hat gewonnen
        AWinner := APlayClass.Player2;
        ALooser := APlayClass.Player1;
      end;
      // neues Spiel für Gewinner ermitteln
      PlayerinGame(AWinner, APlayClass, True);
      // neues Spiel für Verlierer ermitteln
      PlayerinGame(ALooser, APlayClass, False);

      // Counter der gespielten Spiele der Spieler erhöhen
      AWinner.PlayCount := AWinner.PlayCount + 1;
      ALooser.PlayCount := ALooser.PlayCount + 1;

      // aktuelle Platzierung der Spieler setzen
      AWinner.Position := FPlayerList.Count - AWinner.PlayCount;
      ALooser.Position := FPlayerList.Count - ALooser.PlayCount - 1;

      // Spielstatus auf beendet
      APlayClass.Status := ps_finish;
    end;
  end;
end;
Hier noch einige Bemerkungen zum Ablauf. Wird in einem Spiel ein Spielstand (oder eine andere Eigenschaft) geändert so ruft das Spiel die Procedure ChangePlay seiner PlayList auf und übergibt sich selbst sowie den Namen der Eigenschaft an die Procedure.
Die Procedure der PlayList macht jetzt folgendes. Erstens wird geschaut, ob der geänderte Parameter des Spiels der Spielstand oder der Typ des Spielers ist (Freilos bei Spieler). Ist ein gültiger Spielstand eingetragen, so wird der Gewinner und Verlierer des Spiels ermittelt. Dann werden diese an die Procedure PlayerinGame übergeben. Diese erhält folgender Werte:
APlayer = Spieler der in ein neues Spiel eingetragen werden soll
AOldPlay = Spiel das gerade zu Ende gespielt wurde
winning = gibt an, ob der Spieler der Gewinner oder Verlierer des Spieles ist.

Nun prüft die Procedure erst mal, welches Spiel das gerade gespielte Spiel ist, um das neue Spiel zu ermitteln, in das der aktuelle Spieler jetzt eingetragen werden soll.
Der erste Block der Abfrage für den Gewinner sollte eigentlich soweit ok sein. Keinen Plan hab ich noch für den zweiten Block, Eintrag des Verlierers. Das vorallem wenn er ein V- oder G-Spiel verloren hat.

Da die Procedure eine eigene Methode der PlayList ist, wird hier auf eigene Hilfsfunktionen zugegriffen. Das ist z.B. die Funktion GetPlay. GetPlay sucht in der Liste nach einem Spiel mit der angegebenen Bezeichnung und gibt die Instanz dieses Spieles als Ergebnis zurück. Wurde kein Spiel mit dieser Bezeichnung gefunden, so liefert die Funktion nil.
Das ergibt natürlich, dass in der Liste alle Spiele schon eingetragen sind. Erledigt wird das bei der Übergabe der Spielerliste an die PlayList. Dabei wird auf Basis der Anzahl der in der PlayerList eingetragenen Spieler der gesamte Spielplan automatisch erstellt und alle Spiele eingetragen. Das ist auch schon fertig und hat so keine großen Probleme bereitet. Hier mal diese Funktion zur Kontrolle:
Delphi-Quellcode:
procedure TPlayList.UpdatePlayCount;
var APlayerCount : Integer;
    Counter, CRound : Integer;

  procedure AddPlays(AGame : Char; ARound, ANumberCount : Integer);
  var BCounter : Integer;
  begin
    for BCounter := 1 to ANumberCount div 2 - 1 do begin
      if not Assigned(GetPlay(AGame, ARound, BCounter)) then begin
        // Spiel ist noch nicht angelegt
        Add(TPlayClass.Create(AGame, ARound, BCounter));
      end;
    end;
  end;

begin
  if not Assigned(FPlayerList) or (FPlayerList.Count = 0) then begin
    Clear;
  end else begin
    Clear;
    APlayerCount := FPlayerList.Count;
    // bei ungerade Anzahl von Spielern einen dazu
    if odd(APlayerCount) then
      inc(APlayerCount);

    // R-Spiele anlegen
    AddPlays('R', 1, APlayerCount div 2);

    // G-Spiele anlegen
    Counter := APlayerCount div 4;
    CRound := 1;
    while (Frac(Counter/2) = 0) do begin
      AddPlays('G', CRound, Counter);
      inc(CRound);
      Counter := Counter div 2;
    end;

    // V-Spiele anlegen
    Counter := APlayerCount div 4;
    CRound := 1;
    while (Frac(Counter/2) = 0) do begin
      AddPlays('V', CRound, Counter);
      inc(CRound);
      if not odd(CRound) then
        Counter := Counter div 2;
    end;

    // Finale anlegen
    Add(TPlayClass.Create('F', 0, 0));
  end;
end;
Du brauchst die Methoden hier nicht rauskopieren. Ich hab die Unit mit den Klassen schon fertig und hänge sie hier bei einem der nächsten Beiträge mit ran, dann kannst du sie dir direkt downloaden.

Ja, somit müssen wir nur noch die kleinen Probleme mit der Spielzuordnung für die Verlierer lösen und das Datenmodell ist fertig.
Dann können wir uns um den visuellen Teil kümmern.

Dann bis die Tage,

Gruß oki
42
  Mit Zitat antworten Zitat
Optiplex

Registriert seit: 5. Mär 2008
131 Beiträge
 
Delphi 2005 Personal
 
#37

Re: Neue Komponente mit 2 TEdit Komponenten

  Alt 9. Jun 2009, 15:46
hallo Oki,
ich werde versuchen dir den Ablauf zu erklären, nimm bitte dazu den Spielplan den ich hier mal an ein post von mir angehängt habe zur Hand.

R ist Runde1 hier beginnt das Turnier.
Die Anzahl der Spieler beträgt entweder 8 oder 16 oder 32 oder 64 usw., sonst funktioniert ein Doppel KO System nicht.
Die Gewinner jeder Paarung gehen in die Gewinnerrunde G1 die Verlierer in die Verliererrunde V1.
Der Gewinner der Gewinnerrunde G1 geht weiter in die Gewinnerrunde G2
der Verlierer der Gewinnerrunde G1 geht in die Verliererrunde V2 und war an die jeweilige Position A,B,C usw. (gelbes Kästchen unterhalb der Paarung) welche bei der Gewinnerrunde G1 angegeben ist (Verlierer -> A).
Der Verlierer aus der Verliererrunde V1 scheidet aus dem Turnier aus, weil er ein zweites mal verloren hat, der Gewinner der Verliererrunde V1 kommt weiter in die Verliererrunde V2 und trifft dort mit einem Verlierer aus der ersten Gewinnerrunde G1 zusammen.
Schau dir den Plan genau an, dann weist du wann ein Verlierer der Gewinnerrunde in die Verlierrunde kommt und an welcher Position er weiterspielt, den Zwischendurch gibt es auch runden bei den Paarung rein von der Verlierrunde zusammentreffen(haben kein gelbes Kasten unterhalb der Paarung).

Der Automat gehört nur bedingt zur Paarung, er ist für den eigentlichen Ablauf nicht notwendig.(praktisch nur der Spielort wo das Spiel stattfindet) sollte aber bei der paarung dabei sein wegen der Übersichtlichkeit.

Ich hoffe, dass du das nun verstanden hast, solltest du dennoch noch fragen haben, stehe ich dir gerne zur Verfügung.

bis dann Dieter
  Mit Zitat antworten Zitat
oki

Registriert seit: 30. Dez 2002
Ort: Brandshagen
1.819 Beiträge
 
Delphi 2007 Professional
 
#38

Re: Neue Komponente mit 2 TEdit Komponenten

  Alt 9. Jun 2009, 17:27
Hallo optiplex,

soweit habe ich den Spielplan verstanden. Der Punkt ist, dass es Sinn macht ein allgemeines Zuordnungsprinzip, einen Algorithmus zu finden, mit dem man mathematisch das nächste Spiel ermitteln kann. Somit wird die procedure universell und gilt für alle Anzahlen von Spielern, egal ob 8, 16, 32 usw. Man muss halt nicht für jede Anzahl von Spielern eine eigene Zuordnungsprocedure schreiben. Das habe ich versucht, bin an der erwähnten Stelle gescheitert. Da hatte ich auch noch nicht begriffen, dass das KO-System auf eine Spieleranzahl zur Basis 8 definiert ist.

Ich erkläre mal meine Vorgehensweise für den Teil den ich bis jetzt in den Griff bekommen haben (dabei war die Annahme, dass ausschließlich eine gerade Anzahl von Spielern notwendig ist).

[edit] Sorry, hier noch mal was die Eigenschaften bei TPlayClass (und somit für den Parameter APlayClass) bedeuten.
Delphi-Quellcode:
    FGame: Char; // Spiel; R, V, G
    FNumber: Integer; // Spielnummer 1..x
    FPlayer1: TPlayerClass; // Spieler 1
    FPlayer2: TPlayerClass; // Spieler 2
    FPlayList: TPlayList; // übergeordnete PlayList
    FPlayResult: TPlayResult; // Ergebnis des Spiels
    FRound: Integer; // Runde
    FStatus: TPlayState; // Spielstatus
Bsp.:
R1-2
R = Game
1 = Round
2 = Number

- = nur optischer Trenner im String.
[/edit]

In der procedure wird der Spieler der einem neuen Spiel zugeordnet werden soll, das aktuell gespielte Spiel sowie ein Flag ob der übergebene Spieler der Gewinner der Partie war übergeben:
procedure TPlayList.ChangePlay(APlayClass: TPlayClass; AProperty : String); Als erstes prüfe ich, ob der Spieler der einem neuen Spiel zugeordnet werden soll ein Gewinner ist:
Delphi-Quellcode:
    if winning then begin
      // Spieler ist Gewinner des alten Spieles
Jetzt berücksichtige ich, welches Spiel das gerade gespielte Spiel war:
Delphi-Quellcode:
      case ORD(AOldPlay.FGame) of
        ORD('R') : begin
          // Gewinner der ersten Runde
Also, der Spieler hat in einer Runde 'R' (erste Spielrunde aller Spieler) gewonnen. Anhand des Spielplanes hab ich eine recht einfache logische Folge entdeckt. Der Gewinner einer Runde "R" geht wie folgt als Spieler in ein Spiel der Runde "G" :

Gewinner aus:
R1 wird erster Spieler G1
R2 wird zweiter Spieler G1
R3 wird erster Spieler G2
R4 wird zweiter Spielr G2
.... und endlos so weiter.
Daraus folgt, das der Gewinner aller ungeraden Spielnummern für "R" immer der erste Spieler des folgenden Gewinnerspieles wird und der Gewinner mit den geraden Spielnummern für "R" immer der zweite Spieler. Die Nummer des zu ermittelnden "G"-Spieles ist immer das Ergebnis die auf eine gerade Zahl aufgerundete Spielnummer von "R" geteilt durch 2.
R-Nummer wird zur G-Nummer
1 -> 1
2 -> 1
3 -> 2
4 -> 2
.........
17 -> 9
18 -> 9
19 -> 10
20 -> 10
.........
somit entstehr folgender Code:
Delphi-Quellcode:
          if Odd(AOldPlay.Number) then begin // Gewinner einer ungeraden Spielrunde
            NewPlay := GetPlay('G', 1, (AOldPlay.Number+1) div 2); // das Spiel "G1-x" holen, wobei x gleich (y+1)/2 aus R1-y für das ungerade Spiel ist
            if Assigned(NewPlay) then
              NewPlay.FPlayer1 := APlayer; // wird Spieler 1
          end else begin // Gewinner einer geraden Spielrunde
            NewPlay := GetPlay('G', 1, (AOldPlay.Number) div 2); // // das Spiel "G1-x" holen, wobei x gleich y/2 aus R1-y für das gerade Spiel ist
            if Assigned(NewPlay) then
              NewPlay.FPlayer2 := APlayer; // wird Spieler 2
          end;
Soweit so gut. Das lässt so einfach für alle Spieler ermitteln, die Gewinner einer Runde sind, Egal ob sie vorher einmal verloren haben. Ich denke unter dieser Erläuterung sollte der Code für die gewonnenen "G" und "V"-Spiele nachvollziehbar sein, auch wenn er einer etwas anderen Logik folgt.

In den weiteren Spielrunden für "G" und "V" prüfe ich zusätzlich, ob wirklich ein neues Spiel gefunden wurde. Ist dies nämlich nicht der Fall, so ist der Gewinner ein Teilnehmer für das Finale. Da gibt es keinen Ausweg.
Delphi-Quellcode:
            if Assigned(NewPlay) then begin
              NewPlay.FPlayer1 := APlayer;
            end else begin
              // das war das letzte Gewinnerspiel, ab ins Finale
              NewPlay := GetPlay('F', 0, 0);
              if Assigned(NewPlay) then
                NewPlay.Player1 := APlayer;
            end;
Dabei ist recht einfach zu erkennen, dass der Gewinner eines "G"-Spieles der erste Spieler des Finales und der Gewinner des "V"-Spieles der zweite Spieler des Finales wird (für mich ist das aber wurscht, es bleiben eh nur zwei übrig; wer das erster oder zweiter Spieler ist scheint wohl nur für die Profis wichtig zu sein).


Soweit war das alles recht logisch. Meine Probleme fangen mit den Verlierern der "G" und "V"-Spiele an. Für die Verlierer der R-Spiele ist das so einfach wie oben beschrieben bei den Gewinnern.

Ich habe folgendes gesehen (für 16 Spieler) Verlierer des Spiels geht in Spiel:
Gx-y -> Va-b
G1-1 -> V2-4 2.Spieler
G1-2 -> V2-3 2.Spieler
G1-3 -> V2-2 2.Spieler
G1-4 -> V2-1 2.Spieler

G2-1 -> V4-2 2.Spieler
G2-2 -> V4-1 2.Spieler

G3-1 -> V6-1 2.Spieler

da steckt auch ein System dahinter. Schau mal, ob du das umgesetzt bekommst. Das sollte rein mathematisch gehen. Ein Ansatz ist, dass für 16 Spieler 4 G1 Spiele existieren, wobei das Va-b Spiel a=x*2 und b=16/4-y-1 ist. x und y entnimmt man Gx-y. Jo, so klappts.

Das ganze muss jetzt noch für die Verliererspiele ausgetüftelt werden.

Läßt sich mit dem neu ermittelten Spielnamen kein Spiel in der Spielliste finden, so ist das Turnier für diesen Spieler zu ende. Die Berechnung der Platzierung ist bei mir noch falsch, aber dazu später.

Gruß oki
42
  Mit Zitat antworten Zitat
oki

Registriert seit: 30. Dez 2002
Ort: Brandshagen
1.819 Beiträge
 
Delphi 2007 Professional
 
#39

Re: Neue Komponente mit 2 TEdit Komponenten

  Alt 9. Jun 2009, 17:36
Ähhm, das sieht jetzt aber nicht so schwer aus:
Delphi-Quellcode:
      // Spieler ist Verlierer des alten Spieles
      case ORD(AOldPlay.FGame) of
        ORD('R') : begin
          // Gewinner der ersten Runde
          if Odd(AOldPlay.Number) then begin
            NewPlay := GetPlay('V', 1, (AOldPlay.Number+1) div 2);
            if Assigned(NewPlay) then
              NewPlay.FPlayer1 := APlayer;
          end else begin
            NewPlay := GetPlay('V', 1, (AOldPlay.Number) div 2);
            if Assigned(NewPlay) then
              NewPlay.FPlayer2 := APlayer;
          end;
        end;
        ORD('G') : begin
          NewPlay := GetPlay('V', AOldPlay.Round*2, 16/4 - AOldPlay.Number - 1);
          if Assigned(NewPlay) then
            NewPlay.FPlayer2 := APlayer;
        end;
        ORD('V') : begin
          // das wars dann, kein weiteres Spiel :-(
          // oder doch? :-) hab ich das System aber auch noch nicht durchschaut
        end;
      end;
"V"-Spiele muss noch. Neu ist der Teil:
Delphi-Quellcode:
        ORD('G') : begin
          NewPlay := GetPlay('V', AOldPlay.Round*2, 16/4 - AOldPlay.Number - 1);
          if Assigned(NewPlay) then
            NewPlay.FPlayer2 := APlayer;
        end;
umgesetzt wie vorher beschrieben. Sieht irgendwie zu einfach aus.

Hab ich da was verpennt?

Gruß oki
42
  Mit Zitat antworten Zitat
Optiplex

Registriert seit: 5. Mär 2008
131 Beiträge
 
Delphi 2005 Personal
 
#40

Re: Neue Komponente mit 2 TEdit Komponenten

  Alt 10. Jun 2009, 09:19
Hallo Olaf,
das mit der Basis 8 ist falsch,
damit ein Spielplan aufgeht egal ob Doppel KO oder einfach KO benötigst du immer 2,4,8,16,32,64,128 usw spieler sonst geht das Turnier einfach nicht auf. deshaslb musst du fehlende Spieler durch Freilose ersetzen und diese Freilose must du an bestimmten stellen einsetzen damit jedes Freilos Spätestens in der 2 Verliererrund ausscheidet.
Siehe Beispiel (Anhang Plan.jpg) dies sind 12 Parungen=24 Spieler und das Turnier geht nicht auf.

Ist ein Spieler in der Verliererrunde und verliert dann ist er ausgeschieden hier kommt nur der Gewinner weiter.


Ich habe dir gleich gesagt, dass es so einfach nicht ist, wie du dir das am Anfang vorgestellt hast.

Gruss Dieter
Miniaturansicht angehängter Grafiken
plan_171.jpg  
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 4 von 5   « Erste     234 5      


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 00:48 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