Vaša konzolová aplikácia napísaná v jazyku C bude fungovať v týchto krokoch:
V simulácii proti sebe bojujú dve armády. Každá armáda obsahuje bojové jednotky. Armáda musí mať počet jednotiek v intervale $\langle1,5\rangle$.
Bojová jednotka je reprezentovaná štruktúrou UNIT.
#define MAX_NAME 100 // maximalna dlzka nazvu/mena
typedef struct unit {
char name[MAX_NAME + 1]; // meno jednotky
const ITEM *item1; // prvy predmet v inventari
const ITEM *item2; // druhy predmet v inventari
int hp; // zdravie
} UNIT;
Bojová jednotka môže mať vo svojom inventári 1 alebo 2 predmety. Kapacita inventára je 2 sloty. To znamená, že jednotka môže byť vybavená 1 alebo 2 predmetmi, ktorých súčet slotov nepresahuje hodnotu 2.
Každá bojová jednotka musí mať aspoň 1 predmet v inventári. Najviac môže mať 2 predmety. Pri vytváraní armády vyberá používateľ svojim jednotkám predmety z dodanej databázy.
Každý predmet je reprezentovaný štruktúrou ITEM.
#define MAX_NAME 100 // maximalna dlzka nazvu/mena
typedef struct item {
char name[MAX_NAME + 1]; // nazov predmetu
int att; // utok
int def; // obrana
int slots; // pocet slotov, ktore zabera predmet v inventari
int range; // utocny dosah/dostrel predmetu
int radius; // sirka zasahu (alebo damage radius)
} ITEM;
Jednotky môžu byť vybavené len takými predmetmi, ktoré pochádzajú z dodanej databázy predmetov.
Táto databáza je reprezentovaná poľom items
. Toto pole je
deklarované v hlavičkovom súbore data.h
a definované v zdrojovom súbore
data.c
.
#define NUMBER_OF_ITEMS 16 // velkost databazy predmetov
const ITEM items[NUMBER_OF_ITEMS] = {
// predmety, ktore zaberaju 1 slot, zoradene podla atributu 'att'
{.name = "wand", .att = 12, .def = 4, .slots = 1, .range = 4, .radius = 2}, // kuzelna palica
{.name = "fireball", .att = 11, .def = 0, .slots = 1, .range = 3, .radius = 3}, // ohniva gula
{.name = "sword", .att = 9, .def = 2, .slots = 1, .range = 0, .radius = 0}, // mec
{.name = "spear", .att = 6, .def = 1, .slots = 1, .range = 1, .radius = 1}, // ostep
{.name = "dagger", .att = 4, .def = 0, .slots = 1, .range = 0, .radius = 0}, // dyka
{.name = "rock", .att = 3, .def = 0, .slots = 1, .range = 2, .radius = 1}, // skala
{.name = "armor", .att = 2, .def = 7, .slots = 1, .range = 0, .radius = 0}, // brnenie
{.name = "shield", .att = 2, .def = 6, .slots = 1, .range = 0, .radius = 0}, // stit
{.name = "gloves", .att = 1, .def = 4, .slots = 1, .range = 0, .radius = 0}, // rukavice
{.name = "helmet", .att = 1, .def = 5, .slots = 1, .range = 0, .radius = 0}, // helma
{.name = "aura", .att = 0, .def = 8, .slots = 1, .range = 0, .radius = 0}, // ochranna aura
// predmety, ktore zaberaju 2 sloty, zoradene podla atributu 'att'
{.name = "cannon", .att = 12, .def = 0, .slots = 2, .range = 4, .radius = 4}, // kanon
{.name = "axe", .att = 10, .def = 2, .slots = 2, .range = 1, .radius = 1}, // sekera
{.name = "hammer", .att = 8, .def = 2, .slots = 2, .range = 1, .radius = 2}, // kladivo
{.name = "crossbow", .att = 5, .def = 1, .slots = 2, .range = 3, .radius = 0}, // kusa
{.name = "slingshot", .att = 2, .def = 0, .slots = 2, .range = 2, .radius = 1} // prak
};
Používateľ po spustení programu vytvorí obidve armády. Bojové jednotky sa zadávajú z klávesnice (stdin). Povolený počet jednotiek v armáde je $\langle1,5\rangle$. Počiatočné zdravie každej jednotky je HP=100. Počas vytvárania armády môžu nastať chybové situácie, ktoré je nutné odhaliť.
Formát načítania obidvoch armád je nasledovný:
Každá jednotka sa načíta v samostatnom riadku, ktorý má nasledovný tvar.
unit_name item1 item2
Vysvetlivky:
unit_name
- meno jednotky, tester ho vždy zadá a nikdy nebude dlhšie
ako MAX_NAME
item1
- názov 1. predmetu v inventári (jednotka musí mať aspoň jeden
predmet)
item2
- názov 2. predmetu v inventári (tento predmet nie je nutné
zadať)
Po zadaní názvu predmetu sa vyhľadá konkrétny predmet v databáze items
.
Pod textom uvádzame príklad vstupu (stdin), pomocou ktorého sa načítajú obidve armády (prvá armáda má 2
jednotky a druhá armáda má 4 jednotky).
2
Palo cannon
Pankrac shield rock
4
Jaro dagger gloves
Bohus slingshot
Bohdan rock
Jergus spear spear
Počas vytvárania armády môže nastať niektorá zo 4 chybových situácií (nebudú sa kombinovať). Ak program odhalí niektorú z nich, vypíše sa príslušné chybové hlásenie a program skončí (return 0).
ERR_UNIT_COUNT
- táto chyba nastane, keď zadaný počet jednotiek nepatrí do intervalu $\langle1,5\rangle$. Nasleduje ukážka vstupu, ktorý spôsobí uvedenú chybu (prvá armáda má 6 jednotiek).
6
peter sword
john dagger wand
mike aura gloves
steve gloves shield
tom wand wand
kane dagger dagger
2
tim crossbow
paul fireball rock
ERR_ITEM_COUNT
- táto chyba nastane, keď jednotka nemá zadaný
predmet alebo je počet zadaných predmetov viac ako 2. Nasleduje ukážka vstupu, ktorý spôsobí uvedenú chybu (jednotka s menom paul
má až 3 predmety).
3
peter sword
john dagger wand
mike sword
5
tim crossbow
paul fireball rock armor
ivan wand gloves
igor axe
robo slingshot
ERR_WRONG_ITEM
- táto chyba nastane, keď používateľ zadá neplatný názov predmetu (neexistuje v databáze). Nasleduje ukážka vstupu, ktorý spôsobí uvedenú chybu (jednotka s menom paul
má zadané neplatné názvy obidvoch predmetov).
3
peter sword
john dagger wand
mike aura fireball
2
tim crossbow
paul paper dart
ERR_SLOTS
- táto chyba nastane, keď má jednotka v inventári 2
predmety a súčet ich slotov je viac ako 2. Nasleduje ukážka vstupu, ktorý spôsobí uvedenú chybu (jednotka s menom gabe
má predmety, ktorých súčet slotov je 4).
1
gabe hammer crossbow
1
henry sword
Pred začiatkom súboja sa vypíše podrobný prehľad oboch načítaných armád (pod sebou). V armáde sa vypíšu všetky vytvorené jednotky. Pre každú jednotku sa vypíše jej meno, predmety a zdravie. Nasledujúci príklad ilustruje vstup do programu a k nemu prislúchajúci výpis armád.
Vstup:
1
Gejza crossbow
2
Alojz hammer
Felix armor spear
Výpis armád pred začiatkom súboja:
Army 1
Unit: 0
Name: Gejza
HP: 100
Item 1: crossbow,5,1,2,3,0
Army 2
Unit: 0
Name: Alojz
HP: 100
Item 1: hammer,8,2,2,1,2
Unit: 1
Name: Felix
HP: 100
Item 1: armor,2,7,1,0,0
Item 2: spear,6,1,1,1,1
Vysvetlivky:
Unit:
predstavuje index jednotky resp. jej pozíciu na bojovom poli.att
, def
, slots
, range
a radius
.
Pravidlá formátovania:
Army
, Unit:
, Name:
, HP:
, Item 1:
a Item 2:
Príklad očakávaného správneho výstupu a reálneho výstupu programu, ktorý bude testerom tolerovaný.
Očakávaný správny výstup
Army 1
Unit: 0
Name: Gejza
HP: 100
Item 1: crossbow,5,1,2,3,0
Army 2
Unit: 0
Name: Alojz
HP: 100
Item 1: hammer,8,2,2,1,2
Unit: 1
Name: Felix
HP: 100
Item 1: armor,2,7,1,0,0
Item 2: spear,6,1,1,1,1
Výstup tolerovaný testerom
Army 1
Unit:0
Name:Gejza
HP: 100
Item 1: crossbow, 5, 1, 2, 3, 0
Army 2
Unit: 0
Name: Alojz
HP:100
Item 1: hammer,8, 2, 2 , 1 , 2
Unit: 1
Name: Felix
HP: 100
Item 1: armor,2 , 7 , 1 , 0 , 0
Item 2: spear,6 ,1 ,1 ,1 , 1
Bojové pole si predstavujeme ako 1D pole, v ktorom sú umiestnené bojové jednotky oboch armád.
Bojové pole je rozdelené na 10 pozícií (5 pozícií vľavo pre armádu 1 a 5 pozícií vpravo pre armádu 2). Pozície sa indexujú od stredu (hranice medzi armádami) smerom von.
Po načítaní armády sa rozmiestnia jednotky na bojové pole. Indexy načítaných jednotiek v rámci jednotlivých armád sa musia zhodovať s pozíciami na bojovom poli. Pre rozmiestnenie jednotiek platí, že jednotka s indexom 0 je najbližšie k stredu bojového poľa. Jednotka s indexom 1 je o 1 pozíciu ďalej od stredu, atď.
V nasledovnom príklade ilustrujeme rozmiestnenie konkrétnych jednotiek na bojové pole.
5
Milan hammer
Jano fireball aura
Palo crossbow
Peter spear armor
Lukas spear armor
5
Adam spear armor
Stano crossbow
Riso wand
Fero sword shield
Rudo fireball aura
Atribút $range$ predstavuje útočný dosah konkrétneho predmetu. Ak platí $pos <= range$, kde $pos$ je pozícia bojovej jednotky na bojovom poli, tak vtedy môže jednotka vykonať s daným predmetom útok. Cieľom každého útoku je vždy nepriateľská jednotka na pozícii 0.
Atribút $radius$ predstavuje akčný rádius konkrétneho predmetu. Hovorí o tom, koľko jednotiek sa zasiahne navyše okrem cieľovej nepriateľskej jednotky. Rádius sa šíri od stredu bojového poľa smerom von. Ak napr. $radius = 2$, znamená to, že okrem cieľovej nepriateľskej jednotky na pozícii 0 sa zasiahnu ešte 2 nepriateľské jednotky, konkrétne jednotky na pozíciách 1 a 2.
Na obrázku 5 vidíme ilustráciu útoku jednotky s menom Riso
na pozícii 2 v armáde 2, ktorá sa snaží zaútočiť na nepriateľskú armádu 1 (vľavo). Jednotka Riso
môže vykonať útok predmetom wand
, nakoľko tento predmet má útočný dosah 4 (platí, že $pos <= range$). Jednotka Riso
vykoná útok na nepriateľské jednotky v armáde 1 na pozíciách 0,1,2 nakoľko predmet wand
má akčný rádius 2.
Po vytvorení a výpise armád začína súboj, ktorý prebieha v kolách pokiaľ niektorá z armád nestratí všetky svoje jednotky (alebo obidve armády súčasne).
Postupnosť krokov v každom kole sa dá vyjadriť nasledujúcim pseudokódom.
while(!is_game_over()){
print_units(); // vypis armad na zaciatku kola
attack_army(); // armada 1 vykona utok
attack_army(); // armada 2 vykona utok
print_damage(); // vypis sposobenych zraneni
update_army(); // armada 1 sa aktualizuje
update_army(); // armada 2 sa aktualizuje
print_units(); // vypis armad na konci kola
}
Vysvetlivky:
is_game_over()
zistí, či súboj armád neskončil. To nastane, ak existuje armáda, ktorá stratila všetky svoje jednotky. Súboj môže skončiť aj remízou.
print_units()
vypíše jednotky v obidvoch armádach (vypíšu sa len mená a zdravie).
attack_army()
vykoná útok všetkých jednotiek v armáde útočníka na armádu obrancu.
print_damage()
vypíše prehľad o zraneniach spôsobených jednotlivými jednotkami počas útoku (vypíšu sa len tie jednotky a predmet, ktoré sa reálne zúčastnili útoku).
update_army()
aktualizuje armádu. To znamená, že sa aktualizuje zdravie všetkých jednotiek podľa spôsobeného zranenia a z armády sa odstránia všetky jednotky, ktoré boli počas útoku zničené, t.j. $HP <=0$.
print_units()
Táto funkcia má za úlohu vypísať aktuálny stav oboch armád. Vypíše sa len meno a zdravie každej jednotky. Na začiatku výpisu sa zobrazí poradové číslo armády, ktorá sa vypisuje. Meno a zdravie sú oddelené čiarkou. Jednotky sú oddelené medzerami. Pod textom je ukážka výstupu z tejto funkcie.
1: Niko,100 Odin,100
2: Oldo,100 Ondro,100 Oskar,100 Oto,100
print_damage()
Táto funkcia má za úlohu vypísať pre každú jednotku v oboch armádach zranenie, ktoré spôsobila nepriateľovi. Každá jednotka, ktorá spôsobila zranenie sa vypíše v samostatnom riadku. Vo výpise figurujú len tie jednotky a predmety, ktoré reálne útočili. Pod textom je ukážka výstupu z tejto funkcie.
1,Niko,gloves: [Oldo,1]
1,Niko,wand: [Oldo,12] [Ondro,10] [Oskar,7]
1,Odin,fireball: [Oldo,11] [Ondro,9] [Oskar,6] [Oto,9]
2,Oldo,dagger: [Niko,1]
2,Ondro,axe: [Niko,2] [Odin,10]
2,Oskar,rock: [Niko,1] [Odin,3]
Štruktúra jedného riadku výpisu:
V tejto časti uvádzame príklad celkového výpisu, ktorý sa uskutoční v rámci jedného kola. Má 4 časti. Najprv sa vypíše poradové číslo kola. Následne, na začiatku kola sa zavolá funkcia print_units()
. Po vykonaní útoku oboch armád sa zavolá funkcia print_damage()
. Na konci kola sa ešte raz zavolá funkcia print_units()
.
Round 1
1: Niko,100 Odin,100
2: Oldo,100 Ondro,100 Oskar,100 Oto,100
1,Niko,gloves: [Oldo,1]
1,Niko,wand: [Oldo,12] [Ondro,10] [Oskar,7]
1,Odin,fireball: [Oldo,11] [Ondro,9] [Oskar,6] [Oto,9]
2,Oldo,dagger: [Niko,1]
2,Ondro,axe: [Niko,2] [Odin,10]
2,Oskar,rock: [Niko,1] [Odin,3]
1: Niko,96 Odin,87
2: Oldo,76 Ondro,81 Oskar,87 Oto,91
V každom kole vykonajú útok obidve armády súčasne. Útoku sa zúčastní každá živá jednotka v armáde. Každá jednotka zaútočí 0, 1 alebo 2 predmetmi v inventári podľa toho, či má predmet dostatočný útočný dosah (range).
Každá jednotka sa pokúsi zaútočiť všetkými predmetmi v inventári (pokus zlyhá ak predmet nemá dostatočný dosah). Najprv sa snaží vykonať útok predmetom č. 1 (item1
) a potom predmetom č. 2 (item2
).
Ak dôjde k útoku, jednotka spôsobí zranenie 1 alebo viacerým nepriateľským jednotkám podľa toho, či sa nachádzajú v akčnom rádiuse predmetu).
Každý predmet v inventári spôsobí brániacej sa jednotke nejaké zranenie. Celkové zranenie $DMG_{Attacker}$, ktoré spôsobí útočiaca jednotka sa vypočíta ako súčet zranení, ktoré spôsobia všetky predmety útočníka, ktoré boli použité pri útoku.
$DMG_{Attacker} = DMG_{Item 1} + DMG_{Item 2}$, kde:
Zranenie, ktoré spôsobí útočník zvoleným predmetom sa vypočíta podľa nasledovného vzťahu.
$DMG_{item} = max(1,ATT_{item} - DEF_{total})$, kde:
att
zvoleného predmetu útočníkadef
všetkých predmetov obrancu.Na obrázku 6 vidíme ilustráciu výpočtu zranenia, ktoré spôsobí jednotka s menom Fero (vľavo) jednotke s menom Milan (vpravo). Predpokladáme, že pozície týchto jednotiek na bojovom poli spĺňajú podmienku na vykonanie útoku, t.j. $pos <= range$.
Aktualizácia armád nastane až po tom, keď obidve armády dokončia svoj útok v rámci kola. Skladá sa z 2 fáz.
Po každom kole sa vyhodnotí, či súboj neskončil. Ak súboj skončil, môže mať 3 výsledky:
WINNER: 1
.WINNER: 2
.NO WINNER
.
Používateľ môže pri spustení programu v termináli zadať nepovinný argument $N$.
Tento argument stanovuje maximálny počet kôl súboja.
Ak $N = 0$, vykoná sa len úvodný výpis armád.
Ak používateľ nezadá $N$, súboj prebehne až do konca.
Na spracovanie CMD argumentov použite parametre argc
a
argv
, ktoré vstupujú do main
funkcie.
Viac o spracovaní CMD argumentov.
Celkový výpis programu má nasledujúcu štruktúru.
Príklad celkového výstupu programu (bez zadania argumentu $N$):
Vstup
4
Wren rock
Elio sword dagger
Juno sword helmet
Hippo sword wand
3
Smag spear rock
Rio helmet rock
Tipo wand wand
Výstup
Army 1
Unit: 0
Name: Wren
HP: 100
Item 1: rock,3,0,1,2,1
Unit: 1
Name: Elio
HP: 100
Item 1: sword,9,2,1,0,0
Item 2: dagger,4,0,1,0,0
Unit: 2
Name: Juno
HP: 100
Item 1: sword,9,2,1,0,0
Item 2: helmet,1,5,1,0,0
Unit: 3
Name: Hippo
HP: 100
Item 1: sword,9,2,1,0,0
Item 2: wand,12,4,1,4,2
Army 2
Unit: 0
Name: Smag
HP: 100
Item 1: spear,6,1,1,1,1
Item 2: rock,3,0,1,2,1
Unit: 1
Name: Rio
HP: 100
Item 1: helmet,1,5,1,0,0
Item 2: rock,3,0,1,2,1
Unit: 2
Name: Tipo
HP: 100
Item 1: wand,12,4,1,4,2
Item 2: wand,12,4,1,4,2
Round 1
1: Wren,100 Elio,100 Juno,100 Hippo,100
2: Smag,100 Rio,100 Tipo,100
1,Wren,rock: [Smag,2] [Rio,1]
1,Hippo,wand: [Smag,11] [Rio,7] [Tipo,4]
2,Smag,spear: [Wren,6] [Elio,4]
2,Smag,rock: [Wren,3] [Elio,1]
2,Rio,rock: [Wren,3] [Elio,1]
2,Tipo,wand: [Wren,12] [Elio,10] [Juno,5]
2,Tipo,wand: [Wren,12] [Elio,10] [Juno,5]
1: Wren,64 Elio,74 Juno,90 Hippo,100
2: Smag,87 Rio,92 Tipo,96
Round 2
1: Wren,64 Elio,74 Juno,90 Hippo,100
2: Smag,87 Rio,92 Tipo,96
1,Wren,rock: [Smag,2] [Rio,1]
1,Hippo,wand: [Smag,11] [Rio,7] [Tipo,4]
2,Smag,spear: [Wren,6] [Elio,4]
2,Smag,rock: [Wren,3] [Elio,1]
2,Rio,rock: [Wren,3] [Elio,1]
2,Tipo,wand: [Wren,12] [Elio,10] [Juno,5]
2,Tipo,wand: [Wren,12] [Elio,10] [Juno,5]
1: Wren,28 Elio,48 Juno,80 Hippo,100
2: Smag,74 Rio,84 Tipo,92
Round 3
1: Wren,28 Elio,48 Juno,80 Hippo,100
2: Smag,74 Rio,84 Tipo,92
1,Wren,rock: [Smag,2] [Rio,1]
1,Hippo,wand: [Smag,11] [Rio,7] [Tipo,4]
2,Smag,spear: [Wren,6] [Elio,4]
2,Smag,rock: [Wren,3] [Elio,1]
2,Rio,rock: [Wren,3] [Elio,1]
2,Tipo,wand: [Wren,12] [Elio,10] [Juno,5]
2,Tipo,wand: [Wren,12] [Elio,10] [Juno,5]
1: Elio,22 Juno,70 Hippo,100
2: Smag,61 Rio,76 Tipo,88
Round 4
1: Elio,22 Juno,70 Hippo,100
2: Smag,61 Rio,76 Tipo,88
1,Elio,sword: [Smag,8]
1,Elio,dagger: [Smag,3]
1,Hippo,wand: [Smag,11] [Rio,7] [Tipo,4]
2,Smag,spear: [Elio,4] [Juno,1]
2,Smag,rock: [Elio,1] [Juno,1]
2,Rio,rock: [Elio,1] [Juno,1]
2,Tipo,wand: [Elio,10] [Juno,5] [Hippo,6]
2,Tipo,wand: [Elio,10] [Juno,5] [Hippo,6]
1: Juno,57 Hippo,88
2: Smag,39 Rio,69 Tipo,84
Round 5
1: Juno,57 Hippo,88
2: Smag,39 Rio,69 Tipo,84
1,Juno,sword: [Smag,8]
1,Juno,helmet: [Smag,1]
1,Hippo,wand: [Smag,11] [Rio,7] [Tipo,4]
2,Smag,spear: [Juno,1] [Hippo,1]
2,Smag,rock: [Juno,1] [Hippo,1]
2,Rio,rock: [Juno,1] [Hippo,1]
2,Tipo,wand: [Juno,5] [Hippo,6]
2,Tipo,wand: [Juno,5] [Hippo,6]
1: Juno,44 Hippo,73
2: Smag,19 Rio,62 Tipo,80
Round 6
1: Juno,44 Hippo,73
2: Smag,19 Rio,62 Tipo,80
1,Juno,sword: [Smag,8]
1,Juno,helmet: [Smag,1]
1,Hippo,wand: [Smag,11] [Rio,7] [Tipo,4]
2,Smag,spear: [Juno,1] [Hippo,1]
2,Smag,rock: [Juno,1] [Hippo,1]
2,Rio,rock: [Juno,1] [Hippo,1]
2,Tipo,wand: [Juno,5] [Hippo,6]
2,Tipo,wand: [Juno,5] [Hippo,6]
1: Juno,31 Hippo,58
2: Rio,55 Tipo,76
Round 7
1: Juno,31 Hippo,58
2: Rio,55 Tipo,76
1,Juno,sword: [Rio,4]
1,Juno,helmet: [Rio,1]
1,Hippo,wand: [Rio,7] [Tipo,4]
2,Rio,helmet: [Juno,1]
2,Rio,rock: [Juno,1] [Hippo,1]
2,Tipo,wand: [Juno,5] [Hippo,6]
2,Tipo,wand: [Juno,5] [Hippo,6]
1: Juno,19 Hippo,45
2: Rio,43 Tipo,72
Round 8
1: Juno,19 Hippo,45
2: Rio,43 Tipo,72
1,Juno,sword: [Rio,4]
1,Juno,helmet: [Rio,1]
1,Hippo,wand: [Rio,7] [Tipo,4]
2,Rio,helmet: [Juno,1]
2,Rio,rock: [Juno,1] [Hippo,1]
2,Tipo,wand: [Juno,5] [Hippo,6]
2,Tipo,wand: [Juno,5] [Hippo,6]
1: Juno,7 Hippo,32
2: Rio,31 Tipo,68
Round 9
1: Juno,7 Hippo,32
2: Rio,31 Tipo,68
1,Juno,sword: [Rio,4]
1,Juno,helmet: [Rio,1]
1,Hippo,wand: [Rio,7] [Tipo,4]
2,Rio,helmet: [Juno,1]
2,Rio,rock: [Juno,1] [Hippo,1]
2,Tipo,wand: [Juno,5] [Hippo,6]
2,Tipo,wand: [Juno,5] [Hippo,6]
1: Hippo,19
2: Rio,19 Tipo,64
Round 10
1: Hippo,19
2: Rio,19 Tipo,64
1,Hippo,sword: [Rio,4]
1,Hippo,wand: [Rio,7] [Tipo,4]
2,Rio,helmet: [Hippo,1]
2,Rio,rock: [Hippo,1]
2,Tipo,wand: [Hippo,6]
2,Tipo,wand: [Hippo,6]
1: Hippo,5
2: Rio,8 Tipo,60
Round 11
1: Hippo,5
2: Rio,8 Tipo,60
1,Hippo,sword: [Rio,4]
1,Hippo,wand: [Rio,7] [Tipo,4]
2,Rio,helmet: [Hippo,1]
2,Rio,rock: [Hippo,1]
2,Tipo,wand: [Hippo,6]
2,Tipo,wand: [Hippo,6]
1:
2: Tipo,56
WINNER: 2
Dodaný CLion projekt sa skladá z 3 častí:
include
, ktorý obsahuje hlavičkový súbor
data.h
/*
* Makra, struktury, deklaracie
*/
#ifndef DATA_H
#define DATA_H
#define NUMBER_OF_ITEMS 16 // velkost databazy predmetov
#define MAX_NAME 100 // maximalna dlzka nazvu/mena
#define MIN_ARMY 1 // minimalny pocet bojovych jednotiek v armade
#define MAX_ARMY 5 // maximalny pocet bojovych jednotiek v armade
// Struktura pre predmet v inventari
typedef struct item {
char name[MAX_NAME + 1]; // nazov predmetu
int att; // utok
int def; // obrana
int slots; // pocet slotov, ktore zabera predmet v inventari
int range; // utocny dosah/dostrel predmetu
int radius; // sirka zasahu (alebo damage radius)
} ITEM;
// Struktura pre bojovu jednotku
typedef struct unit {
char name[MAX_NAME + 1]; // meno jednotky
const ITEM *item1; // prvy predmet v inventari (ukazuje do pola 'items')
const ITEM *item2; // druhy predmet v inventari (ukazuje do pola 'items')
int hp; // zdravie (z angl. hit points)
} UNIT;
// databaza predmetov, ktore moze mat bojova jednotka v inventari
extern const ITEM items[NUMBER_OF_ITEMS];
#endif //DATA_H
src
, ktorý obsahuje zdrojový súbor
data.c
a z4.c
/*
* Definicie
*/
#include "data.h"
// databaza predmetov, ktore moze mat bojova jednotka v inventari
const ITEM items[NUMBER_OF_ITEMS] = {
// predmety, ktore zaberaju 1 slot, zoradene podla atributu 'att'
{.name = "wand", .att = 12, .def = 4, .slots = 1, .range = 4, .radius = 2}, // kuzelna palica
{.name = "fireball", .att = 11, .def = 0, .slots = 1, .range = 3, .radius = 3}, // ohniva gula
{.name = "sword", .att = 9, .def = 2, .slots = 1, .range = 0, .radius = 0}, // mec
{.name = "spear", .att = 6, .def = 1, .slots = 1, .range = 1, .radius = 1}, // ostep
{.name = "dagger", .att = 4, .def = 0, .slots = 1, .range = 0, .radius = 0}, // dyka
{.name = "rock", .att = 3, .def = 0, .slots = 1, .range = 2, .radius = 1}, // skala
{.name = "armor", .att = 2, .def = 7, .slots = 1, .range = 0, .radius = 0}, // brnenie
{.name = "shield", .att = 2, .def = 6, .slots = 1, .range = 0, .radius = 0}, // stit
{.name = "gloves", .att = 1, .def = 4, .slots = 1, .range = 0, .radius = 0}, // rukavice
{.name = "helmet", .att = 1, .def = 5, .slots = 1, .range = 0, .radius = 0}, // helma
{.name = "aura", .att = 0, .def = 8, .slots = 1, .range = 0, .radius = 0}, // ochranna aura
// predmety, ktore zaberaju 2 sloty, zoradene podla atributu 'att'
{.name = "cannon", .att = 12, .def = 0, .slots = 2, .range = 4, .radius = 4}, // kanon
{.name = "axe", .att = 10, .def = 2, .slots = 2, .range = 1, .radius = 1}, // sekera
{.name = "hammer", .att = 8, .def = 2, .slots = 2, .range = 1, .radius = 2}, // kladivo
{.name = "crossbow", .att = 5, .def = 1, .slots = 2, .range = 3, .radius = 0}, // kusa
{.name = "slingshot", .att = 2, .def = 0, .slots = 2, .range = 2, .radius = 1} // prak
};
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "data.h" // NEMENIT, inak vas kod neprejde testom !!!
// chybove hlasenia
#define ERR_UNIT_COUNT "ERR_UNIT_COUNT"
#define ERR_ITEM_COUNT "ERR_ITEM_COUNT"
#define ERR_WRONG_ITEM "ERR_WRONG_ITEM"
#define ERR_SLOTS "ERR_SLOTS"
int main(const int argc, char *argv[]) {
return 0;
}
CMakeLists.txt
, ktorý obsahuje nastavenie projektu.
K dispozícii máte balík s testovacími súbormi pomocou, ktorých si viete otestovať funkcionalitu vášho programu v jednotlivých scenároch.
Balík je distribuovaný ako ZIP súbor s názvom z4_testing.zip
, ktorý obsahuje
tieto adresáre:
stdin
- adresár, ktorý obsahuje TXT súbory, v ktorých sú uložené vstupy
do programu pre všetky testovacie prípady a scenáre (odporúčame skompilovaný program spúšťať pomocou
presmerovania štandardného vstupu z týchto súborov)
stdout
- adresár, ktorý obsahuje správne výstupy pre všetky testovacie
prípady vo všetkých scenároch
Štandardný vstup programu vieme v termináli jednoducho presmerovať pomocou operátora <
. Použitím tohto operátora sa vstup bude čerpať z dodaného textového súboru
a nie z klávesnice. Príklad spustenia programu s presmerovaním štandardného vstupu v Linux termináli je uvedený
pod textom.
./my_program < input.txt
Uvádzame príklad ako testovať váš program pomocou dodaných TXT súborov pre jednotlivé scenáre. V príklade je
program testovaný pre náhodne vybrané testovacie prípady v scenári 1. Program z4
predstavuje skompilované zadanie č. 4 a predpokladáme, že sa nachádza v
adresári stdin
.
./z4 < scenar_1/example_1.txt
./z4 < scenar_1/example_2.txt
./z4 < scenar_1/example_3.txt
Uvádzame aj príklad ako si rýchlo v Linux termináli otestovať, či váš program vypísal očakávaný výstup pre
zvolený testovací scenár a prípad. Využijeme na to presmerovanie štandardného vstupu a príkaz diff
na porovnanie obsahu dvoch textov. Budeme predpokladať, že skompilovaný
program sa nachádza na rovnakej úrovni ako adresáre stdin
a stdout
. V tomto príklade testujeme, či náš program správne funguje v testovacom
prípade 2 v rámci scenára 4. Ak sa po spustení tohto príkazu nič nevypíše, signalizuje to, že výstup nášho
programu sa nelíši od správneho výstupu.
./z4 < stdin/scenar_4/example_2.txt | diff - stdout/scenar_4/example_2.txt --ignore-trailing-space
Poznámka: pokročilí programátori a nadšenci si môžu proces testovania a porovnávania výstupov programu so
správnym výstupom automatizovať pomocou Python, Linux shell skriptov resp. Powershell skriptov a pod. Ideálny
nástrojom na porovnávanie obsahu dvoch TXT súborov je príkaz diff
. Viac
informácií nájdete na tomto odkaze.
Odovzdávací systém otestuje a vyhodnotí nasledovné oblasti funkcionality vášho programu. Na získanie bodov za konkrétny testovací scenár je nutné, aby testom prešli všetky testovacie prípady v danom scenári.
Scenár 1
Detekcia chýb pri načítavaní jednotiek
|
1,0 b |
Scenár 2
Načítanie armád + úvodný výpis (používateľ zadá N=0)
|
1,0 b |
Scenár 3
Výpis priebehu súboja, 1 vs. 1 (používateľ nezadá N)
|
1,0 b |
Scenár 4
Výpis priebehu súboja, veľa jednotiek (používateľ zadá N > 0)
|
3,0 b |
Scenár 5
Výpis priebehu súboja, veľa jednotiek (používateľ nezadá N)
|
3,0 b |
Scenár 6
Kontrola výpisu víťaza (používateľ nezadá N)
|
1,0 b |
Súčet | 10,0 b |
Všetky testovacie príklady na stiahnutie
V testovacom scenári 4 boli pre jednotlivé príklady použité tieto hodnoty CMD parametra $N$.
example_1.txt
... $N = 10$example_2.txt
... $N = 5$example_3.txt
... $N = 14$example_4.txt
... $N = 12$example_5.txt
... $N = 11$example_6.txt
... $N = 16$example_7.txt
... $N = 10$example_8.txt
... $N = 12$example_9.txt
... $N = 190$Nasledujúce zdroje vám môžu pomôcť pri programovaní zadania. Odporúčame si tieto zdroje preštudovať. Na prístup k niektorým zdrojom potrebujete byť prihlásení vo vašom univerzitnom Google STU konte.