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í.
Avatar
Petr Navrátil:8.3.2020 15:20

Zdravim, rozhodl jsem se vytvorit primitivni hru kde uzivatel hada cislo ktere si mysli program. Zdrojovy kod:

#include <iostream>
#include <stdlib.h>
#include <time.h>

using namespace std;

void nahoda()
{
  srand(time(NULL));
}

int nahodne_cislo(int maximum)
{
    int random = 1 + rand() % maximum;
    return random;
}

int main()
{
    nahoda();
    int pocet = nahodne_cislo(200);
    int zvolenecislo;


    cout << "Vitej ve hre kde je tvym ukolem uhadnout cislo ktere si myslim." << endl;


    while(zvolenecislo != pocet)
    {
        cout << "Tvuj typ: ";
        cin >> zvolenecislo;

        if(zvolenecislo < pocet)
        {
            cout << "Myslim si vetsi cislo." << endl;
        }

        else if(zvolenecislo > pocet)
        {
            cout << "Myslim si mensi cislo." << endl;
        }
        else
        {
            cout << "Toto neni cislo!" << endl;
        }


    }
        if(zvolenecislo == pocet)
        {
           cout << "Uhadl jsi cislo ktere si myslim. Gratuluju!" << endl;
        }


    cin.get(); cin.get();
}

Vse funguje tak jak ma az na to ze chci docilit toho ze kdyz uzivatel napise cokoli jineho nez nejake cislo napr. pismeno aby mu to vyhodilo hlasku ve smyslu ze to neni cislo a at tedy zada cislo. V kodu je videt jak jsem se to snazil vyresit ale marne vzdy dojde akorat k zacykleni hlasky "Tvuj typ: Myslim si vetsi cislo." Je tu tedy nekdo kdo by mi poradil jak to vyresit? Predem diky za odpovedi.

 
Odpovědět
8.3.2020 15:20
Avatar
Roman
Člen
Avatar
Odpovídá na Petr Navrátil
Roman:8.3.2020 17:26

Za prve pri deklaraci promene "zvolenecislo" by jsi ji mel priradit vychozi hodnotu. Za druhe po precteni vstupu od uzivatele by jsi mel zjistit a osetri co jsi nacetl a v tomto kroku vyhodnotit co s nactenym vstupem. Takze v cyklu jako prvni krok provedes kontrolu vstupu pokud bude vstupem cislo pak budes pokracovat k vyhodnoceni zda je mensi nebo vetsi. Pokud vstupem nebude cislo pak vyhodis hlasku a opet budes nacitat vstup. Koukni na cctype

Editováno 8.3.2020 17:27
 
Nahoru Odpovědět
8.3.2020 17:26
Avatar
DarkCoder
Člen
Avatar
Odpovídá na Petr Navrátil
DarkCoder:8.3.2020 17:45

Správnou funkčností programu bych si nebyl tak jistý. Hláška: "Toto není cislo!" při uhodnutí čísla nepůsobí zrovna dvakrát přesvědčivě. V programu máš strukturální a logické chyby, ale nic co by se nedalo snadno opravit. Největší chybou je puštění neošetřené hodnoty dále do programu. Když si vypíšeš její hodnotu hned po jejím zadání, zjistíš, proč se cyklus opakuje. Validaci vstupu je nutné provádět ihned, vyhneš se tak mnoha nepředvídatelným událostem které mohou nastat. Struktura programu by měla vypadat následovně:

inicializace();
informace_o_hre();
while (cislo_nebylo_uhodnuto){
        vstup_uzivatele();
        validace_vstupu();
        vyhodnoceni_pro_vetsi_mensi();
}
informace_o_uhodnuti_cisla();

Validaci vstupu tedy provedeš po zadání vstupu. Testuješ na nekorektnost vstupu, po kterém vypíšeš informativní hlášku o neplatném vstupu a vyvoláš opakování cyklu pomocí příkazu continue.

Teď postupně k jednotlivým chybám a lepším způsobům:

Programuješ v C++ a tam mají hlavičky jinou podobu (použij cstdlib namísto stdlib.h a ctime namísto time.h).

#include <iostream>
#include <cstdlib>
#include <ctime>

Používáš neinicializovanou lokální proměnnou zvolenecislo. To může způsobit chybnou funkci programu, kdy Ti někdy zpracování programu skočí do cyklu a někdy ne. Inicializuj tuto proměnnou na číselnou hodnotu mimo rozsah vyhodnocení náhodného čísla ale platnou v rámci typu.

int zvolenecislo = 0;

Po zadání vstupu od uživatele netestuješ validaci proměnné, viz. odstavec výše. Cyklus správně testuješ na nerovnost, není tedy třeba uvnitř cyklu testovat na uhodnutí čísla. Zde použiješ příkazy v podobě if-elseif bez else.

while (zvolenecislo != pocet){
                cout << "Tvuj typ: ";
                cin >> zvolenecislo;

                // zde validace vstupu

                if (zvolenecislo < pocet){
                        cout << "Myslim si vetsi cislo." << endl;
                }
                else if (zvolenecislo > pocet){
                        cout << "Myslim si mensi cislo." << endl;
                }
}

Pokud se řízení programu dostane za cyklus, pak uživatel číslo uhodl, není třeba vyhodnocovat uhodnutí čísla pomocí if, hlášku o uhodnutí čísla můžeš přímo vypsat.

cout << "Uhadl jsi cislo ktere si myslim. Gratuluju!" << endl;

Strukturu programu a chyby v něm nyní znáš, jediným tvým úkolem teď bude zpracovat si sám funkci o validaci vstupu. Drobnou nápovědu v mém textu máš.

Nahoru Odpovědět
8.3.2020 17:45
"I ta nejlepší poučka postrádá na významu, není-li patřičně předána." - DarkCoder
Avatar
Odpovídá na DarkCoder
Petr Navrátil:8.3.2020 23:50

Dekuju, nejak jsem to sesmolil. Pokud ale napisu nejakou kravinu tak me to sice upozorni ze jsem nezadal cislo a vrati me to ale kdyz napisu cislo tak to preskoci tu smycku kde jsou podminky a hodi me to rovnou na konec tudiz vzdy se "trefím" do spravneho cisla.. viz. kod

void nahoda()
{
  srand(time(NULL));
}

int nahodne_cislo(int maximum)
{
    int random = rand() % maximum;
    return random;
}

int main()
{
    nahoda();
    int pocet = nahodne_cislo(200);
    string zvolenecislo = "a";
    int zvolenecisloint = 0;

    cout << "Vitej ve hre kde je tvym ukolem uhadnout cislo ktere si myslim." << endl;


    while(zvolenecisloint != pocet)
    {
        cout << "Tvuj typ: ";

            try
            {
                cin >> zvolenecislo;
                zvolenecisloint = stoi(zvolenecislo);
                break;
            }
               catch (invalid_argument& exception)
               {
                   cout << "Nebylo zadano cislo" << endl;
                   continue;
               }
               catch (out_of_range& exception)
               {
                   cout << "Cislo je prilis velke!" << endl;
                   continue;
               }


        if(zvolenecisloint < pocet)
        {
            cout << "Myslim si vetsi cislo." << endl;
            continue;
        }

        else if(zvolenecisloint > pocet)
        {
            cout << "Myslim si mensi cislo." << endl;
            continue;
        }

    }

    cout << "Uhadl jsi cislo ktere si myslim. Gratuluju!" << endl;
    cin.get(); cin.get();
    return 0;
}

Jak se to dá vyresit?

 
Nahoru Odpovědět
8.3.2020 23:50
Avatar
DarkCoder
Člen
Avatar
Odpovídá na Petr Navrátil
DarkCoder:9.3.2020 0:51

Chování programu by mělo být takové, aby o neplatném vstupu byl uživatel informován a vyzván pro zadání nové hodnoty. Jak jsem psal, test je třeba provádět pouze na chybné zadání. Pokud je typ vstupu v pořádku, neřešís to a provádění programu přejde do sekce vyhodnocování. Program Ti vyhodnocování přeskočí, protože příkazem break ukončuješ cyklus while. Cyklus while porovnává hodnoty na nerovnost, je tedy zbytečné používat příkazy continue při vyhodnocování menšího a většího čísla. Chyba to není, je to zbytečné a mnoho takových skoků působí nepřehledně. Sekce vyhodnocování bude tedy vypadat takto:

if (zvolenecisloint < pocet) {
     cout << "Myslim si vetsi cislo." << endl;
}
else if (zvolenecisloint > pocet) {
     cout << "Myslim si mensi cislo." << endl;
}
Akceptované řešení
+20 Zkušeností
+2,50 Kč
Řešení problému
Nahoru Odpovědět
9.3.2020 0:51
"I ta nejlepší poučka postrádá na významu, není-li patřičně předána." - DarkCoder
Avatar
Petr Navrátil:9.3.2020 18:41

Ok, dekuju.

 
Nahoru Odpovědět
9.3.2020 18:41
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 6 zpráv z 6.