Gothic I Gothic II Gothic III Risen Modding
Občas se stane, že potřebujete nějaký kód několikrát zopakovat. To pak můžete celej kód napsat 10x pod sebe, což ale není z programátorského hlediska zrovna hezký. Někdy ale ani nevíte kolikrát chcete určitý kód vykonat. Takovéto problémy pak řeší právě cykly. Jsou 2 druhy cyklů. Cykly, u kterých dopředu víte, kolikrát se bude určitý kód opakovat a cykli kde to nevíte. Začneme s cyklem s předem známým počtem opakování. Využijeme přitom toho, že funkce může volat sama sebe.

Cyklus s předem daným počtem opakování

func void Loop(var int i, var int count)
{
    // kód

    if (i < count)
    {
        Loop(i + 1, count);
    };
};

func void Main()
{
    Loop(0, 10);
};

V příkladu zavoláme z hlavní funkce funkci s parametry s počáteční hodnotou 0 a konečnou hodnotou 10. Na konci cyklu Loop pak vždy ověříme jestli je ještě proměnná i menší jak proměnná count a pokud je, zavoláme z funkce Loop funkci Loop se stejnými parametry, akorát proměnná i bude o jedničku větší. Tím zajistíme, že v našem případě podmínka if (i < count) přestane po 10 zavoláních funkce Loop platit a zdánlivě nekonečná smyčka se tak ukončí.

U scriptování módů pro Gothic ale v drtivé většině případů asi nebudeme vědět, kolikrát se má nějaká situace opakovat. Určitě si vzpomínáte na rozhovor s Vatrasem, který neskončil dokud mu hrdina neodpověděl na všechny tři otázky správně. Na to se hodí náš cyklus. Dokud bude hrdina lhát o své minulosti, cyklus se neukončí...

func void Loop()
{
    var int spravne;
    spravne = true;

    if (false) // Hrdina odpoví špatně na první otázku
    {
        spravne = false;
    };

    if (false) // Hrdina odpoví špatně na druhou otázku
    {
        spravne = false;
    };

    if (false) // Hrdina odpoví špatně na třetí otázku
    {
        spravne = false;
    };

    // Cyklus se znovu zavolá,
    // pokud udělal hrdina v nějaké otázce chybu
    if (spravne == false)
    {
        Loop();
    };
};

func void Main()
{
    // Hrdina se dá do rozhovoru s Vatrasem
    // a Vatras se ho poptá na minulost

    Loop();

    // A sem se hrdina dostane až po zodpovězení
    // všech tří otázek
};

Všimněte si, že cyklus s předem neznámým počtem opakování nepotřebuje žádné další parametry a celkově je lehčí na zkonstruování.

Cyklus ale může být zároveň i docela zákeřný. Pokud nějak poděláte ukončovací podmínku, bude do nekonečna něco vykonávat a většinou to skončí pádem celé hry! Nebo co když si k počítači sedne sedmileté dítě, které neumí vůbec anglicky a dialogy jen proklikává. Třeba nepřijde na to, jak se ze zákeřné Vatrasovi smyčky dostat. Zkusíme tedy náš předchozí kód upravit, aby sedmiletému hráči po pěti neúspěšných pokusech rovnou řekl, že už to nemá cenu a pustil ho z dialogu.

func void Loop(var int i, var int count)
{
    var int spravne;
    spravne = true;

    if (false) // Hrdina odpoví špatně na první otázku
    {
        spravne = false;
    };

    if (false) // Hrdina odpoví špatně na druhou otázku
    {
        spravne = false;
    };

    if (false) // Hrdina odpoví špatně na třetí otázku
    {
        spravne = false;
    };

    // Cyklus se znovu zavolá,
    // pokud udělal hrdina v nějaké otázce chybu
    if (spravne == false && i < count)
    {
        Loop(i + 1, count);
    }
    else
    {
        if (spravne == true)
        {
            // Gratulace hrdinovy
        }
        else
        {
            // Vynadání, ať hrdina neplýtvá jeho časem
        };
    };
};

func void Main()
{
    // Hrdina se dá do rozhovoru s Vatrasem
    // a Vatras se ho poptá na minulost

    Loop(0, 5);
};

Moc řádků kódu nepřibylo a naše sedmileté dítě nemusí natvrdo vypínat počítač :).
Google+