Laden...

Feedback zu Algorithmus/Logik - Simulation Fußballergebnisse

Erstellt von spike1302 vor 9 Jahren Letzter Beitrag vor 9 Jahren 3.512 Views
S
spike1302 Themenstarter:in
17 Beiträge seit 2011
vor 9 Jahren
Feedback zu Algorithmus/Logik - Simulation Fußballergebnisse

Hallo Community,

ich bin dabei eine Simulation von Fußballergebnissen zu schreiben. Dies habe ich bereits vorab umgesetzt und möchte gerne die Vorgehensweise sowie den Algorithmus/Logik mit euch besprechen, ob das überhaupt Sinn macht, man es anders angehen sollte und geneelles Feedback.

Ausgangssituation:*Zwei Mannschaften trete gegeneinander an: Mannschaft A / Mannschaft B *Jede Manschaft hat eine individuelle Mannschaftsstärke, zusammensetztend aus den Spielerstärken *Spielerstärken beispielsweise 1-15 *Spieler haben unterschiedliche Positionen: Torwart, Linker Verteidiger, Innenverteidiger, .., Rechtes Mittelfeld, .. , Sturm *Somit habe ich die Stärken in 9 Bereiche+Torwart unterteilt:
Sturm: Linker Sturm | Mittlerer Sturm | Rechter Sturm
Mittelfeld: Linkes Mittelfeld | Mittleres Mittelfeld | Rechtes Mittelfeld
Abwehr: Linke Abwehr | Mittlere Abwehr | Rechte Abwehr
Torwart

  • Bild siehe unten

Algorithmus/Logik*Ballbesitz wird anhand der Stärke zwei Mannschaften in % dargestellt *Beispiel: Mannschaft A: 55,9% Mannschaft B: 44,1%


ballbesitzA = MannschaftA.gesamtstaerke / (MannschaftA.gesamtstaerke + MannschaftB.gesamtstaerke);
ballbesitzB = MannschaftB.gesamtstaerke / (MannschaftA.gesamtstaerke + MannschaftB.gesamtstaerke);

*Offensive Bonus und Defensive Bonus als weiteren einstellbaren Indikator dazu *100% Offensive = 30%Bonus auf Sturm; jedoch 30% Abzug auf Abwehr *0% Defensive = 30% Abzug auf Sturm; jedoch 30% Bonus auf Abwehr *30% Sind eine Annahme von mir und kann jederzeit geändert werden


//_prozent_offensive sind ie 30% Annahme
public float Berechne_Bonus(float _prozent_offensive)
            {
                float bonus = ((_prozent_offensive * 2 * this.prozent_offensive / 100) - (_prozent_offensive));  //bsp 30%
                return bonus;
            }
            
            public float Berechne_Bonus_offensive(float _prozent_offensive)
            {
                float bonus = Berechne_Bonus(_prozent_offensive);
                float bonus_offensive = (bonus / 100) + 1;  //bsp max 1.3; zum rechnen

                return bonus_offensive;

            }

            public float Berechne_Bonus_defensive(float _prozent_offensive)
            {
                float bonus = Berechne_Bonus(_prozent_offensive);
                float bonus_defensive = (-bonus / 100) + 1;  //bsp 0.7; zum rechnen

                return bonus_defensive;

            }

//Als Ergebnis kommt zum weiterrechnen max 1.3 und mind 0.7 raus

*Ergebnisberechnung: *Mannschaft A und Mannschaft B werden getrennt voneinaner berechnet *es wird in 3 Schritten berechnet sowie Ballbesitz mit den jeweiliegn Schrittechancen multipliziert: *1. Schafft Abwehr+Mittelfeld(Mannschaft A) sich gegen Sturm+Mittelfeld(Mannschaft B) durchzusetzen (Chance berechnend auf die jeweilige Stärke der Bereiche)? Nein=Chance vorbei; Ja=Weiter nächster Schritt *Wenn ja; 2. schafft Mittelfeld+Sturm(Mannschaft A) sich gegen Mittelfeld+Abwehr(Mannschaft B) durchzusetzen (Chance berechnend auf die jeweilige Stärke der Bereiche)? Nein=Chance vorbei; Ja=Weiter nächster Schritt *Wenn ja; Torchance+1; 3. schafft Sturm(Mannschaft A) sich gegen Abwehr+Torwart(Mannschaft B) durchzusetzen (Chance berechnend auf die jeweilige Stärke der Bereiche)? Ja=Tor; Nein=nichts *Somit muss immer von Abwehr über MIttelfeld bis zum Sturm berechnet werden, ansonsten ist der Spielzug vorbei.


public void Berechnung_Ergebnis()
        {
            Random rnd = new Random();

            float B_A_M = MannschaftB.gesamtstaerke_abwehr * MannschaftB.Berechne_Bonus_defensive(prozent_offensive) + MannschaftB.gesamtstaerke_mittelfeld;
            float A_M_S = MannschaftA.gesamtstaerke_sturm * MannschaftA.Berechne_Bonus_offensive(prozent_offensive) + MannschaftA.gesamtstaerke_mittelfeld;
            float B_M_S = MannschaftB.gesamtstaerke_mittelfeld + MannschaftB.gesamtstaerke_sturm * MannschaftB.Berechne_Bonus_offensive(prozent_offensive);
            float A_A_M = MannschaftA.gesamtstaerke_abwehr * MannschaftA.Berechne_Bonus_defensive(prozent_offensive) + MannschaftA.gesamtstaerke_mittelfeld;
            float A_S = MannschaftA.gesamtstaerke_sturm * MannschaftA.Berechne_Bonus_offensive(prozent_offensive);
            float B_S = MannschaftB.gesamtstaerke_sturm * MannschaftB.Berechne_Bonus_offensive(prozent_offensive);
            float A_T_A = MannschaftA.staerke_torwart + MannschaftA.gesamtstaerke_abwehr * MannschaftA.Berechne_Bonus_defensive(prozent_offensive);
            float B_T_A = MannschaftB.staerke_torwart + MannschaftB.gesamtstaerke_abwehr * MannschaftB.Berechne_Bonus_defensive(prozent_offensive);

            //Mannschaft A
            for (int i = 1; i <= 3; i++)
            {
                int random = rnd.Next(1, 10001);

                //Abwehr zum Mittelfeld
                if (i == 1)
                {
                    float x = (A_A_M / (A_A_M + B_M_S)) * 10000; //bsp 55,43  daher nochmals *100, damit Kommastellen mit beachtet werden
                    if (random > x*ballbesitzA) break; //Wenn nicht getroffen, dann break und raus aus schleife, Chance vorbei.
                }

                //Mittelfeld zum Sturm
                else if (i == 2)
                {
                    float x = (A_M_S / (A_M_S + B_A_M)) * 10000; //bsp 55,43  daher nochmals *100, damit Kommastellen mit beachtet werden
                    if (random > x * ballbesitzA) break; //Wenn nicht getroffen, dann break und raus aus schleife, Chance vorbei.
                }

                //Sturm, Tor: ja/nein;
                else
                {
                    MannschaftA.torchancen += 1;
                    float x = (A_S / (A_S + B_T_A)) * 10000; //bsp 55,43  daher nochmals *100, damit Kommastellen mit beachtet werden
                    if (random <= x * ballbesitzA) MannschaftA.tore += 1;
                }

            }
            label_A_torchance.Text = MannschaftA.torchancen.ToString();
            label_A_tore.Text = MannschaftA.tore.ToString();


            //Mannschaft B
            for (int i = 1; i <= 3; i++)
            {
                int random = rnd.Next(1, 10001);

                //Abwehr zum Mittelfeld
                if (i == 1)
                {
                    float x = (B_A_M / (B_A_M + A_M_S)) * 10000; //bsp 55,43  daher nochmals *100, damit Kommastellen mit beachtet werden
                    if (random > x * ballbesitzB) break; //Wenn nicht getroffen, dann break und raus aus schleife, Chance vorbei.
                }

                //Mittelfeld zum Sturm
                else if (i == 2)
                {
                    float x = (B_M_S / (B_M_S + A_A_M)) * 10000; //bsp 55,43  daher nochmals *100, damit Kommastellen mit beachtet werden
                    if (random > x * ballbesitzB) break; //Wenn nicht getroffen, dann break und raus aus schleife, Chance vorbei.
                }

                //Sturm, Tor: ja/nein;
                else
                {
                    MannschaftB.torchancen += 1;
                    float x = (B_S / (B_S + A_T_A)) * 10000; //bsp 55,43  daher nochmals *100, damit Kommastellen mit beachtet werden
                    if (random <= x * ballbesitzB) MannschaftB.tore += 1;
                }

            }
            label_B_torchance.Text = MannschaftB.torchancen.ToString();
            label_B_tore.Text = MannschaftB.tore.ToString();

        }

So sieht es aus und es funktioniert super (unterschiedlcieh Stärken ausprobiert und es macht funktioniert super (nicht zu viele Tore; Auch kann der Schwächere gewinnen (jedoch nicht so oft wie der stärkere))
Bild, siehe Dateianhang

ToDos:*Derzeit existiert noch keine Berechnung einer einstellbaren Spielseite (mehr über links, mehr über rechts etc.). Daher auch ursprünglich die Einteilung in 9 Bereiche und nicht 3 *Eventuell berechnen, wenn Chanceaufbau von Abwehr+MIttelfeld gegen Sturm+Mittelfeld fehlschlägt, dass somit eine Chance für Mannschaft B existiert. Ebenfalls bei den anderen berechnungen. Problem: Somit würden viel mehr Tore entsstehen und so müsste ich die Chancen/Prozent runterschrauben?!

Vielen Dank fürs Diskutieren und Feedback 😃

82 Beiträge seit 2014
vor 9 Jahren

Hi spike1302,

meiner Meinung nach gibt es bei Deinem Berechnungsansatz ein paar kleine "macken". In welchem Zeitrahmen läuft Deine Simulation? Ein Angriff pro Minute?
Wie Du schon selbst schreibst --> Angriff erfolglos --> Angriff für Gegner! Das bedeutet aber auch, das Du dann einen Konter hast, bei dem Du eventuell die Abwehr schwächer bewerten musst.
Problem: Beachten, in welchen zeitlichen Rahmen sich Angriff/Konter bewegt. Wenn es zu lange dauert, ist die Abwehr wieder da.
So wie Dein Ansatz jetzt aussieht, müsstest Du bei Angriff über eine bevorzugte Seite dann aber auch die taktik und Aufstellung der Abwehr beachten. Die würde sich in so einem Fall dann ebenfalls umstellen.

Ich habe vor vielen vielen Jahren mal so was auf c64 gemacht. Dabei habe ich die aktuelle Tabellenposition und eventuelle Sieg- Niederlagenserien mit in die Stärke einfließen lassen. Weiterhin habe ich berücksichtigt, dass auch eine starke Mannschaft bei einem Gegentor an Stärke verlieren kann und umgekehrt.

Das nur mal so paar Anregungen.

So wie Du das jetzt umsetzen willst, wird die starke Mannschaft am Ende immer Erster und die schwache immer Letzter. Die Zufallszahlen sind i.d.R. gleichmäßig verteilt. Du musst also bei den Torchancen noch andere "Unterscheidungsmerkmale" berücksichtigen.
Das brauch sehr viel Testläufe und Anpassungen bei den Parametern, bis Du Dein gewünschtes Ergebnis bekommst. Pauschal 30% oder so kann Dir wahrscheinlich keiner sagen.

Bei mir konnte praktisch auch ein Zweitligist gegen Bayern München gewinnen. Ist zwar sehr selten passiert, hats aber gegeben.

gruß schnelleHelga

C
1.214 Beiträge seit 2006
vor 9 Jahren

So sieht es aus und es funktioniert super

Was heißt das? Hast du deine Ergebnisse mit den bekannten Ergebnissen tatsächlicher Spiele verglichen? Da gibt es schon sehr viele Testdaten, an denen man den Algorithmus optimieren könnte.
Pauschal würde ich aber sagen, dass dein Ansatz viel zu einfach ist und so gesehen "nichts bringt". Das nichts bringt in Anführungszeichen, weil du nicht mal dazugeschrieben hast, was du eigentlich erreichen willst. Als Ziel könnte man hier definieren, die zukünftigen Ergebnisse mit einer gewissen Wahrscheinlichkeit vorhersagen zu können. Wie du dir sicher denken kannst, gibts hier schon einiges. Die ganzen Wettanbieter werden sowas einsetzen und ich glaube, die haben wesentlich mehr Arbeit in ihre Algorithmen und die Optimierung reingesteckt, schliesslich ist das ihr Geschäft und es geht um viele Millionen. Und trotzdem liegen sie bei weitem nicht immer richtig. Dass man hier auch gar nicht immer richtig liegen kann und das Ergebnis von sehr vielen unterschiedlichen Faktoren abhängt ist denke ich sowieso klar. Aber dann muss ich erst recht fragen, was genau ist dein Ziel?

S
spike1302 Themenstarter:in
17 Beiträge seit 2011
vor 9 Jahren

Hallo,
vielen Dank für Antworten.

Vorweg: Mein Ziel ist es einen FußballManager (Spiel) zu schreiben. Allein für mich als Hobby.
Ich spiele gerne Anstoss, EA FM, etc und daraus ist mein Antrieb entstanden.
Also keine SImulation für Sportwetten doer sowas:)

Daher der kleine Anfang.

Das dieser Algorithmus zu "einfach" gestaltet ist, ist mir bewusst. Mir geht es darum, ob ich diesen Ansatz überhaupt so machen kann, oder ob ich Berechnungs-/Logikfehler habe. Daher der Thread, um die Grundbasis "abzusegnen" und weiter zu machen

Klar werden noch Faktoren rein kommen wie:

  • Moral
  • Individuelle Spielerfähigkeiten (Zeikampg, Torinstinkt, Flanken(Mittelfeld), ...
  • Eingespieltheit im Team
  • Frisch, Kondifition
  • Selbstsicherheit (viele Siege hintereinander, ...)
  • ...
    (aber irgendwo muss ja mal ein Anfag her, ohne es komplex schwer zu machen zu Beginn)

Ich habe schon viele "Testläufe" gemacht und bei mir gewinnt nicht nur der Stärkere. Anteilsmäßig schon, aber die chancen sind ausgewogen.
Würdet ihr es anders angehen, als dieses Chancen/Prozentmodell gemessen an der stärke in den Bereichen? Ist m.W in der Praxis nicht anders.

Ich bin gerne für weiteres Feedback offen und auch Idden zur "Komplexitätserhöhung" 😃

5.658 Beiträge seit 2006
vor 9 Jahren

Hi spike1302,

Ich bin gerne für weiteres Feedback offen und auch Idden zur "Komplexitätserhöhung" 😃

Falls du Tips zum Algorithmus selbst haben willst, solltest du erstmal erklären, wie er momentan funktioniert. Der Code ist für mich nahezu unlesbar, und selbst die Kommentare sind nicht hilfreich bis überflüssig:


float x = (B_A_M / (B_A_M + A_M_S)) * 10000; //bsp 55,43  daher nochmals *100, damit Kommastellen mit beachtet werden

Ganz allgemein gesagt, könntest du dich mal mit objektorientierte Programmierung beschäftigen und mit Schichtentrennung, dann ist der Code übersichtlicher, besser zu verstehen, einfacher zu erweitern und leichter zu debuggen.

Siehe dazu z.B. [Artikel] Drei-Schichten-Architektur

Christian

Weeks of programming can save you hours of planning

C
1.214 Beiträge seit 2006
vor 9 Jahren

Ich bin gerne für weiteres Feedback offen und auch Idden zur "Komplexitätserhöhung" 😃

Was anscheinend noch nicht erwähnt wurde ist, ob die Mannschaft daheim oder auswärts spielt. Das macht sehr oft sehr viel aus. Wenn du dir Statistiken anschaust, sind die meisten Mannschaften daheim deutlich stärker.