Základy OOP, někde dělám chybu.   zodpovězená otázka

C#

Dobrý den,

rád bych si nechal poradit, kde dělám chybu.

Naprogramoval jsem velmi jednoduchý konzolový program, abych si vyzkoušel jak funguje primitivní generátor čísel (random)...

Program byl mnohem větší ale počítal mi blbě... zjednodušoval jsem tedy více a více a všiml jsem si, že od jisté doby mi přestal random generovat náhodné číslo při každém zavolání metody.

Pro všechny metody mi tedy vygeneruje stejné číslo... Kde dělám chybu ?

Děkuji za čas strávený nad pousmáním se :D

Pavel F

http://pastebin.com/LkkPHCyx

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Je potřeba object ze třídy Random nevytvářet v metodě Vystrelil() při každém volání, ale mít ho vytvořený výš na úrovni třídy.

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Ahoj, děkuji za odpověď...

zkusil jsem dát random na úroveň třídy...

nyní vypadá takto:

public static Random a = new Random();
public int Zasah = a.Next(0, 5);

Problém nabral jiný směr....

Pro první dvě volání skutečně vygeneruje dvě rozdílná čísla... která ovšem pak už opakuje až do porušení podmínky (jeden z hráčů má zivoty < 0 )

Třeba to funguje jak má a já se mylně domnívám že volání metody "Vystrel" z cyklu while bude generovat nová a nová čísla... (což by doufám měl... asi je blbost aby se mi jednou přidělila hodnota z randomu a cykl to pak už jenom kopíroval znovu a znovu do porušení podmínky)

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Nevím přesně, jak jste to změnil, ale vypadá, že jste i "public int Zasah = a.Next(0, 5);" dal na úroveň třídy. To ne! To musí samozřejmě zůstat v metodě "Vystrel".

Čili pouze vytvořit object ze třídy Random na úrovni třídy - static - společný pro všechny objekty, ale Next() se musí volat při každém výstřelu.

Je potřeba si ujasnit rozdíl mezi statickými členy třídy a nestatickými členy objektů a lokálními proměnnými v metodách.

nahlásit spamnahlásit spam 0 odpovědětodpovědět

A teď jste na to pane kápnul :)

s pokorou a poděkováním Pavel F

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Ač je mi to trapné, je možno nějakým pohádkovým příběhem vysvětlit rozdíl mezi deklarací randomu v metodě a deklarací na úrovni třídy ?

Předpokládal jsem že když zavolám metodu daného objektu, tak se vždy provede celá metoda od píky znovu.

V mém případě se v ní tedy vytvoří nově objekt random, který nově vytvořené proměnné "zasah" přidělí hodnotu... a ta po provedení metody zase zanikne, stejně tak jako objekt random.

Přijde další volání... a založí se úplně nový random... který vygeneruje uplne jiné číslo, které přidělí opět nově vytvořené proměnné "zásah"

To se ovšem nedělo...

edit: Je možné že se to dělo, ale algorytmus randomu byl stejný a se stejným počátkem a proto jsem dostával pro každé paralelní volání stejné číslo ?

respektive: ty sis založil nový a první hodnotu kterou ti dám bude 1... a ty sis taky zalozil nový a svůj první... a proto ti dám taky jedna...

nahlásit spamnahlásit spam 0 odpovědětodpovědět

V podstatě máte pravdu a v ideálním případě by to tak fungovalo, když pominu výkonnostní problém se znovuvtvářením objektu Random().

Ale, když kouknete do MSDN - https://msdn.microsoft.com/cs-cz/library...

"The default seed value is derived from the system clock and has finite resolution. As a result, different Random objects that are created in close succession by a call to the default constructor will have identical default seed values and, therefore, will produce identical sets of random numbers."

Čili pokud jsou objekty Random vytvořeny v krátké době po sobě, vracejí tytéž náhodná čísla.

Schválně, za jak dlouho proběhne celý program - smyčka?

nahlásit spamnahlásit spam 0 odpovědětodpovědět

děkuji za odpověd... prosím mrkněte na můj přidaný edit v předchozím příspěvku.

a ted to zajímavé... již jsem slyšel o měření času na smyčku, ale ještě nevím jak to měřit...

najdu sám a nebo nastřelíte ? :)

edit: narážka na algorytmus asi nebyla na místě... jak píše příručka, tak si hodnotu bere ze system clock :)

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Random třída má samozřejmě společný algoritmus pro generování pseudonáhodných čísel. To co se liší to je první hodnota, začátek řady, kterou generuje, a ta závisí na "seed value", a ta je ovlivněna defaultně systémovým časem. Jinak můžete použít jiný konstruktor Random() a seed value zadat.

Měření času běhu smyčky / programu - triviální řešení - zapamatovat čas před a po a na konci vypsat rozdíl.

PS: Algoritmus se píše s měkkým "i".

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Ad měření času) Zkuste se podívat na třídu System.Diagnostics.Stopwatch , k měření by Vám měly stačit metody Start(), Stop() a vlastnost Elapsed nebo ElapsedMilliseconds (uběhlý čas).

https://msdn.microsoft.com/cs-cz/library...

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Jen bych pro další čtenáře tématu doplnil, že stejná čísla se v krátkém časovém okamžiku vrací proto, že je použit při vytváření instance bezparametrický konstruktor. A ten (jak tu už bylo uvedeno z dokumentace MSDN) interně volá systémový čas a sestavuje si pomocí něj seed. Lze ale vytvořit instanci třídy Random a předat do konstruktoru vlastní seed. Například takto:

Random random = new Random(Guid.NewGuid().GetHashCode());

O třídě Random a náhodných číslech jsem napsal článek na svém blogu: https://www.miroslavholec.cz/blog/nahodn...

nahlásit spamnahlásit spam 0 odpovědětodpovědět
                       
Nadpis:
Antispam: Komu se občas házejí perly?
Příspěvek bude publikován pod identitou   anonym.
  • Administrátoři si vyhrazují právo komentáře upravovat či mazat bez udání důvodu.
    Mazány budou zejména komentáře obsahující vulgarity nebo porušující pravidla publikování.
  • Pokud nejste zaregistrováni, Vaše IP adresa bude zveřejněna. Pokud s tímto nesouhlasíte, příspěvek neodesílejte.

přihlásit pomocí externího účtu

přihlásit pomocí jména a hesla

Uživatel:
Heslo:

zapomenuté heslo

 

založit nový uživatelský účet

zaregistrujte se

 
zavřít

Nahlásit spam

Opravdu chcete tento příspěvek nahlásit pro porušování pravidel fóra?

Nahlásit Zrušit

Chyba

zavřít

feedback