Java programovanie príklady: Vytvor si užitočnú aplikáciu na generovanie náhodných zápasov tímových dvojíc vo štvorhre

V tomto článku som si dal zacieľ ukázať, ako sa dajú jednoducho riešiť reálne problémy zo života v programovacom jazyku Java.

Zadanie

Spoločne si vytvoríme program, ktorý z N prihlásených ľudí vytvorí unikátne páry a z nich sa vygenerujú náhodne 2 tímy dvojíc, ktoré budú hrať proti sebe. Cieľom je vytvoriť všetky možné variácie zápasov, aby si zahral každý tím proti zvyšným tímom.

Návrh riešenia

Ak riešime komplexnejšie zadanie, odporúča sa rozložiť si ho na menšie časti a tieto vyriešiť samostatne. V tomto zadaní by bolo možné rozložiť ho na nasledovné kroky:

  • načítanie prihlásených ľudí a uloženie do pamäte programu,
  • vytvorenie variácií párov bez opakovania,
  • vytvorenie všetkých možných hier dvoch dvojíc,
  • náhodné premiešanie vygenerovaných zápasov,
  • výpis výsledkov.

Teraz sa pozrieme na jednotlivé kroky podrobnejšie.

Načítanie prihlásených ľudí a uloženie do pamäte programu

V tejto časti načítame zo súboru zoznam mien prihlásených ľudí a uložíme ich do zoznamu ludia. Jeden človek bude reprezentovaný triedou Osoba.

Vytvorenie variácií párov bez opakovania

Keď máme načítaných ľudí potrebujeme z ich vytvoriť všetky možne dvojice, tak aby sa v nich osoby neopakovali a samozrejme každá dvojica by mala byť unikátna. Pri dvojici nám nezáleží na poradí, kto je prvý, resp. druhý člen. Takýto dvojčlenný tím bude reprezentovaný triedou Dvojica a výsledky si uložíme do zoznamu unikatneDvojice.

Vytvorenie všetkých možných hier dvoch dvojíc

Z vytvorených dvojčlenných tímov vytvoríme všetky možné hry, aby si zahral každý tím s každým. Musíme však zabezpečiť, aby daná dvojica hrala v jednom zápase iba v jednom tíme, to znamená dvojica nemôže hrať v zápase proti sebe a zároveň žiadny hráč nemôže hrať naraz v dvoch tímoch.

Jedna hra bude reprezentovaná triedou Zapas a tie si uložíme do zoznamu zapasy na ďalšie spracovanie.

Náhodné premiešanie vygenerovaných zápasov

Pre ozvláštnenie, pridáme prvok náhody tým, že vygenerované zápasy náhodne premiešame.

Výpis výsledkov

Pre tento typ konzolovej aplikácie bude postačovať, ak výsledky vypíšeme na konzolu.

Implementácia návrhu v programovacom jazyku Java

Potom, čo sme identifikovali kľúčové kroky programu, nám neostáva nič iné, iba si program naprogramovať. Vytvoríme si turnajový systém pre zápasy medzi skupinami tímov (dvojíc ľudí). Pre lepšiu predstavu o tom, čo program robí, vysvetlím ho krok za krokom:

Osoba.java

package entities;

public class Osoba {
    public String meno;

    public Osoba(String meno) {
        this.meno = meno;
    }
}

Definuje triedu Osoba s jedným atribútom meno, ktorý predstavuje meno osoby.

Dvojica.java

package entities;

public class Dvojica {
    public Osoba osoba1;
    public Osoba osoba2;

    public Dvojica(Osoba osoba1, Osoba osoba2) {
        this.osoba1 = osoba1;
        this.osoba2 = osoba2;
    }
}

Definuje triedu Dvojica, ktorá obsahuje dve osoby (osoba1 a osoba2) a reprezentuje dvojicu ľudí, resp. tím zložený z dvoch ľudí.

Zapas.java

package entities;

public class Zapas {
    public Dvojica tim1;
    public Dvojica tim2;

    public Zapas(Dvojica tim1, Dvojica tim2) {
        this.tim1 = tim1;
        this.tim2 = tim2;
    }
}

Trieda Zapas predstavuje jeden zápas medzi dvoma dvojicami, resp. tímami (tim1 a tim2).

Generator.java

package entities;

import entities.*;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;

public class Generator {
    private List<Osoba> ludia;
    private List<Dvojica> unikatneDvojice;
    private List<Zapas> zapasy;

    public void Generator() {
        ludia = null;
        unikatneDvojice = null;
        zapasy = null;
    }

    public void nacitajVstupneData() throws IOException {
        ludia = new ArrayList<>();
        for(String line : Files.readAllLines(Paths.get("vstupy.txt"))) {
            ludia.add(new Osoba(line));
        }
    }

    // Vytvori všetky možné dvojice z ľudí
    public void vygenerujUnikatneDvojice() {
        unikatneDvojice = new ArrayList<>();
        for (int i = 0; i < ludia.size(); i++) {
            for (int j = i + 1; j < ludia.size(); j++) {
                Dvojica dvojica = new Dvojica(ludia.get(i), ludia.get(j));
                unikatneDvojice.add(dvojica);
            }
        }
    }

    // Vytvori všetky možné zápasy s danými dvojicami
    public void vygenerujUnikatneZapasy() {
        zapasy = new ArrayList();

        for (int i = 0; i < unikatneDvojice.size(); i++) {
            for (int j = i + 1; j < unikatneDvojice.size(); j++) {
                Dvojica tim1 = unikatneDvojice.get(i);
                Dvojica tim2 = unikatneDvojice.get(j);
                if(tim1.osoba1.equals(tim2.osoba1) || tim1.osoba1.equals(tim2.osoba2) || tim1.osoba2.equals(tim2.osoba1) || tim1.osoba2.equals(tim2.osoba2))
                    continue;
                zapasy.add(new Zapas(tim1, tim2));
            }
        }
    }

    public List<Osoba> getLudia() {
        return ludia;
    }

    public List<Dvojica> getUnikatneDvojice() {
        return unikatneDvojice;
    }

    public List<Zapas> getZapasy() {
        return zapasy;
    }
}

Trieda Generator je zodpovedná za načítanie, spracovanie dát a vygenerovanie výsledkov. Používa tri zoznamy (ludia, unikatneDvojice a zapasy) pre spravovanie údajov o ľuďoch, tímoch a zápasoch.

Konštruktor Generator() – inicializuje zoznamy na hodnotu null.

Metóda nacitajVstupneData() – načíta údaje o ľuďoch zo súboru vstupy.txt a vytvára z nich objekty typu Osoba, ktoré ukladá do zoznamu ludia.

Metóda vygenerujUnikatneDvojice() – vytvára všetky možné dvojice z ľudí a ukladá ich do zoznamu unikatneDvojice.

Metóda vygenerujUnikatneZapasy() – vytvára všetky možné zápasy medzi dvojicami a ukladá ich do zoznamu zapasy. Zabezpečuje, aby sa žiadne dve osoby neopakovali v rôznych dvojiciach.

Prístupové metódy getLudia(), getUnikatneDvojice(), getZapasy() – poskytujú prístup k jednotlivým zoznamom.

Main.java

import java.io.IOException;
import java.util.Collections;
import java.util.Random;

import entities.*;

public class Main {
    public static void main(String[] args) throws IOException {
        Generator generator = new Generator();
        generator.nacitajVstupneData();

        System.out.println("Prihlaseni ludia [" +  generator.getLudia().size() + "]: ");
        for (Osoba osoba : generator.getLudia()) {
            System.out.println(osoba.meno);
        }
        System.out.println();

        generator.vygenerujUnikatneDvojice();
        System.out.println("Mozne dvojice [" +  generator.getUnikatneDvojice().size() + "]: ");
        for (Dvojica dvojica : generator.getUnikatneDvojice()) {
            System.out.println(dvojica.osoba1.meno + " a " + dvojica.osoba2.meno);
        }
        System.out.println();

        generator.vygenerujUnikatneZapasy();
        Collections.shuffle(generator.getZapasy(), new Random());
        System.out.println("Zapasy kazdy s kazdym v nahodnom poradi [" +  generator.getZapasy().size() + "]: ");
        for (Zapas zapas : generator.getZapasy()) {
            System.out.println(zapas.tim1.osoba1.meno + " a " + zapas.tim1.osoba2.meno + " vs. " +
                    zapas.tim2.osoba1.meno + " a " + zapas.tim2.osoba2.meno);
        }
    }
}

Obsahuje hlavnú metódu main(), ktorá demonštruje funkcionalitu programu. Vytvorí inštanciu triedy Generator. Načíta vstupné údaje o ľuďoch a vypíše prihlásených ľudí. Vygeneruje všetky možné unikátne dvojice a vypíše ich. Vygeneruje všetky možné zápasy, tie potom náhodne zotriedi a vypíše ich na konzolu.

Program funguje pre ľubovoľné množstvo ľudí a dá sa jednoducho upraviť a adaptovať pre vlastné požiadavky.

Vstup programu:

Vytvorí inštanciu triedy Generator. Načíta vstupné údaje o ľuďoch a vypíše prihlásených ľudí. Vygeneruje všetky možné unikátne dvojice a vypíše ich.

Výstup programu:

Program funguje pre ľubovoľné množstvo ľudí a dá sa jednoducho upraviť a adaptovať pre vlastné požiadavky.

Cvičenie 1

Rozšír triedu Osoba o atribút pohlavie (muž, žena).

Uprav metódu vygenerujUnikatneDvojice() tak, aby vytvárala všetky možné dvojice z ľudí tak, aby tím bol zložený z jedného muža a jednej ženy. Následne vygeneruj možné zápasy.

Výsledky ulož do výstupného súboru.

Cvičenie 2 (challenge)

Pri vytváraní inštancie generátora zadaj číslo, ktoré bude určovať koľko členné tímy bude treba vytvoriť. Kód z príkladu následne uprav tak, aby fungoval pre ľubovoľne veľké tímy.

Java príklad kódu

Pripravili sme pre teba súbory so spomínaným príkladom vo forme kódu, ktorý si môžeš spustiť priamo v Jave. Stiahni si Java kód príkladu tu.

Ak ti vytvorenie kódu zo zadania nerobí problém a si skúsený Java programátor, pozri si naše firemné benefity a reaguj na pracovné ponuky.

O autorovi

Jozef Wagner

Java Developer Senior

Viac ako 10 rokov programujem v Jave, momentálne pracujem v msg life Slovakia ako Java programátor senior a pomáham zákazníkom implementovať ich požiadavky do poistného softvéru Life Factory. Vo voľnom čase si rád oddýchnem v lese, prípadne si zahrám nejakú dobrú počítačovú hru.

Daj nám o sebe vedieť