IT rekvalifikace s garancí práce. Seniorní programátoři vydělávají až 160 000 Kč/měsíc a rekvalifikace je prvním krokem. Zjisti, jak na to!
Hledáme nové posily do ITnetwork týmu. Podívej se na volné pozice a přidej se do nejagilnější firmy na trhu - Více informací.

Diskuze: Generovaní náhodných čísel atd.

V předchozím kvízu, Online test znalostí Java, jsme si ověřili nabyté zkušenosti z kurzu.

Aktivity
Avatar
Jan Béňa
Člen
Avatar
Jan Béňa:29.1.2020 20:30

Ahoj všem.
Asi bych potřeboval poradit. Snažil jsem se udělat program, který by vygeneroval mezi sebou dvě náhodné čísla a ty pak porovnal mezi sebou. Pokud by jedno bylo větší přičetl by +1 do proměnné třeba a v opačném případě do b. při rovnosti nic. Snažil jsem se to naprogramovat pomocí OOP a vše funguje jak jsem popsal. Ovšem když to dám do cyklu tak to vygeneruje jednou náhodně a pak to vezme první náhodné generování. Nějak nemůžu docílit toho, aby to vždycky vygenerovalo nové čísla do cyklu tak že mám vždy jen tři výsledky.(1:0,0:1 nebo 0:0). Myslím že pokud jsem došel sem, měl bych to zvládnout, akorát už se s tím lámu týden a pořád nic. Mohl by mi když tak nějaký zkušený borec dát nějaký tip aby mě nasměroval. Děkuji mockrát.

Zkusil jsem:

package fotbal.manager.pkg001;

public class FotbalManager001 {


    public static void main(String[] args) {

     Klub sparta = new Klub("Sparta");
     Klub slavie = new Klub("Slavie");
     System.out.println(sparta);
     System.out.println(slavie);
     Zapas zapas = new Zapas(sparta,slavie);
     zapas.hraj();
     System.out.println(zapas);
         }
    }
package fotbal.manager.pkg001;

import java.util.Random;

public class Klub {
    Random random=new Random();
    public String jmeno;
    public int zaloha;

    public Klub(String jmeno){
        this.jmeno=jmeno;
        zaloha= random.nextInt(6)+1;
    }
    @Override
public String toString(){
    return jmeno+" "+zaloha;
}
}
package fotbal.manager.pkg001;

import java.util.Random;

public class Zapas {
   public Random random;
   public Klub domaci;
   public Klub hoste;
   public int scoredomaci;
   public int scorehoste;

public Zapas(Klub domaci,Klub hoste){
    random = new Random();
    this.domaci = domaci;
    this.hoste = hoste;

}
public int hraj(){
    scoredomaci=0;
    scorehoste=0;
    for (int i = 1; i<3;i++){
        if (domaci.zaloha>hoste.zaloha)
        {
          scoredomaci += 1;
        }
        else if (domaci.zaloha<hoste.zaloha)
        {
          scorehoste += 1;
        }
    }
 return scoredomaci + scorehoste;
}
@Override
public String toString(){
return domaci.jmeno+" "+scoredomaci+" : "+scorehoste+" "+hoste.jmeno;

}
}

Předem říkám že jsem začátečník ale musím říct že mě to baví :)

 
Odpovědět
29.1.2020 20:30
Avatar
Odpovídá na Jan Béňa
Luboš Běhounek Satik:29.1.2020 20:40

Ahoj, problém je v tom, že si pokaždé vytvoříš novou instanci třídy random, která má pokaždé stejný seed (počáteční hodnoty), jelikož seed se obvykle bere z aktuálního času. Udělej si jen jednu instanci třídy random a používej ji všude :)

Editováno 29.1.2020 20:41
Nahoru Odpovědět
29.1.2020 20:40
https://www.facebook.com/peasantsandcastles/
Avatar
Jan Béňa
Člen
Avatar
Odpovídá na Luboš Běhounek Satik
Jan Béňa:29.1.2020 20:49

Takže jestli to chápu dobře, mám docílit toho, co se bralo v tutoriálu a tzv. jednu kostku tahat pořád sebou? Chtěl jsem právě, aby měl každá proměnná svůj generátor. Protože mi úplně nesedí ,že když změním hodnotu jedné instance třídy random, změní se mi hodnota všude.

 
Nahoru Odpovědět
29.1.2020 20:49
Avatar
Jan Béňa
Člen
Avatar
Jan Béňa:29.1.2020 21:15

Změnil jsem třídu Klub a Zapas a abych se přiznal tak nechápu co to vlastně ted dělá :D zřejmě to už projíždí cyklem vícekrát s různými čísly ale zase nefungují podmínky :D.

package fotbal.manager.pkg001;

import java.util.Random;

public class Klub {
    private Random random;
    public String jmeno;
    public int zaloha;

    public Klub(String jmeno){
        this.jmeno=jmeno;
        zaloha= 6;
        random=new Random();
    }
    public int prihraj(){
        return random.nextInt(zaloha);
    }
    @Override
public String toString(){
    return jmeno+" "+prihraj();
}
}
package fotbal.manager.pkg001;


public class Zapas {

   public Klub domaci;
   public Klub hoste;
   public int scoredomaci;
   public int scorehoste;

public Zapas(Klub domaci,Klub hoste){
    this.domaci = domaci;
    this.hoste = hoste;

}
public int hraj(){
    scoredomaci=0;
    scorehoste=0;
    for (int i = 1; i<5;i++){
        if (domaci.prihraj()>hoste.prihraj())
        {
          scoredomaci += 1;
        }
        else if (domaci.prihraj()<hoste.prihraj())
        {
          scorehoste += 1;
        }
    }
 return scoredomaci + scorehoste;
}
@Override
public String toString(){
return domaci.jmeno+" "+scoredomaci+" : "+scorehoste+" "+hoste.jmeno;

}
}
 
Nahoru Odpovědět
29.1.2020 21:15
Avatar
Luboš Běhounek Satik:29.1.2020 21:27

Tady porad vytvaris pro kazdy klub novou instanci randomu, klidne si tu kostku udelej jen jednou a statickou.

Nahoru Odpovědět
29.1.2020 21:27
https://www.facebook.com/peasantsandcastles/
Avatar
zitekv
Člen
Avatar
Odpovídá na Jan Béňa
zitekv:29.1.2020 22:29

Oni fungují, jen nedělají to co bys chtěl...

if (domaci.prihraj()>hoste.prihraj())
       {
         scoredomaci += 1;
       }
       else if (domaci.prihraj()<hoste.prihraj())
       {
         scorehoste += 1;
       }

Ty totiž házíš znovu kostkou v případě, že domácí prohráli a tudíž se ti pak stane, že vyhrajou a ty ani jednou nic nepřičteš.
Před testováním si ulož hozené hodnoty a pak testuj podmínky.

int domaciHod=0;
int hosteHod=0;
...
for(...
domaciHod=domaci.prihraj();
hosteHod=hoste.prihraj();
if (domaciHod>hosteHod)
        {
          scoredomaci += 1;
        }
        else if(domaciHod>hosteHod)
        {
          scorehoste += 1;
        }

Snad je to ono...

 
Nahoru Odpovědět
29.1.2020 22:29
Avatar
Jan Béňa
Člen
Avatar
Odpovídá na zitekv
Jan Béňa:30.1.2020 20:58

To už jsem jednou zkoušel pro jistotu jsem to udělal znova ale program padá.Píše něco o Null hodnotě a pointerech ale tomu já ještě nerozumím. :)

 
Nahoru Odpovědět
30.1.2020 20:58
Avatar
Odpovídá na Jan Béňa
Matúš Olejník:30.1.2020 23:06

V takom prípade treba postnúť aj kód aj chybu :)

Nahoru Odpovědět
30.1.2020 23:06
/* I am not sure why this works but it fixes the problem */
Avatar
Lubor Pešek
Člen
Avatar
Lubor Pešek:31.1.2020 15:08

"Nějak nemůžu docílit toho, aby to vždycky vygenerovalo nové čísla do cyklu"

Zkus si položit na tuto část věty otázku.
Kdy generuješ nové číslo? (najdi si v kódu, kdy generuješ v kódu číslo) a tím i zjistíš, proč ti to negeneruje nové číslo v cyklu.
(Rada do budoucna. Toto je bohužel ta nejhorší ze tří chyb - logická. Pokud Prostě program nedělá to, co chceš a ani nepíše žádnou chybu, tak se musíš takhle ptát. Proč to nedělá co má a co vlastně chci, aby to dělalo).

Přiznám se, že jsem doteď nepochopil tu spojitost mezi původním zněním zadání a pak tím kódem.
Když bych to vzal z původního zadání:

Snažil jsem se udělat program, který by vygeneroval mezi sebou dvě náhodné čísla a ty pak porovnal mezi sebou. Pokud by jedno bylo větší přičetl by +1 do proměnné třeba a v opačném případě do b. při rovnosti nic. Snažil jsem se to naprogramovat pomocí OOP a vše funguje jak jsem popsal. Ovšem když to dám do cyklu tak to vygeneruje jednou náhodně a pak to vezme první náhodné generování. Nějak nemůžu docílit toho, aby to vždycky vygenerovalo nové čísla do cyklu tak že mám vždy jen tři výsledky.(1:0,0:1 nebo 0:0)

Tak by kód vypadal asi takhle nějak:

import java.util.Random;

public class Generator {

    private final Random random = new Random();
    private int firstNumber;
    private int secondNumber;
    private int firstNumberWinsCounter;
    private int secondNumberWinsCounter;

    //konstruktor
    public Generator() {
        generateNumbers();
        output();
    }

    //přístupové metody
    public int getFirstNumber() {
        return firstNumber;
    }

    public void setFirstNumber(int firstNumber) {
        this.firstNumber = firstNumber;
    }

    public int getSecondNumber() {
        return secondNumber;
    }

    public void setSecondNumber(int secondNumber) {
        this.secondNumber = secondNumber;
    }

    public int getFirstNumberWinsCounter() {
        return firstNumberWinsCounter;
    }

    public int getSecondNumberWinsCounter() {
        return secondNumberWinsCounter;
    }

    //metody
    private void increaseFirstNumberWins() {
        firstNumberWinsCounter++;
    }

    private void increaseSecondNumberWins() {
        secondNumberWinsCounter++;
    }

    private void output() {
        System.out.println(getFirstNumberWinsCounter());
        System.out.println(getSecondNumberWinsCounter());
    }

    private void generateNumbers() {
        setFirstNumber(random.nextInt(10));
        setSecondNumber(random.nextInt(10));
        if (getFirstNumber() > getSecondNumber()) {
            increaseFirstNumberWins();
        } else if (getSecondNumber() > getFirstNumber()) {
            increaseSecondNumberWins();
        }
    }

    //main
    public static void main(String[] args) {
        new Generator();
    }
}

No a potom stačí dát v konstruktoru metodu generateNumber­s(); do cyklu a měl bys mít kýžený výsledek.

import java.util.Random;

public class Generator {

    private final Random random = new Random();
    private int firstNumber;
    private int secondNumber;
    private int firstNumberWinsCounter;
    private int secondNumberWinsCounter;

    //konstruktor
    public Generator() {
        for (int i = 0; i < 10; i++) {
            generateNumbers();
        }
        output();
    }

    //přístupové metody
    public int getFirstNumber() {
        return firstNumber;
    }

    public void setFirstNumber(int firstNumber) {
        this.firstNumber = firstNumber;
    }

    public int getSecondNumber() {
        return secondNumber;
    }

    public void setSecondNumber(int secondNumber) {
        this.secondNumber = secondNumber;
    }

    public int getFirstNumberWinsCounter() {
        return firstNumberWinsCounter;
    }

    public int getSecondNumberWinsCounter() {
        return secondNumberWinsCounter;
    }

    //metody
    private void increaseFirstNumberWins() {
        firstNumberWinsCounter++;
    }

    private void increaseSecondNumberWins() {
        secondNumberWinsCounter++;
    }

    private void output() {
        System.out.println(getFirstNumberWinsCounter());
        System.out.println(getSecondNumberWinsCounter());
    }

    private void generateNumbers() {
        setFirstNumber(random.nextInt(10));
        setSecondNumber(random.nextInt(10));
        if (getFirstNumber() > getSecondNumber()) {
            increaseFirstNumberWins();
        } else if (getSecondNumber() > getFirstNumber()) {
            increaseSecondNumberWins();
        }
    }

    //main
    public static void main(String[] args) {
        new Generator();
    }
}
Nahoru Odpovědět
31.1.2020 15:08
Existují dva způsoby, jak vyřešit problém. Za prvé vyhoďte počítač z okna. Za druhé vyhoďte okna z počítače.
Avatar
Lubor Pešek
Člen
Avatar
Lubor Pešek:31.1.2020 15:25

Jinak:)
To cos napsal o NullPointerEx­ceptionu:) To neznamená Null pointerů:)
Toto je jedna z nejčastějších chyb v programování. NullPointerEx­ception = Chyba, ukazuješ na nevytvořený objekt (na instanci s null hodnotou).
Abys pochopil smysl této chyby, tak je to, jako kdybys chtěl v reálném životě něco po něčem, co neexistuje.
Kupříkladu kdybys stál vedle 3 lidí (Libor, Luboš, Lubor) a řekneš jim:
"Lubomíre, udělej tři kroky dopředu"
Tak ti pán bůh řekne:
"Pitomče, Lubomír neexistuje"

V podstatě Java ti to říká úplně stejně. Ty kupříkladu chceš na nějaký objekt zavolat jeho metodu, ale ten objekt ještě neinicializuješ (nevytvoříš jej). Například bys takovou chybu mohl získat takto:

Random random;
random.nextInt();

Když tento kód provoláš v main metodě, tak ti to vrátí NullPointerEx­ception.
Prostě ti to řekne, že voláš metodu nextInt na objekt random, který ale neexistuje. Tys jen řekl, že to někdy bude instance typu Random, ale ta instance neexistuje, protože jsi ji nevytvořil.

Tak to je asi celková podstata NullPointerEx­ception. Je to častá a nepříjemná chyba, ale jedna z nejjednodušších, protože víš, že v nějaké části programu nemáš vytvořený objekt, ale voláš na něj metodu.

Nahoru Odpovědět
31.1.2020 15:25
Existují dva způsoby, jak vyřešit problém. Za prvé vyhoďte počítač z okna. Za druhé vyhoďte okna z počítače.
Avatar
Odpovídá na Lubor Pešek
Tomáš Brabec:2.2.2020 17:54
Random random;
random.nextInt();

Něco takového ti ani neprojde kompilátorem.

Random random = null;
random.nextInt();

Tahle už kompilátorem projde a při běhu to konečně vyhodí tu velice oblíbenou výjimku.

Nahoru Odpovědět
2.2.2020 17:54
Lidé se dělí do 10 skupin. Jedni dvojkovou soustavu znají a druzí ne.
Avatar
Lubor Pešek
Člen
Avatar
Odpovídá na Tomáš Brabec
Lubor Pešek:2.2.2020 18:43

Asi jo, já jsem to psal z patra

Nahoru Odpovědět
2.2.2020 18:43
Existují dva způsoby, jak vyřešit problém. Za prvé vyhoďte počítač z okna. Za druhé vyhoďte okna z počítače.
Avatar
Jan Béňa
Člen
Avatar
Jan Béňa:2.2.2020 19:49

Všem děkuji za odpovědi a pomoc. Poopravil jsem svůj program a díky radám co jste mi daly to už funguje. Nicméně, když tak zůstaňte na příjmu určitě budu mít jiný problém. Jo a jinak udělal jsem to bez těch setterů a getterů, protože tak daleko ještě nejsem, tak pracuji s tím co znám teda alespoň si myslím, že to znám. A to je po lekci cca OOP 3. Tak že ještě jednou děkuji za pomoc.

 
Nahoru Odpovědět
2.2.2020 19:49
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 13 zpráv z 13.