C# Feedback zu Algorithmus/Logik - Simulation Fußballergebnisse

spike1302

Ensign
Registriert
März 2013
Beiträge
143
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%

Code:
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

Code:
//_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.

Code:
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))
ecrzhum7.jpg



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 :)
 
Hallo,
was hat deine Problemstellung genau mit C# zu tun? ;-)

Greetz
hroessler
 
Es geht um Programmieren generell und hat nichts mit C# Problematiken zu tun.
Ich Programmiere in C#, daher die Auswahl. Ist das verwirrend?

back to topic.
Gibt es weitere Kommentare?


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" :)
 
Ich habe großes Interesse dich bei diesem Projekt zu unterstützen.
Ich habe vor längerer Zeit auch mal versucht so etwas aufzubauen, allerdings bin ich dann gescheitert, da es zu komplex wurde und meine Kenntnisse dafür nicht ausreichten...

Ideen habe ich ebenfalls genug...

Falls Interesse besteht dieses Projekt gemeinsam voranzutreiben, dann kannst du dich ja gerne mal melden...
 
Zurück
Oben