Avatar
Ondřej Krsička
Redaktor
Avatar
Ondřej Krsička:

Ahoj, napsal jsem si program "Opilcova procházka", ale moc nevím, jak jej napsat objektově. Proto prosím, jestli by někdo měl čas a navrhnul mi elegantnější řešení pomocí OOP, nebo mě alespoň popostrčil správným směrem nějakou radou. Zdrojový kód je níže. Ondra

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;

namespace Opilcova_procházka
{
    class Program
    {
        static bool HodDoHospody()
        {
            Random a = new Random();
            int aa = a.Next(1, 100);
            int bb = a.Next(1, 100);
            if (aa > bb) return true;
            else return false;
        }
        static void Main(string[] args)
        {
            char xxx = '5';
            char yyy = '5';
            while (xxx == yyy)
            {
            //vytvoření cesty a umístění opilce
                int kroku = 0;
            int opilec = 20;
            char[] cesta = new char[41];
            for (int i = 0; i < cesta.Length; i++)
                cesta[i] = '-';
            cesta[opilec] = '#';
            //cyklus procházky
            while (cesta[0] != '#' || cesta[40] != '#')
            {
                Thread.Sleep(100);
                Console.Clear();
                Random vlevo = new Random();
                Random vpravo = new Random();
                if (HodDoHospody())
                {
                    if (opilec > 0)
                    {
                        cesta[opilec] = '-';
                        opilec--;
                        cesta[opilec] = '#';
                        kroku++;
                    }
                    else
                    {
                        Console.WriteLine("Opilec se vrátil do hospody.");
                        break;
                    }

                }
                else
                {
                    if (opilec < cesta.Length - 1)
                    {
                        cesta[opilec] = '-';
                        opilec++;
                        cesta[opilec] = '#';
                        kroku++;
                    }
                    else
                    {
                        Console.WriteLine("Opilec šťastně dorazil domů.");
                        break;
                    }
                }
                Console.Write("Hospoda");
                for (int i = 0; i < cesta.Length; i++)
                    Console.Write(cesta[i]);
                Console.Write("Doma");
                }
                Console.WriteLine("Zabralo mu to {0} kroků", kroku);
                Console.WriteLine("Pro opakování ztiskni >5<");
                xxx = Console.ReadKey().KeyChar;
            }

        }
    }
}
 
Odpovědět  +1 2.7.2015 13:44
Avatar
hanpari
Redaktor
Avatar
hanpari:

Ta tvoje metoda HodDoHospody je sice vynalézavá, ale ve skutečnosti ti stačí tohle, pokud chceš náhodně vybrat ano/ne:

var r = new Random();
var b = Convert.ToBoolean(r.Next(0,2));

jestli chceš OOP, tak to udělej pomocí WPF graficky. Nebo to přepiš pomocí LINQ, ale to není OOP :)

 
Nahoru Odpovědět  +1 2.7.2015 14:56
Avatar
Ondřej Krsička
Redaktor
Avatar
Odpovídá na hanpari
Ondřej Krsička:

Díky za radu. Mně šlo právěže o to jak to napsat. Jakože jaký třídy, v nich metody, proměnné atd. Prostě opravdu souhra objektů či jak to nazvat. Nedokážu udělat komplexní OOP program, umím jenom malé metody. Můžeš kdyžtak doporučit nějakou knihu / návod nebo mi poradit, jak si to procvičit?

 
Nahoru Odpovědět 2.7.2015 15:07
Avatar
hanpari
Redaktor
Avatar
hanpari:

Pokud se chceš naučit programovat, jdi na checkio.org.

Já jsem známý tím, že v OOP takový zlatý grál nevidím, takže mi to přijde, jako ti ukazovat, kudy nejrychleji do pekla. :)

Hezká knížka je ale tato:
https://www.zonerpress.cz/…vrhove-vzory

Ale je trochu náročnější.

 
Nahoru Odpovědět 2.7.2015 15:21
Avatar
Ondřej Krsička
Redaktor
Avatar
Odpovídá na hanpari
Ondřej Krsička:

Sice je vyprodaná, ale díky :D

 
Nahoru Odpovědět 2.7.2015 15:29
Avatar
hanpari
Redaktor
Avatar
Odpovídá na Ondřej Krsička
hanpari:

Tak zkus jinde, nebo si ji přečti anglicky:
http://it-ebooks.info/book/202/

Ale dřív než začneš OOP, měl bys zkusit redukovat svůj stávající kód tak na třetinu. Nevím, co máš za IDE, ale pravděpodobně na tebe řve, že vlevo a vpravo nikde nepoužíváš. Proměnné xxx a yyy jsou také úplně zbytečné. C# myslím zná cyklus Do while. Také se zamyslí, jestli bys nemohl vhodněji využít switch-case místo if-else.

Podrženo, sečteno. Zatím pořádně nevyužíváš základní konstrukce, takže zadělávat si v šišce na další zmatek s OOP, ti moc neprospěje :)

PS: Ale jinak tě musím pochválit, že na to jdeš přes příkazovou řádku. Spousta jiných se na tvém místě se snaží začínat rovnou s XNA :)

Editováno 2.7.2015 17:24
 
Nahoru Odpovědět  +1 2.7.2015 17:22
Avatar
Ondřej Krsička
Redaktor
Avatar
Odpovídá na hanpari
Ondřej Krsička:

Mám Visual C# Express 2010.
Nevím, nic na mě neřve :D.
No, zkusím si to dnes večer ještě přepsat a dám si víc záležet. Kdyžtak ti to uploadnu.

 
Nahoru Odpovědět  +1 2.7.2015 20:14
Avatar
hanpari
Redaktor
Avatar
Odpovídá na Ondřej Krsička
hanpari:

Zamysli se, jestli opravdu potřebuješ ten přepínač Ano/Ne

Nestačí ti tohle? Doleva -1, doprava +1

int pos = 0;
var r = new Random();
for (int i = 0; i < 1000; i++) {
        pos -= r.Next(0,2)==0?-1:1;
        Console.WriteLine(pos);
}

Console.ReadKey();
 
Nahoru Odpovědět 2.7.2015 20:34
Avatar
Ondřej Krsička
Redaktor
Avatar
Ondřej Krsička:

Jo a v té mé metodě si můžu ovlivňovat pravděpodobnost toho true / false.
Kód jsem zkrátil o 20 řádků :D :

using System;
using System.Threading;

namespace Opilcova_procházka_2
{
    class Program
    {
        static bool Kam()
        {
            var a = new Random();
            bool b = Convert.ToBoolean(a.Next(0,2));
            return b;
        }
        static void Main(string[] args)
        {
            char c = '5';
            do
            {
                Console.WriteLine("Zadej vzdálenost hospody od domova.");
                int delka = int.Parse(Console.ReadLine());
                int opilec = delka / 2;
                int kroku = 0;
                char[] cesta = new char[delka];
                for (int i = 0; i < delka; i++)
                    cesta[i] = '-';
                cesta[opilec] = '#';

                while (opilec > 0 && opilec < delka - 1)
                {
                    Thread.Sleep(100);
                    Console.Clear();
                    cesta[opilec] = '-';
                    if (Kam())
                    {
                        opilec++;
                        cesta[opilec] = '#';
                    }
                    else
                    {
                        opilec--;
                        cesta[opilec] = '#';
                    }
                    kroku++;

                    Console.Write("Hospoda");
                    for (int i = 0; i < delka; i++)
                        Console.Write(cesta[i]);
                    Console.Write("Doma");
                }
                //závěr
                if (opilec == 0)
                    Console.WriteLine("\nOpilec se vrátil do hospody.");
                else
                    Console.WriteLine("\nOpilec šťastně dorazil domů.");

                Console.WriteLine("\nPro opakování ztiskni 5.");
                c = Console.ReadKey().KeyChar;
            }
            while (c == '5');
        }
    }
}
Akceptované řešení
+5 Zkušeností
Řešení problému
 
Nahoru Odpovědět 2.7.2015 20:57
Avatar
Ondřej Krsička
Redaktor
Avatar
Odpovídá na hanpari
Ondřej Krsička:

pos -= r.Next(0,2)==0?-1:1;

Tohle nechápu.

PS: Už jsem to znovu zkrátil na 57 řádků. Ale dávat to sem nebudu.

Editováno 2.7.2015 21:02
 
Nahoru Odpovědět 2.7.2015 20:59
Avatar
Odpovídá na Ondřej Krsička
Ondřej Štorc:

To by se dalo přepsat na toto:

if(r.Next(0,2) == 0)
   pos -= -1
else
   pos -= 1

http://www.dotnetperls.com/ternary

Nahoru Odpovědět  +1 2.7.2015 21:06
Život je příliš krátký na to, abychom bezpečně odebírali USB z počítače..
Avatar
hanpari
Redaktor
Avatar
Odpovídá na Ondřej Krsička
hanpari:

Co se týče té pravděpodobnosti, nic ti nebrání to napsat takto :)

pos -= r.Next(0,100)<40?-1:1;  //40% že půjde doleva, 60% že půjde doprava
 
Nahoru Odpovědět  +1 2.7.2015 22:11
Avatar
vodslon
Člen
Avatar
Odpovídá na Ondřej Krsička
vodslon:

Ahoj, ale pokud se ptal na to aby to bylo více objektově, tak těma změnama si zkrátil zápis, ale objekt si nepřidal. Ta myšlenka by měla být taková, že máš vše co je nějáký celek v objektu, celek je ale možná blbej název. Prostě nějákou logiku, kterou potom můžeš i repoužít. Třeba tady bys to měl Cestu, Cesta by měla třeba metodu VykresliCestu() podle nějákých parametrů. Takže bys na začátku kodu neměl ten cyklus, ale jenom Cesta cesta = new Cesta() a podtím cesta.Vykresli­Cestu()...tře­ba jako další hru bys měl závod dvou opilců domů a tam bys zase použil tu cestu, aniž by si jí musel dělat znovu. Ideální stav by tedy byl třeba jenom v mainu mít třídu HraKamSeVydaOpilec a ta třída by brala dva parametry instanci typu opilec a cesty....

 
Nahoru Odpovědět  +1 3.7.2015 8:03
Avatar
hanpari
Redaktor
Avatar
Odpovídá na vodslon
hanpari:

Budu parafrázovat...
Když jediné, co umíš, je bouchat kladivem, tak všechny problémy připomínají hřebíky.
Nemá smysl uměle řešit opilcovu procházku pomocí objektů. Bylo by to krkolomné a zbytečné, nota bene pokud nelze stavět na solidních základech.
Připomíná to situaci, kdy se doplazíš ke kaluži, a místo aby ses učil skákat, budeš si chtít postavit letadlo, aby ses dostal na druhou stranu.
Není důvod začínat s objekty, pokud neznáš základní konstrukce a datové typy konkrétního jazyka. Jinak ti hrozí, že budeš vymýšlet znovu kolo.

Je dobré se porozhlédnout i jinde než ve světě IT. Moc hezká je třeba definice sportu: S co nejmenším úsilím, co nejvyšší možný výkon.

Ovšem možná dáváš přednost sokolské definici. Ta praví: "S co největším úsilím, co největší možný výkon." Spolu se smutným Tondou dávám přednost prvnímu.

(Poznámka pro zvědavé. Jde o literání odkaz na dílo spisovatele Žáka.)

 
Nahoru Odpovědět 3.7.2015 8:44
Avatar
vodslon
Člen
Avatar
Odpovídá na hanpari
vodslon:

Dobře, ale tu konzoli psal člověk, co určitě základní představy o konstrukci má. A samozřejmně, že je občas vytvářet jednoduchou věc nuceně objektově vlastně zbytečné, ale právě na těch jenoduchých příkladech se to učí.

 
Nahoru Odpovědět 3.7.2015 10:02
Avatar
hanpari
Redaktor
Avatar
Odpovídá na vodslon
hanpari:

určitá základní představa != solidní základy :)

Na procvičení OOP je lepší použít něco, kde se ty objekty samy nabízejí, namátkou třeba karetní hry.
Na řešení jednoduchého algoritmu to je zbytečné. Navíc zdejšímu osazenstvu by prospělo, kdyby se snažilo řešit problémy bez OOP. Aspoň by pak nevznikaly tuny zbytečného kódu místo přiměřených pár řádek :)

 
Nahoru Odpovědět 3.7.2015 10:13
Avatar
vodslon
Člen
Avatar
Odpovídá na hanpari
vodslon:

Já prostě zastávám názor, že co má jenom trochu smysl dávat do objektů by tam mělo být, ale to at si už každý dělá podle sebe.

 
Nahoru Odpovědět 3.7.2015 12:05
Avatar
hanpari
Redaktor
Avatar
Odpovídá na vodslon
hanpari:

V tom případě se asi shodneme, že se neshodneme. :)

 
Nahoru Odpovědět 3.7.2015 12:18
Avatar
Ondřej Krsička
Redaktor
Avatar
Odpovídá na vodslon
Ondřej Krsička:

No přesně to jsem myslel. Já jakože jednotlivý metody udělám, ale navrhnout celkově co bude dělat, to už mi dělá problém. Nemám v tom skill. To by nejspíš chtělo si projít nějaký open-source, ale moc nevím jaký a kde :/
Možná by bylo dobrý trochu umět i takový ty diagramy tříd a tak, že by mi to pomohlo do toho prohlédnout, ale nevím, jestli by to k něčemu bylo.

Editováno 3.7.2015 13:52
 
Nahoru Odpovědět 3.7.2015 13:49
Avatar
hanpari
Redaktor
Avatar
Odpovídá na Ondřej Krsička
hanpari:

Zkusil jsem to trochu zkrátit po svém :)

http://pastebin.com/wFsAc7pV

Výsledek je cca 35 řádků, spousta z toho jsou ale závorky :)
Není to zdaleka nejkratší, co by se dalo. Je tam hodně míst, které bych mohl zkrátit silou, ale snížila by se čitelnost. Také jsem se nesnažil o nic originálního, šlo mi jen o úpravu stávajícího kódu. Jen tak na ukázku, co se dá vymyslet :)

Pokud to někoho zajímá, ať zadá do google code golf nebo programming golf.

 
Nahoru Odpovědět 3.7.2015 13:49
Avatar
Ondřej Krsička
Redaktor
Avatar
Odpovídá na hanpari
Ondřej Krsička:

Wow, tolik věcí co neznám. No až se budu nudit, místo cska se budu věnovat např. těm otazníkům :D Díky ti za alternativní řešení.

 
Nahoru Odpovědět  +1 3.7.2015 13:59
Avatar
Ondřej Krsička
Redaktor
Avatar
Odpovídá na hanpari
Ondřej Krsička:

O čem je to checkio.org?

 
Nahoru Odpovědět 9.7.2015 22:33
Avatar
qwertyW
Redaktor
Avatar
Odpovídá na Ondřej Krsička
qwertyW:

V zásadě postupně plnis programátorské ulohy,které systém sám vyhodnocuje a za které se ti odemyká přístup k jinym.

Editováno 10.7.2015 8:36
Nahoru Odpovědět 10.7.2015 8:35
Programuji, tedy jsem.
Avatar
hanpari
Redaktor
Avatar
Odpovídá na Ondřej Krsička
hanpari:

Existuje hodně stránek, které dělají totéž co checkio. Nabízejí ti programátorské úlohy a ty se je snažíš vyřešit pomocí kódu.
Checkio je ovšem podle mne výjimečné. Má velmi propracovaný a jednotný systém; nakonec ho v podstatě dělal jednom jeden člověk, Bryukh.
Ty ostaní systémy jsem zkoušel, ale většinou stojí za pendrek. Ne že by se nedaly používat, ale jsou moc roztříštěné a nesedly mi :)

Samotné úkoly jsou na checkio velmi zajímavé a řešení se testuje opravdu důkladně.
V tamější komunitě bez nadsázky najdeš nejlepší programátory na světě, a to nejen v pythonu.
Komunitu netvoří převážně náctiletí. :)

A navíc, checkio má Vekyho :)

Velká výhoda je i v tom, že se (zatím) programuje výhradně v pythonu. Takže krom toho, že tě systém donutí se naučit výborný programovací jazyk, tak si díky prohlížení cizích řešení rozšíříš rozhled, a to podstatně.

Takže to shrnu:

  • 1/ Získáš praxi v programování, zejména v algoritmizaci (naprosto přenositelnou),
  • 2/ naučíš se do hloubky vynikající programovací jazyk, což ti pomůže se naučit jakýkoliv jiný programovací jazyk,
  • 3/ naučíš se, jak stejný problém řeší různí lidé s různým přístupem, zkušenostmi apod,
  • 4/ potkáš Vekyho :)
 
Nahoru Odpovědět 10.7.2015 14:40
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 26 zpráv z 26.