Bundesliga Simulator

Bitte aktiviere JavaScript!
Hey,

erstmal bevor dieser Artikel anfängt, möchte ich kurz anmerken, dass dies mein erster Beitrag auf diesem Forum ist; falls ich also irgendetwas falsch gemacht habe oder der Beitrag hier fehl am Platz ist, tut es mir Leid und weist mich bitte darauf hin.


Also zu meiner Person, ich bin 14 und blutiger Hobby-Programmier-Anfänger. Ich versuche gerade in Java eine Art Bundesliga-Simulator zu programmieren. Bedeutet, dass das Programm automatisch Spieltage generiert, die Ergebnisse berechnen lässt und das Alles in einer Tabelle darstellt.

Ich habe aber schon länger das Problem, dass bei dem Erschaffen von Spieltagen folgendes Problem auftritt: Eine Begegnung A passt in keinen Spieltag, da entweder das eine Team X der Begegnung an diesem Spieltag schon spielt oder das andere Y. Ich habe bereits den Lösungsansatz ausprobiert, eine Begegnung B (enthält ein Team aus A) aus einem Spieltag S rauszunehmen, in den Spieltag dann Begegnung A einzufügen und dann mit B einen passenden Spieltag zu finden, und das Ganze solange bis alles passt. Das klappt aber irgendwie noch nicht so gut und ich kriege immer noch folgenden Output:

--------------------------------
1. Spieltag:
FC Bayern - 1. FC Nürnberg 2:0
RB Leipzig - Fortuna Düsseldorf 4:1
Borussia Dortmund - FC Schalke 04 1:0
--------------------------------

, --------------------------------
2. Spieltag:
Borussia Dortmund - Fortuna Düsseldorf 2:0
FC Schalke 04 - 1. FC Nürnberg 3:3
FC Bayern - RB Leipzig 3:4
--------------------------------

, --------------------------------
3. Spieltag:
FC Bayern - FC Schalke 04 3:2
RB Leipzig - 1. FC Nürnberg 0:1
--------------------------------

, --------------------------------
4. Spieltag:
FC Bayern - Borussia Dortmund 0:4
1. FC Nürnberg - Fortuna Düsseldorf 0:1
FC Schalke 04 - RB Leipzig 0:1
--------------------------------

, --------------------------------
5. Spieltag:
Borussia Dortmund - 1. FC Nürnberg 1:0
FC Bayern - Fortuna Düsseldorf 1:0
--------------------------------

(Ich arbeite momentan nur mit 6 Teams, damit es übersichtlicher ist)

Wie man sehen kann, gibt es bei Spieltag 5 und Spieltag 3 jeweils eine Begegnung zu wenig.


Hier der Code:

Main
Java:
import java.util.concurrent.ThreadLocalRandom;
import java.util.*;

public class Main {
    public static void main(String[] args) {
        System.out.println("Start");
        Team[] teams = {new Team("FC Bayern", 10), new Team("Borussia Dortmund", 9), new Team("FC Schalke 04", 5),
                        new Team("RB Leipzig", 9), new Team("1. FC Nürnberg", 3), new Team("Fortuna Düsseldorf", 3)};
        ArrayList<Begegnung> begegnungen = makeBegegnungen(teams);
        begegnungen.forEach((Begegnung i) -> i.makeGameResults());
        System.out.println(begegnungen.size() + "\n" + begegnungen);
        shuffleArrayList(begegnungen);
        ArrayList<Spieltag> spieltage = makeSpieltage(begegnungen, 5);
        System.out.println(spieltage);
        for(Team i : teams)
            System.out.println(i.getName() + ":   " + i.punkte + "P " + i.tore + "T " + i.gegentore + "G " );
    }
    
    static <T> void shuffleArray(T[] ar) {
        // If running on Java 6 or older, use `new Random()` on RHS here
        Random rnd = ThreadLocalRandom.current();
        for (int i = ar.length - 1; i > 0; i--)
        {
          int index = rnd.nextInt(i + 1);
          // Simple swap
          T a = ar[index];
          ar[index] = ar[i];
          ar[i] = a;
        }
    }
    
    static <T> void shuffleArrayList(ArrayList<T> ar) {
        // If running on Java 6 or older, use `new Random()` on RHS here
        Random rnd = ThreadLocalRandom.current();
        for (int i = ar.size() - 1; i > 0; i--)
        {
          int index = rnd.nextInt(i + 1);
          // Simple swap
          T a = ar.get(index);
          ar.set(index, ar.get(i));
          ar.set(i, a);
        }
      }
    
    
    static ArrayList<Begegnung> makeBegegnungen(Team[] teams) {
        ArrayList<Begegnung> rslt = new ArrayList<Begegnung>();
        for(Team i : teams) {
            for(Team j : teams) {
                if(i.equals(j) || i.isGegner(j)) {
                    continue;
                }else {
                    rslt.add(new Begegnung(i, j));
                    i.addGegner(j);
                    j.addGegner(i);
                }
            }
        }
        return rslt;
    }
    
    static ArrayList<Spieltag> makeSpieltage(ArrayList<Begegnung> begegnungen, int count) {
        ArrayList<Spieltag> spieltage = new ArrayList<Spieltag>();
        ArrayList<Begegnung> bereitsGemachteBegegnungen = new ArrayList<>();
        boolean s = false;
        boolean successful = false;
        for(int i = 0; i < count; i++)
            spieltage.add(new Spieltag(i + 1));
        System.err.println(spieltage);
        for(Begegnung j : begegnungen) {
            System.err.println(j);
            successful = false;
            for(Spieltag i : spieltage) {
                System.err.println(i);
                s = i.addBegegnung(j, bereitsGemachteBegegnungen);
                if (s) {
                    successful = true;   
                    break;
                }
            }
            if(!successful) {
                System.err.println("No Success! first");
                unsuccessfulHandlerSetInTeam(j, spieltage, bereitsGemachteBegegnungen);
            }
        }
        System.err.println(spieltage);
        return spieltage;
    }
    
    
    // Versuch, die nicht automatisch vergebenen Begegnungen einzufügen
    static void unsuccessfulHandlerSetInTeam(Begegnung b, ArrayList<Spieltag> s, ArrayList<Begegnung> bereitsGemachteBegegnungen) {
        boolean successful = false;
        boolean su = false;
        Begegnung ego = b;
        Begegnung last = new Begegnung();
        ArrayList<Begegnung> bereitsGetauscht = new ArrayList<Begegnung>();
        while(!successful) {
            System.err.println("another one");
            successful = false;
            for(Spieltag i : s) {
                System.err.println(i);
                su = i.addBegegnung(ego, bereitsGemachteBegegnungen);
                if (su) {
                    System.err.println("success!");
                    successful = true;
                    bereitsGetauscht.clear();
                    bereitsGetauscht.add(last);
                    break;
                }
            }
            if (!successful) {
                System.err.println("no success!");
                Begegnung temp = new Begegnung();
                Spieltag temp2 = new Spieltag();
                boolean breaker = false;
                for (Spieltag i : s) {
                    System.err.println(i);
                    for(Begegnung k : i.getBegegnungen()) {
                        System.err.println(ego);
                        System.err.println(k+ " " + bereitsGetauscht);
                        System.err.println(k.isIn(bereitsGetauscht));
                        if((k.t1.equals(ego.t1) || k.t2.equals(ego.t1)) && !k.isIn(bereitsGetauscht)) {
                            temp = k;
                            temp2 = i;
                            bereitsGetauscht.add(ego);
                            System.err.println("getauscht " + bereitsGetauscht + " " + ego);
                            breaker = true;
                        }
                        if (breaker) break;
                    }
                    if (breaker) break;
                }
                System.err.println(temp + " " + temp2 + "/////////////////");
                temp2.removeBegegnung(temp, bereitsGemachteBegegnungen);
                temp2.addBegegnung(ego, bereitsGemachteBegegnungen);
                System.err.println(temp + " " + temp2 + "/////////////////xxyxx");
                last = ego;
                ego = temp;
            }
        }
    }
}
Klasse Team
Java:
import java.util.ArrayList;

public class Team implements ContainedChecker {
    
    private String name;
    private int prozentchance;
    private ArrayList<Team> gegner = new ArrayList<Team>();
    
    public int punkte;
    public int tore;
    public int gegentore;
    
    
    //Constructor
    public Team(String name, int prozentchance) {
        this.name = name;
        this.prozentchance = prozentchance;
        this.punkte = 0;
    }
    
    
    //Boolean methods
    public boolean isGegner(Team that) {
        for(Team i : this.gegner) {
            if(i.equals(that))
                return true;
        }
        return false;
    }
    
    
    //Dynamic Methods
    public void addGegner(Team that) {
        this.gegner.add(that);
    }
    
    
    public void handleBegegnung(Begegnung that) {
        int mygoals = (that.t1.equals(this)) ? that.get_toreT1() : that.get_toreT2();
        int theirgoals = (that.t1.equals(this)) ? that.get_toreT2() : that.get_toreT1();
        this.tore += mygoals;
        this.gegentore += theirgoals;
        if(mygoals > theirgoals)
            this.punkte += 3;
        else if(mygoals == theirgoals)
            this.punkte++;
    }
    
    //"Overridden" Methods
    public boolean equals(Team that) {
        return this.toString() == that.toString();
    }
    
    @Override public String toString() {
        return this.name;
    }
    @Override public boolean isIn(ArrayList<Begegnung> that) {
        for (Begegnung i : that) {
            if (i.t1.equals(this) || i.t2.equals(this))
                return true;
        }
        return false;
    }
    
    
    //Getter Setter
    public int getChance() {
        return this.prozentchance;
    }
    public String getName() {
        return this.name;
    }
}
Klasse Spieltag
Code:
import java.util.ArrayList;

public class Spieltag {
    private int nummer;
    private ArrayList<Begegnung> begegnungen = new ArrayList<Begegnung>();
    
    //Constructor
    public Spieltag(int nummer) {
        this.nummer = nummer;
    }
    
    public Spieltag() {};
    
    
    //Dynamic methods
    public boolean addBegegnung(Begegnung that, ArrayList<Begegnung> bereitsGemachteBegegnungen) {
        if(!that.isIn(bereitsGemachteBegegnungen) && !that.t1.isIn(this.begegnungen) && !that.t2.isIn(this.begegnungen)) {
            this.begegnungen.add(that);
            bereitsGemachteBegegnungen.add(that);           
            System.err.println("geaddet");
            return true;
        }
        System.err.println("verkackt beim adden");
        return false;
    }
    
    public boolean removeBegegnung(Begegnung that, ArrayList<Begegnung> bereitsGemachteBegegnungen) {
        if(that.isIn(bereitsGemachteBegegnungen) && that.t1.isIn(this.begegnungen) && that.t2.isIn(this.begegnungen)) {
            this.begegnungen.remove(that);
            bereitsGemachteBegegnungen.remove(that);
            System.err.println("removet");
            return true;
        }
        System.err.println("verkackt beim removen");
        return false;
    }
    
    
    
    //"Overridden" methods
    @Override public String toString() {
        final String line = "--------------------------------";
        String rslt = "";
        rslt = rslt.concat(line + "\n");
        rslt = rslt.concat(this.nummer + ". Spieltag:\n");
        for(Begegnung i : begegnungen)
            rslt = rslt.concat(i.toString() + "\n");
        return rslt.concat(line + "\n\n");
    }
    
    
    //Getter Setter
    public ArrayList<Begegnung> getBegegnungen () {
        return this.begegnungen;
    }
}
Klasse Begegnung
Code:
import java.util.ArrayList;

public class Begegnung implements ContainedChecker {
    private static final int MAXGOALS = 6;
    private int toreT1;
    private int toreT2;
    
    public Team t1;
    public Team t2;
    
    
    //Constructor
    public Begegnung (Team t1, Team t2) {
        this.t1 = t1;
        this.t2 = t2;
    }
    
    public Begegnung()  {}
    
    
    //Boolean methods
    
    
    
    //Dynamic methods
    public void makeGameResults() {
        double torerare = Math.random() * MAXGOALS;
        final int tore = (int) torerare;
        final int chance1 = this.t1.getChance();
        final int chance2 = this.t2.getChance();
        double[] arrToreRare = {Math.random()*chance1, Math.random()*chance2};
        int[] arrTore = {(int) arrToreRare[0], (int) arrToreRare[1]};
        int heigher;
        int lower;
        if(arrTore[0] == arrTore[1])  {
            heigher = tore;
            lower = tore;
        }
        heigher  = (arrTore[0] > arrTore[1]) ? 0 : 1;
        lower  = (arrTore[0] > arrTore[1]) ? 1 : 0;
        int differ = arrTore[heigher] - arrTore[lower];
        arrTore[heigher] = tore; if (tore == 0) arrTore[heigher] = 1;
        arrTore[lower] = tore - differ; if (arrTore[lower] < 0) arrTore[lower] = 0;
        this.toreT1 = arrTore[0];
        this.toreT2 = arrTore[1];
        this.t1.handleBegegnung(this);
        this.t2.handleBegegnung(this);
    }
    
    
    //"Overridden" methods
    @Override public String toString() {
        return t1.toString() + " - " + t2.toString() + "  " + toreT1 + ":" + toreT2;
    }
    public boolean equals(Begegnung that) {
        return this.toString().contains(that.t1.toString()) && this.toString().contains(that.t2.toString());
    }
    @Override public boolean isIn(ArrayList<Begegnung> that) {
        for(Begegnung i : that) {
            if(i.equals(this)) {
                return true;
            }
        }
        return false;
    }
    
    
    //Getter Setter
    public int get_toreT1() {
        return this.toreT1;
    }
    
    public int get_toreT2() {
        return this.toreT2;
    }
}
Ich hoffe, ich konnte euch mein Problem genau genug schildern, ansonsten bitte fragt noch einmal nach.

Übrigens, da ich wie gesagt noch Anfänger bin, wäre es total nett, wenn ihr mir mitteilen könnten, wenn ich irgendetwas im schlechtem Style programmiert habe.

Vielen Dank vorab


LG
Marlon
 
Ich weiß nicht, ob sich jemand wirklich diesen ganzen Quellcode antun möchte und eventuelle Fehler identifizieren möchte. Es geht aber auch kürzer (sicherlich als Anfänger/Einstieg aber nicht geeignet!)
Java:
import static java.util.Arrays.*;
import static java.util.stream.IntStream.*;
import static java.util.stream.Stream.*;
import java.util.*;
import java.util.concurrent.atomic.*;
import java.util.stream.*;
/**
 * Adaptiert von:
 * https://stackoverflow.com/questions/26471421/round-robin-algorithm-implementation-java#answer-26471473
 */
public class Bundesliga {
  private static List<String> ms = asList(
      "FC Bayern", "FC Nürnberg", "RB Leipzig",
      "Fortuna Düsseldorf", "Borussia Dortmund", "FC Schalke");
  private static Stream<Stream<String[]>> spieltage() {
    int N = ms.size() - 1, H = ms.size() / 2;
    return range(0, N).mapToObj(d -> concat(
        Stream.<String[]>of(
            new String[] { ms.get(0), ms.get(d % N + 1) }),
        range(1, H).mapToObj(i -> new String[] {
            ms.get((d + i) % N + 1), ms.get((d + N - i) % N + 1) })));
  }
  public static void main(String[] args) {
    AtomicInteger t = new AtomicInteger(1);
    spieltage().forEach(tag -> {
      System.out.println(t.getAndIncrement() + ". Spieltag:");
      tag.forEach(begegnung -> {
        System.out.println(begegnung[0] + " - " + begegnung[1]);
      });
      System.out.println();
    });
  }
}
 
Letztlich ist es nichts anderes als ein [n][2]-Array, bei dem ein Element fix ist und die anderen im oder entgegen dem Uhrzeigersinn rotiert werden. Daher hier eine Anfänger-freundlichere Implementierung:

Java:
public class MatchMaker {
    
public static void match(int n) {
        System.out.println("Matching " + n + " teams...");
        
        int matchesPerDay = (n + 1) / 2;
        
        char[][] matches = new char[matchesPerDay][2];
        for(int i = 0; i < matchesPerDay; i++) {
            matches[i][0] = (char) ('1' + i);
            matches[i][1] = (char) ('1' + (i + matchesPerDay));
        }
        
        // adding virtual Team aka Pause
        if(n % 2 != 0) {
            matches[matchesPerDay-1][1] = 'P';
        }
        
        for(int i = 1; i < matchesPerDay * 2; i++) {
            System.out.println(Arrays.deepToString(matches));
            
            // Rotation
            char temp = matches[0][0];
            for(int j = 0; j < matchesPerDay-1; j++) {
                matches[j][0] = matches[j + 1][0];
            }
            matches[matchesPerDay-1][0] = matches[matchesPerDay-2][1];
            for(int j = matchesPerDay-2; j > 0; j--) {
                matches[j][1] = matches[j-1][1];
            }
            matches[0][1] = temp;
        }
    }
 
    public static void main(String[] args) {
        for(int i = 3; i <= 7; i++) {
            match(i);
        }
    }
}
Ausgabe:
Code:
Matching 3 teams...
[[1, 3], [2, P]]
[[2, 1], [3, P]]
[[3, 2], [1, P]]
Matching 4 teams...
[[1, 3], [2, 4]]
[[2, 1], [3, 4]]
[[3, 2], [1, 4]]
Matching 5 teams...
[[1, 4], [2, 5], [3, P]]
[[2, 1], [3, 4], [5, P]]
[[3, 2], [5, 1], [4, P]]
[[5, 3], [4, 2], [1, P]]
[[4, 5], [1, 3], [2, P]]
Matching 6 teams...
[[1, 4], [2, 5], [3, 6]]
[[2, 1], [3, 4], [5, 6]]
[[3, 2], [5, 1], [4, 6]]
[[5, 3], [4, 2], [1, 6]]
[[4, 5], [1, 3], [2, 6]]
Matching 7 teams...
[[1, 5], [2, 6], [3, 7], [4, P]]
[[2, 1], [3, 5], [4, 6], [7, P]]
[[3, 2], [4, 1], [7, 5], [6, P]]
[[4, 3], [7, 2], [6, 1], [5, P]]
[[7, 4], [6, 3], [5, 2], [1, P]]
[[6, 7], [5, 4], [1, 3], [2, P]]
[[5, 6], [1, 7], [2, 4], [3, P]]
PS.: Dieses Beispiel ist auf Grund der Wahl char als Datentyp nur für Teamgrößen 3-9 visuell sinnvoll.
 
Zuletzt bearbeitet:
Danke an alle, die geantwortet haben.

Das hat mir wirklich sehr weitergeholfen!
 
Passende Stellenanzeigen aus deiner Region:

Neue Themen

Oben