static class jako modul, namespace, using, using static, alias, public vs. internal, převod objektu na text a zpětusing na prvních řádcích každého programu.Tenhle blok je jen pro vás — dětem ho nepromítejte.
| Fáze | Co se děje | Čas |
|---|---|---|
| Motivace | Otevřete jejich vlastní soubor a zkuste v něm něco najít | 10 min |
| Co je modul | Bloky 2–3 + ukázka 1 | 15 min |
using a namespace |
Bloky 4–6 + ukázka 2 | 20 min |
| Statická třída jako modul | Blok 7 + ukázka 3 | 15 min |
| Objekt na řádek a zpět | Blok 8 + ukázky 4–5 | 20 min |
| Cvičení | Děti pracují samy, vy obcházíte | 55 min |
| Shrnutí | Před/po: kolik řádků má hlavní část | 5 min |
Hlavní myšlenka hodiny: rozdělení kódu není kosmetika. Je to jediný způsob, jak se dá program po pár týdnech ještě číst. Děti to samy necítí — proto začínáme ukázkou jejich vlastního neuklizeného souboru.
Jedno velké upozornění k našemu prostředí. Tlačítko ▶ Spustit v prohlížeči
umí přeložit jeden kus kódu. Nedokáže načíst druhý soubor z disku.
Proto dnes budeme „soubory" simulovat: každou část ohraničíme komentářem
// ===== soubor Data.cs ===== a napíšeme ji jako samostatnou třídu.
Ve Visual Studio Code doma (viz úvodní hodina) je to doopravdy jeden soubor
Data.cs, druhý Nastroje.cs a tak dál — a nic víc se nemění.
Tuhle větu během hodiny zopakujte aspoň třikrát.
Druhé upozornění: namespace se v prohlížečovém spouštěči nepřeloží
(hlásí CS7021). Není to chyba studenta ani vaše — je to vlastnost režimu,
ve kterém prohlížeč kód spouští. Proto jsou všechny ukázky s namespace
dnes jen „na čtení" a nemají tlačítko Spustit.
Než cokoli vysvětlíte, udělejte tohle:
Tohle udělá pro motivaci víc než jakákoli teorie. Dnešní hodina má jediný cíl: aby se v tom souboru dalo něco najít do pěti vteřin.
Druhý argument, který na děti platí: „až budete dělat projekt ve dvou, nemůžete oba psát do jednoho souboru." Rozdělení kódu je i způsob, jak se dá spolupracovat.
Zatím jsi psal všechno do jednoho kusu kódu. To funguje, dokud je program malý. Jakmile má pár set řádků, začne se dít tohle:
Modul je pojmenovaná část programu, která má na starosti jednu věc.
V C# je modul v podstatě jeden soubor .cs a v něm jedna třída.
| Co chceš | Jak se to jmenuje | Kde to bydlí |
|---|---|---|
| seznamy míst, cen, jmen | Data |
Data.cs |
| kostky, procenta, pruh životů | Nastroje |
Nastroje.cs |
třídy Postava, Prisera |
Model |
Postava.cs, Prisera.cs |
| samotný průběh hry | hlavní program | Program.cs |
Pravidlo, které se vyplatí: jeden soubor = jedna třída = jedno téma.
Když se soubor jmenuje Data.cs, nesmí v něm být souboj.
Naše tlačítko ▶ Spustit umí přeložit jeden kus kódu, ne celý projekt. Proto budeme „soubory" jen naznačovat komentářem:
// ===== soubor Data.cs =====
static class Data { ... }
// ===== konec Data.cs =====
Doma ve Visual Studio Code je to opravdový soubor a žádný komentář nepotřebuješ.
Všechno ostatní — názvy, static, public — zůstává úplně stejné.
Modul s daty a pomocnými metodami nechceš „vyrábět" přes new.
Potřebuješ ho jen jednou a pořád stejný. Přesně na to je static class:
Console.WriteLine($"Míst na mapě: {Data.Mista.Count}");
Console.WriteLine($"První místo: {Data.Mista[0]}");
Console.WriteLine($"Cena lektvaru: {Data.CenaLektvaru} zl.");
static class Data
{
public const int CenaLektvaru = 25;
public static List<string> Mista = new List<string>
{
"Mlžný hvozd",
"Skřetí tábor",
"Zřícenina Vraního hradu"
};
}
Všimni si tří věcí:
class je static — třída se nedá vyrobit přes new,static (nebo const),Data.Mista.To poslední je přesně to, co dělá modul modulem. Když někde v kódu uvidíš
Data.Mista, hned víš, odkud to je.
Do modulu nepatří jen data, ale hlavně pomocné metody, které používáš pořád dokola. Dej je na jedno místo a napiš je jenom jednou:
Random kostka = new Random(7);
Console.WriteLine($"Hod k6: {Nastroje.HodKostkou(kostka, 6)}");
Console.WriteLine($"Hod k20: {Nastroje.HodKostkou(kostka, 20)}");
Console.WriteLine($"Procenta: {Nastroje.Procenta(30, 120)} %");
Console.WriteLine(Nastroje.PruhZivotu(75, 120));
static class Nastroje
{
public static int HodKostkou(Random kostka, int sten)
{
return kostka.Next(1, sten + 1);
}
public static int Procenta(int cast, int celek)
{
if (celek == 0)
{
return 0;
}
return cast * 100 / celek;
}
public static string PruhZivotu(int zivoty, int max)
{
int delka = zivoty * 20 / max;
return $"│{new string('█', delka).PadRight(20, '░')}│ {zivoty}/{max}";
}
}
Zkus si představit, kolikrát bys PruhZivotu psal bez modulu.
Teď ho máš jednou — a když se ti nelíbí, opravíš ho na jednom místě.
Na začátku skoro každého C# programu jsou řádky jako using System;.
Znamenají: „budu používat věci z téhle skupiny, nechci psát jejich celé jméno."
Celé jméno třídy Console je totiž System.Console. Bez using bys musel psát:
System.Console.WriteLine("Ahoj");
S using System; stačí Console.WriteLine("Ahoj"). Nic víc v tom není —
using nic nenačítá ani nestahuje, jen zkracuje psaní.
| Zápis | Co dělá |
|---|---|
using System; |
zpřístupní krátká jména ze skupiny System |
using System.Collections.Generic; |
odsud je List<T> a Dictionary<K,V> |
using System.Linq; |
odsud je Sum, Where, OrderBy |
using static System.Math; |
umožní psát Max(a, b) místo Math.Max(a, b) |
using Kostky = Nastroje; |
dá třídě přezdívku (alias) |
Moderní C# má takzvané implicitní usingy — nejběžnější skupiny
(System, System.Linq, System.Collections.Generic a další)
jsou zapnuté automaticky. Proto ti Console i List<T> fungují,
i když jsi žádný using nenapsal. Ve starších projektech je uvidíš nahoře vypsané.
Dvě méně známé podoby using, které se hodí znát, až budeš číst cizí kód:
// alias = přezdívka pro dlouhý název; patří vždy úplně nahoru
using Kostky = Nastroje;
Console.WriteLine($"Vetší z čísel: {Math.Max(12, 30)}");
Console.WriteLine($"Odmocnina: {Math.Sqrt(81)}");
Console.WriteLine($"Přes přezdívku: {Kostky.HodKostkou(new Random(3), 6)}");
static class Nastroje
{
public static int HodKostkou(Random kostka, int sten)
{
return kostka.Next(1, sten + 1);
}
}
Všimni si, že using Kostky = Nastroje; je na prvním řádku.
Všechny using musí být nad příkazy — jinak překladač zahlásí chybu.
Kdy alias použít: když máš dvě třídy se stejným krátkým jménem z různých knihoven. Jinak ho nepoužívej — kód se tím hůř čte.
Když roste projekt, nestačí jména tříd — dvě knihovny můžou mít obě třídu Hrac.
Proto se třídy zabalují do jmenných prostorů:
// soubor Data.cs
namespace CsQuest.Herni;
static class Data
{
public const int CenaLektvaru = 25;
}
// soubor Program.cs
using CsQuest.Herni;
Console.WriteLine(Data.CenaLektvaru);
Čti to takhle: namespace je příjmení třídy. Celé jméno naší třídy je
CsQuest.Herni.Data. Řádek using CsQuest.Herni; znamená „v tomhle souboru
můžu říkat jen Data".
A tady je ten most, který si zapamatuj:
| Python | C# |
|---|---|
import data |
using CsQuest.Herni; |
data.MISTA |
Data.Mista |
| jeden soubor = jeden modul | jeden soubor = jedna třída |
| modul najde podle názvu souboru | třídu najde podle namespace v projektu |
Blok výše je schválně jen na čtení — namespace naše tlačítko ▶ Spustit
nepřeloží (ohlásí CS7021). Je to omezení prohlížečového režimu, ne chyba.
Ve Visual Studio Code doma namespace funguje normálně a používá ho
každý skutečný projekt.
U modulů je důležité rozhodnout, co je „vývěsní štít" a co je vnitřní šuplík:
| Slovo | Kdo na to vidí |
|---|---|
public |
kdokoli, i cizí projekt |
internal |
jen kód ve stejném projektu |
private |
jen ta samá třída |
Pravidlo pro dnešek: public jen to, co má někdo zvenku opravdu volat.
Zbytek nech private. Modul se pak dá měnit zevnitř bez strachu,
že tím něco rozbiješ jinde.
Console.WriteLine(Nastroje.PruhZivotu(60, 120));
Console.WriteLine(Nastroje.PruhZivotu(15, 120));
static class Nastroje
{
private const int SirkaPruhu = 20;
private static int Delka(int zivoty, int max)
{
return zivoty * SirkaPruhu / max;
}
public static string PruhZivotu(int zivoty, int max)
{
return $"│{new string('█', Delka(zivoty, max)).PadRight(SirkaPruhu, '░')}│ {zivoty}/{max}";
}
}
Zvenku existuje jediná metoda PruhZivotu. Jak se počítá délka je vnitřní věc
modulu — a to je přesně správně.
Poslední dnešní kousek. Když chceš postavu uložit, musíš z ní udělat text. A když ji chceš načíst, musíš text zase rozebrat. Dvě metody, které to řeší:
NaRadek() — objekt → text (je to metoda objektu, ví o sobě všechno),ZRadku(...) — text → objekt (je static, protože objekt teprve vznikne).Postava hrdina = new Postava("Elrik", 120, 13);
string radek = hrdina.NaRadek();
Console.WriteLine($"Uloženo jako: {radek}");
Postava nactena = Postava.ZRadku(radek);
Console.WriteLine($"Načteno zpět: {nactena.Jmeno}, {nactena.Zivoty} HP, síla {nactena.Sila}");
class Postava
{
public string Jmeno { get; set; }
public int Zivoty { get; set; }
public int Sila { get; set; }
public Postava(string jmeno, int zivoty, int sila)
{
Jmeno = jmeno;
Zivoty = zivoty;
Sila = sila;
}
public string NaRadek()
{
return $"{Jmeno};{Zivoty};{Sila}";
}
public static Postava ZRadku(string radek)
{
string[] casti = radek.Split(';');
return new Postava(casti[0], int.Parse(casti[1]), int.Parse(casti[2]));
}
}
Tenhle pár metod je základ každého ukládání hry. Na disk se to zapíše až doma
(File.WriteAllLines), ale převod objektu na text je ta zajímavá část —
a tu už umíš.
Co se v C# opravdu děje. Python načítá modul za běhu: import data
najde soubor data.py, spustí ho a vyrobí objekt modulu. C# nic takového nedělá —
překladač dostane všechny .cs soubory projektu najednou a udělá z nich
jednu sestavu (.dll nebo .exe). Rozdělení do souborů je proto v C#
čistě organizační věc pro člověka, ne technická nutnost pro počítač.
Praktické důsledky, které stojí za zmínku:
if __name__ == "__main__":. C# spustí jen vstupní bod
programu. Obdobou testovacího bloku je samostatný konzolový projekt
nebo testovací projekt (xUnit).using není import. Nic nenačítá. Odkaz na cizí knihovnu se přidává
jako balíček (dotnet add package) nebo reference na projekt.
Přesné srovnání: pip install ≈ dotnet add package, import ≈ using.Co dnes vědomě zjednodušujeme. Neřešíme partial class, sealed,
file-scoped typy ani viditelnost napříč sestavami. Stačí, když si děti odnesou
dvojici „soubor = třída" a „using = zkratka jména".
Na co si dát pozor u hodnocení. Odměňujte krátkou hlavní část programu,
ne počet tříd. Jedna dobře pojmenovaná Nastroje je lepší než pět tříd
po jedné metodě.
| Chyba | Jak se projeví | Co s tím |
|---|---|---|
metoda v modulu bez static |
CS0120 — je potřeba instance |
do statické třídy patří jen statické členy |
new Data() |
CS0712 |
statická třída se nevyrábí, volá se přes tečku |
zapomenuté public |
jinde ji „nevidíš" | pomocné metody public, vnitřnosti private |
namespace v okně s Spustit |
CS7021 |
namespace patří do projektu ve VS Code |
| třída nahoře mezi příkazy | CS8803 |
příkazy nahoře, třídy dole |
int.Parse na prázdný text |
výjimka za běhu | zkontroluj Split a počet částí |
všechno public static |
program vypadá jako jedna hromada | ptej se: volá to někdo zvenku? |
Napřed to, co většina z vás má teď: všechno v jednom. Pak to samé, jen rozdělené. Program dělá přesně totéž.
Data.Mista čtvrté místo a spusť znovu.CenaLektvaru — kolik míst v kódu jsi musel upravit?Nastroje na Pomocnik (editor to zvládne, ty ručně).Data.Mista bez slova Data a přečti si chybu.Co si z toho odnést: modul není o tom, že program umí víc. Je o tom, že se v něm dá orientovat.
Dobrý modul ukazuje ven jen pár metod a zbytek schová. Tahle ukázka má sedm metod, ale zvenku se volají jen tři.
SirkaPruhu na 30 a sleduj, kolik míst jsi musel upravit.Nastroje.Delka(10, 100) — přečti si chybu.Nadpis(string text), která text orámuje.'█' za '#' a najdi, kde se mění.Co si z toho odnést: private není omezení, ale svoboda.
Co je uvnitř, můžeš kdykoli přepsat — zvenku to nikdo nepozná.
Všechna čísla a texty hry na jednom místě. Když chceš hru vyladit, otevřeš jediný soubor a neriskuješ, že rozbiješ pravidla.
StartovniZlato a sleduj celý výpis.public const string NazevHry a použij ho v nadpisu.Co si z toho odnést: vyvažování hry (jestli je moc lehká, nebo těžká) je pak otázka pár čísel v jednom souboru.
Objekt převedený na řádek textu a zase zpátky. To je celý základ ukládání hry.
Zlato a dopiš ho do NaRadek() i do ZRadku().; na | — pozor, musíš to změnit na obou místech.Co si z toho odnést: NaRadek() a ZRadku() musí vždycky sedět k sobě.
Když do jednoho něco přidáš, musíš to přidat i do druhého.
Finální podoba: čtyři moduly a hlavní část, která se dá přečíst nahlas. Přesně takhle by měl tvůj projekt vypadat po dnešní hodině.
Data.Obtiznosti a sleduj, jak se změní celá výprava.Souboj hlášku, když hrdina klesne pod 30 HP.Vypis.Co si z toho odnést: hlavní část programu má teď třicet řádků a čte se skoro jako popis hry. To je cíl.
Chyby kolem modulů vypadají divoce, ale je jich jen pár druhů.
| Hláška / projev | Co se stalo | Oprava |
|---|---|---|
CS0120 |
voláš metodu bez static přes jméno třídy |
dopiš static k metodě |
CS0708 |
v static class je nestatická položka |
ve statické třídě musí být všechno static |
CS0712 |
new Data() u statické třídy |
statická třída se nevyrábí |
CS0103 |
Mista místo Data.Mista |
k modulu se chodí přes tečku |
CS0122 |
položka je private |
co se volá zvenku, musí být public |
CS7021 |
namespace v okně se Spustit |
namespace jen ve VS Code, tady bez něj |
CS8803 |
třída napsaná nad příkazy | příkazy nahoře, třídy dole |
CS0111 |
dvě metody stejného jména i parametrů | přejmenuj jednu |
IndexOutOfRangeException |
Split vrátil míň částí |
zkontroluj oddělovač a počet sloupců |
FormatException |
int.Parse dostal text |
ukládáš a načítáš ve stejném pořadí? |
vše je public static |
modul přestal chránit své vnitřnosti | ptej se: volá to opravdu někdo zvenku? |
Skoro každá dnešní chyba má stejný lék: přečíst hlášku a podívat se
na slovo static. Nechte studenty hlášku přečíst nahlas dřív,
než začnou cokoli měnit. Ušetří to polovinu času.
Chyby IndexOutOfRangeException a FormatException se objeví až u cvičení 4.
Připravte si na ně jedno vysvětlení: „uložil jsi čtyři věci a načítáš tři —
tvoje NaRadek a ZRadku si nerozumí."
// ===== soubor Neco.cs =====. Doma je to opravdový soubor.Zadání:
Vytáhni všechna data hry z hlavní části programu do vlastního modulu
Data.
- Založ
static class Dataa dej do ní seznam míst💡 Poradit
Statická třída patří — jako každá třída — pod příkazy:static class Data{public static List<string> Mista = new List<string> { "Mlžný hvozd" };}
Nezapomeň napublici nastaticu položky.- Vypiš místa přes
Data.Mista💡 Poradit
K obsahu modulu se chodí vždycky přes jméno třídy a tečku:foreach (string m in Data.Mista)
Kdybys napsal jenMista, dostanešCS0103.- Přidej konstanty
NazevHryaCenaLektvaru💡 Poradit
public const string NazevHry = "CsQuest";public const int CenaLektvaru = 25;
Uconstsestaticnepíše — je statická automaticky.- Přidej seznam předmětů a jejich cen
💡 Poradit
Dva seznamy vedle sebe (stejné pořadí), nebo rovnou slovník:public static Dictionary<string, int> Ceny = new Dictionary<string, int>{{ "Lektvar", 25 },{ "Meč", 90 }};- Přidej nové místo a ověř, že se objeví samo
💡 Poradit
Dopiš řádek jen doData.Mistaa hlavní část nech úplně beze změny. Pokud se nové místo objevilo, modul funguje přesně tak, jak má.
| Úroveň | Co má zvládnout |
|---|---|
| Minimum | Body 1–2, seznam míst v modulu |
| Rozšíření | Body 3–4, konstanty a ceník |
| Výzva | Bod 5 plus seznam nepřátel pro každé místo |
Očekávaný výsledek: hlavní část neobsahuje ani jedno napevno napsané číslo
nebo název místa. Všechno je v Data.
Kde se zaseknou:
static u položky → CS0708. Připomeňte:
ve statické třídě je všechno statické.Mista bez Data. → CS0103. To je vlastně dobrá zpráva —
překladač hlídá, že víme, odkud data bereme.CS8803. Pravidlo z 15. hodiny platí i dnes.const u seznamu → CS0133. const jde jen u čísel, textů a bool.
U seznamu se používá static.Krok 5 je pointa. Zdůrazněte, že se hlavní část nezměnila. Ptejte se: „kde bys přidával místo před hodinou?"
Rychlíkům zadejte Data.Nepratele — seznam seznamů, ke každému místu jeden.
Toto je jedna z možných variant. Tvoje řešení se může lišit a to je v pořádku.
Zadání:
Postav modul
Nastrojes pomocnými metodami, které používáš pořád dokola.
- Vytvoř
static class Nastrojes metodouHodKostkou(Random, int)💡 Poradit
Metoda ve statické třídě musí být takystatic:public static int HodKostkou(Random kostka, int sten){return kostka.Next(1, sten + 1);}
Pozor nasten + 1— horní mez uNextse nikdy netrefí.- Přidej
Procenta(int cast, int celek)💡 Poradit
Hlídej dělení nulou:if (celek == 0) { return 0; }return cast * 100 / celek;
Násob nejdřív stem, jinak ti celočíselné dělení sežere výsledek.- Přidej
PruhZivotu(int zivoty, int max)💡 Poradit
Spočítej délku plné části a zbytek dopadni tečkami:int delka = zivoty * 20 / max;return new string('█', delka).PadRight(20, '░');- Schovej pomocné výpočty jako
private💡 Poradit
Konstantu šířky i výpočet délky nikdo zvenku nepotřebuje:private const int SirkaPruhu = 20;private static int Delka(int zivoty, int max) { ... }
Zvenku zůstane viditelná jenPruhZivotu.- Použij modul v malé simulaci tří kol
💡 Poradit
ZaložRandom kostka = new Random(4);, v cyklu ubírej životy oNastroje.HodKostkou(kostka, 10)a po každém kole vypišNastroje.PruhZivotu(...). Seed4zajistí, že výsledek bude pokaždé stejný.
| Úroveň | Co má zvládnout |
|---|---|
| Minimum | Body 1–2, dvě funkční metody |
| Rozšíření | Body 3–4, pruh životů a private vnitřnosti |
| Výzva | Bod 5 plus metoda Nadpis(string) s rámečkem |
Očekávaný výsledek: hlavní část neobsahuje žádný výpočet.
Jen volání Nastroje.Neco(...) a výpisy.
Kde se zaseknou:
cast / celek * 100 → vždycky 0. Celočíselné dělení. Násob první.kostka.Next(1, sten) → nikdy nepadne nejvyšší číslo.
Nechte je to odhalit na k6: kdo dostane šestku?static u metody → CS0708 nebo CS0120.private metoda volaná zvenku → CS0122. To je správně!
Ukažte, že překladač hlídá hranici modulu.Math.Max(0, zivoty) → při záporných životech spadne
new string('█', -3). Dobrá příležitost ukázat, že modul má být odolný.Diskuse na závěr: zeptejte se, kolikrát v jejich CsQuestu počítají procenta. Obvykle třikrát až pětkrát, pokaždé trochu jinak. To je přesně ten důvod.
Rychlíkům zadejte Nastroje.Zarovnej(string text, int sirka) nebo
metodu, která vrátí barevný stav ("v pohodě" / "zraněn" / "kriticky").
Toto je jedna z možných variant. Tvoje řešení se může lišit a to je v pořádku.
Zadání:
Rozděl program na tři „soubory": třídu
Postava, modulVypisa hlavní část.
- Napiš třídu
Postavas konstruktorem aToString()💡 Poradit
Obyčejná třída, tedy bezstatic— postav chceš víc:class Postava{public string Jmeno { get; set; }public Postava(string jmeno, int zivoty) { ... }}- Přidej modul
Vypiss metodouRadek(Postava p)💡 Poradit
Modul dostane celou postavu jako parametr:public static string Radek(Postava p){return $"{p.Jmeno,-8} {p.Zivoty,4} HP";}
Musí býtstatic, protožeVypisje statická třída.- Přidej
Vypis.Nadpis()aVypis.Cara()💡 Poradit
Čáru sestavíš z opakovaného znaku:public static string Cara() => new string('═', 46);
Nadpis pak vypadá jako čára, text, čára.- Ohranič každou část komentářem „souboru"
💡 Poradit
Před třídu napiš// ===== soubor Postava.cs =====a za ni// ===== konec Postava.cs =====. Doma ve VS Code to bude opravdový soubor a tyhle komentáře zmizí.- Vypiš celou družinu jednou smyčkou
💡 Poradit
List<Postava> druzina = new List<Postava>();
Naplň ji a pak:foreach (Postava p in druzina) { Console.WriteLine(Vypis.Radek(p)); }
Hlavní část má tak jen pár řádků.
| Úroveň | Co má zvládnout |
|---|---|
| Minimum | Body 1–2, třída a jeden výpis |
| Rozšíření | Body 3–4, nadpis a hranice „souborů" |
| Výzva | Bod 5 plus součet a průměr přes celou družinu |
Očekávaný výsledek: tři jasně oddělené části. Postava neví nic o výpisu,
Vypis nic nepočítá o soubojích, hlavní část jen spojuje.
Kde se zaseknou:
static u Postava → CS0712 při new Postava(...).
Ptejte se: kolik jich potřebuješ? Jednu, nebo víc?
Data a nástroje = static. Věci, kterých je víc = normální třída.Vypis.Radek bez static → CS0708.Vypis jako obyčejná třída → funguje to, ale musí se psát
new Vypis().Radek(p). Ukažte, proč je static lepší.MaxZivotu,
je tam 0 a program spadne. Dobrá lekce o výchozích hodnotách.Klíčová otázka pro celou třídu: „proč Vypis nepatří dovnitř Postavy?"
Odpověď: aby šlo změnit vzhled, aniž by se sáhlo na pravidla hry.
Tomu se říká oddělení odpovědností a je to nejdůležitější myšlenka hodiny.
Rychlíkům zadejte Vypis.Tabulka(List<Postava>), která vypíše
celou družinu včetně nadpisu a součtů jediným voláním.
Toto je jedna z možných variant. Tvoje řešení se může lišit a to je v pořádku.
Zadání:
Nauč postavu převést se na řádek textu a zase se z něj složit.
- Přidej
PostavametoduNaRadek()💡 Poradit
Obyčejná metoda objektu — ví o sobě všechno:public string NaRadek(){return $"{Jmeno};{Zivoty};{Sila}";}
Středník jako oddělovač se hodí, protože se v jménech nevyskytuje.- Přidej statickou metodu
ZRadku(string)💡 Poradit
Musí býtstatic— objekt teprve vznikne:public static Postava ZRadku(string radek){string[] casti = radek.Split(';');return new Postava(casti[0], int.Parse(casti[1]), int.Parse(casti[2]));}- Ulož celou družinu do
List<string>💡 Poradit
Simulujeme soubor seznamem řádků:List<string> soubor = new List<string>();foreach (Postava p in druzina) { soubor.Add(p.NaRadek()); }
Doma z toho budeFile.WriteAllLines("hra.txt", soubor).- Načti družinu zpátky a ověř, že sedí
💡 Poradit
Projdi řádky a skládej nové objekty:foreach (string r in soubor) { nactena.Add(Postava.ZRadku(r)); }
Potom porovnejSumneboCountpůvodní a načtené družiny.- Ošetři poškozený řádek
💡 Poradit
Před rozebráním zkontroluj počet částí a použijint.TryParse:if (casti.Length != 3) { return null; }if (!int.TryParse(casti[1], out int z)) { return null; }
Návratový typ pak budePostava?a při načítánínullpřeskočíš.
| Úroveň | Co má zvládnout |
|---|---|
| Minimum | Body 1–2, jeden objekt tam a zpět |
| Rozšíření | Body 3–4, celá družina |
| Výzva | Bod 5 plus hlášení, kolik řádků bylo poškozených |
Očekávaný výsledek: NaRadek() a ZRadku() tvoří pár —
co jedna zapíše, druhá přečte. Tomu se v praxi říká serializace.
Kde se zaseknou:
ZRadku bez static → CS0120. Vysvětlení pro děti:
„nemůžeš zavolat metodu objektu, který ještě neexistuje."NaRadek píše jméno, životy, sílu;
ZRadku čte jméno, sílu, životy. Program nespadne, jen se hra rozbije.
To je nejzákeřnější chyba dneška — nechte je ji najít samy.IndexOutOfRangeException.
Pravidlo: sáhneš na jednu, sáhni hned na druhou.int.Parse versus int.TryParse — ukažte rozdíl na řádku
Kája;devadesát;18. Parse shodí celý program, TryParse ho zachrání.Postava? s otazníkem — to je jen poznámka pro překladač,
že metoda smí vrátit null. Neřešte hlouběji, stačí „může vrátit nic".Proč neukládáme na disk. V prohlížeči nemáme soubory. Seznam řádků se ale
chová úplně stejně — a doma stačí přidat File.WriteAllLines / File.ReadAllLines.
Tuhle větu řekněte nahlas, ať vědí, že jim nic nechybí.
Rychlíkům zadejte ukládání ve formátu klíč=hodnota (jmeno=Elrik;hp=120),
které přežije i změnu pořadí sloupců.
Toto je jedna z možných variant. Tvoje řešení se může lišit a to je v pořádku.
Zadání:
Rozděl celý CsQuest na čtyři moduly. Hlavní část má zůstat krátká a čitelná.
- Založ modul
Datase všemi čísly a texty hry💡 Poradit
DoDatapatří všechno, co bys chtěl ladit: názvy míst, obtížnosti, startovní zlato, ceny. Pravidlo: když je v hlavní části číslo, patří do Data.- Přidej modul
Nastrojes kostkou a pruhem💡 Poradit
Vezmi metody z cvičení 2 —HodKostkouaPruhZivotu. Nic nevymýšlej znovu, jen je zkopíruj do nové statické třídy.- Přesuň
Postavado vlastního „souboru"💡 Poradit
TřídaPostavaať umíUtoc,ZranitaZije. Pravidla postavy patří do postavy, ne do hlavní části.- Přidej modul
Hras metodouSouboj(...)💡 Poradit
public static bool Souboj(Postava hrdina, string nepritel, int obtiznost, Random r)
Vraťtruepři vítězství. Uvnitř nech cyklus, ale vždy s pojistkoukolo <= 20, ať se nezacyklí.- Nech v hlavní části jen průběh výpravy
💡 Poradit
Hlavní část má být skoro jako scénář:foreach místo → Hra.Souboj(...) → výpis → když padne, break
Spočítej si řádky. Míň než 30 je výborné.
| Úroveň | Co má zvládnout |
|---|---|
| Minimum | Body 1–2, data a nástroje mimo hlavní část |
| Rozšíření | Body 3–4, postava a souboj ve svých modulech |
| Výzva | Bod 5 plus závěrečná bilance a hodnost podle zlata |
Očekávaný výsledek: hlavní část má kolem 25 řádků a dá se přečíst nahlas jako popis hry. Všechno ostatní je ve čtyřech pojmenovaných modulech.
Kde se zaseknou:
Data. Počítá to něco obecného? → Nastroje.
Je to vlastnost hrdiny? → Postava. Je to pravidlo hry? → Hra."static — pořád dokola. Tentokrát už by měli hlášku znát.kolo <= 20 může souboj běžet věčně,
když hrdina neublíží dost. Pojistka je v zadání schválně.Měřte to. Nechte je před začátkem spočítat řádky hlavní části a po skončení znovu. Ten rozdíl je nejlepší hodnocení dnešní hodiny.
Tři minuty na závěr: ať každý řekne, který modul se mu psal nejlíp.
Většinou Data — a to je dobře, protože je to i ten nejužitečnější.
Rychlíkům zadejte modul Ulozeni s metodami Uloz(List<Postava>) a
Nacti(List<string>), které využijí NaRadek() ze cvičení 4.
Toto je jedna z možných variant. Tvoje řešení se může lišit a to je v pořádku.
Ukliď svůj CsQuest do modulů a přines ho na příští hodinu — bude to základ finále.
- modul
Datase všemi čísly a texty hry (žádné číslo v hlavní části),- modul
Nastrojes alespoň třemi pomocnými metodami,- třídy
PostavaaPriserav jasně oddělených „souborech",- modul
Hras aspoň jednou metodou, která řídí souboj nebo výpravu,- v hlavní části méně než 40 řádků — jen průběh hry.
Bonus: přidej
NaRadek()aZRadku(), aby se postava dala uložit a načíst.
Tohle je poslední „stavební" úkol kurzu. Příští hodina je finále — a je mnohem příjemnější, když děti přijdou s programem, ve kterém se dá něco najít. Zdůrazněte to: „příště budete svoji hru ukazovat ostatním. Uklizený kód se předvádí líp."
Na co se při kontrole dívat: ne na počet modulů, ale na délku hlavní části. Nechte je napsat na první řádek komentář s počtem řádků hlavní části před úklidem a po něm. Ten rozdíl je celá známka.
Kdo to nestihne, ať ukliďí aspoň Data. Je to nejmenší krok
s největším viditelným efektem a nikoho nezablokuje.
Pro ty, kdo pracují doma ve VS Code: tady je ten úkol nejlepší —
můžou vyrobit opravdové soubory Data.cs, Nastroje.cs, Postava.cs,
Hra.cs a Program.cs. Připomeňte, že dotnet run je najde sám
a nic se nemusí „importovat".
Toto je jedna z možných variant, jak mohl úkol dopadnout. Tvoje řešení se může lišit a to je v pořádku.
Oficiální dokumentace je místo, kam se programátoři chodí podívat, když si chtějí něco ověřit nebo zjistit víc detailů. Je většinou v angličtině, ale to nevadí — zkus se orientovat podle názvu příkazu a podle ukázek kódu.
| Co jsme použili | Oficiální dokumentace | Co tam najdeš |
|---|---|---|
namespace |
Jmenné prostory | k čemu jsou a jak se skládají jména |
using |
Direktiva using |
všechny tři podoby včetně aliasů |
| implicitní usingy | Implicitní using |
proč nemusíš psát using System; |
static class |
Statické třídy | kdy se hodí a co do nich patří |
public / internal / private |
Modifikátory přístupu | kdo na co zvenku vidí |
| struktura projektu | Struktura projektu .NET | co je .csproj a jak najde soubory |
string.Split |
String.Split |
rozdělení textu na části |
string.Join |
String.Join |
spojení částí zpátky do řádku |
int.TryParse |
Int32.TryParse |
bezpečný převod textu na číslo |
List<T> |
List<T> |
seznam řádků, ze kterého se skládá výpis |
File.WriteAllLines |
File |
zápis a čtení souborů (doma ve VS Code) |
| balíčky | dotnet add package |
obdoba pip install z jiných jazyků |
Stránka o statických třídách je dnes nejužitečnější — má tam přesně ten příklad s pomocnými metodami, který stavíme ve cvičení 2.
Stránku o struktuře projektu ukažte na projektoru i těm, kdo nepracují doma.
Stačí, když uvidí, že .csproj nevyjmenovává soubory — bere prostě všechny
.cs v adresáři. Je to nejrychlejší způsob, jak pochopit rozdíl proti jazykům,
kde se moduly musí ručně importovat.
Pro rychlejší studenty, kteří dokončí cvičení dřív, nebo na posledních 10–15 minut.
| Cvičení | Odkaz | Proč se hodí |
|---|---|---|
| Programování — základy | umimeinformatiku.cz | čtení cizího kódu, dnes hlavně orientace v delším programu |
| Funkce a procedury | umimeinformatiku.cz | parametry a návratové hodnoty — základ každého modulu |
| Práce s textem | umimeinformatiku.cz | Split a Join, které dnes používáme při ukládání |
Sekce o funkcích je dnes nejvhodnější, protože modul není nic jiného než dobře pojmenovaná sbírka funkcí.
Ještě lepší bonus než online cvičení je ale tahle úloha: „Vezmi cizí program od spolužáka a rozděl ho na moduly. Nesmíš změnit, co dělá — jen kam to patří."
Refaktoring cizího kódu je dovednost, kterou v běžné výuce skoro nikdo netrénuje, a přitom je to v praxi to nejčastější, co programátor dělá. Navíc se u toho děti musí domluvit, což je půlka práce v týmu.