Napíšte konzolovú/terminálovú aplikáciu v jazyku C, ktorá bude simulovať a vizualizovať priebeh závodnej automobilovej hry Quantum Racing. Na závodnej dráhe budú pretekať 2 autá. Hra je ťahovo-orientovaná, t.j. autá sa budú striedavo posúvať po dráhe. Rýchlosť pohybu áut je daná pseudo-náhodnosťou (hod kockami). Počas závodu môže dochádzať k rôznym situáciám akými sú eliminácia auta oponenta alebo teleportácia pomocou tzv. tunelov, ktoré sú rozmiestnené na dráhe.
Hra začína načítaním a kontrolou potrebných vstupných parametrov z klávesnice (štandardný vstup). Ak bude do programu zadaný neplatný vstup v zmysle pravidiel zadania, program skončí bez akéhokoľvek výpisu s predpísanou návratovou hodnotou. Ak sú všetky vstupné parametre platné, začína závod. Samotný závod, je plne automatizovaný, t.j. po načítaní vstupných parametrov prebieha bez zásahu používateľa a riadi sa stanovenými pravidlami. Priebeh závodu musí byť vizualizovaný výpismi do terminálu (štandardný výstup) podľa stanovených pokynov. Závod končí víťazstvom niektorého z pretekajúcich áut, t.j. víťazom sa stáva auto, ktoré ako prvé prekoná dĺžku závodnej trate. Zmyslom zadania je precvičenie si práce s poliami.
V závodnej hre sa stretávajú 2 pretekajúce autá, ktoré sa pohybujú po závodnej dráhe. Pohyb pretekajúcich áut závisí od virtuálneho hodu hracími kockami a ďalších stanovených pravidiel. Navyše, na závodnej dráhe sa môžu nachádzať tunely, ktoré teleportujú pretakajúce auto na iné miesto na dráhe. Víťazom sa stáva auto, ktoré ako prvé prekoná dĺžku závodnej dráhy.
Nasledovný zoznam obsahuje základné pojmy, s ktorými sa v zadaní stretávame:
Na závodnú dráhu sa môžeme pozerať ako na postupnosť políčok, po ktorých sa pretekári pohybujú. Dĺžku závodnej dráhy $n$ určuje používateľ z klávesnice. Maximálna dĺžka závodnej dráhy je $N_{max}=100$ políčok. Auto, ktoré ako prvé prekoná dĺžku trate sa stáva víťazom, t.j. jeho index na závodnej dráhe je viac než $n-1$. Políčka závodnej dráhy môžeme rozdeliť na 3 typy:
Na začiatku programu zadáva používateľ z klávesnice vstupné parametre, ktorými sa určia základné atribúty závodu. Je potrebné, aby boli tieto parametre zadávané v predpísanom poradí. Zoznam vstupných parametrov programu:
$ s $ | Inicializačná hodnota pre generátor pseudo-náhodných čísiel. Tento generátor budeme používať na generovanie čísel pri hode kockami. |
$ t $ | Počet tunelov na závodnej dráhe, ktoré slúžia na teleportáciu pretekajúceho auta. Tunel sa skladá, z dvoch častí: políčko s vchodom a políčko s východom z tunela. |
$ n $ | Dĺžka závodnej dráhy (počet jej políčok). |
Po zadaní vstupných parametrov musí program vyhodnotiť ich platnosť. V prípade, že niektorý zo vstupných parametrov je neplatný, program musí ukončiť svoju činnosť bez akéhokoľvek výstupu a vrátiť príslušnú návratovú hodnotu. Treba ošetriť nasledovné situácie:
V prípade, že niektorá z vyššie uvedených podmienok nie je splnená, program skončí bez akéhokoľvek výstupu s
návratovou hodnotou 1
(návratová hodnota funkcie
main
).
Po kontrole vstupných parametrov sa rozmiestnia tunely na dráhe. Tunely ručne rozmiestni používateľ zadávaním čísel z klávesnice. Počet rozmiestnených tunelov je $t$. Používateľ zadáva jednotlivé tunely načítaním dvojice čísel $\{enter,exit\}$.
Pri zadávaní tunelov musia byť splnené tieto podmienky:
V prípade nesplnenia, niektorej z vyššie uvedených podmienok musí program skončiť bez akéhokoľvek výstupu a
vrátiť hodnotu 2
(návratová hodnota funkcie
main
).
Pri testovaní vašich programov je vhodné si automatizovať zadávanie vstupných parametrov pomocou
presmerovania štandardného vstupu z textového súboru. Presmerovanie dosiahneme použitím operátora
<
a následným spustením programu v tvare ./program
< file.txt
. Do textového súboru su napíšeme všetky vstupné parametre programu a pozície tunelov a následne
program spustíme z terminálu spôsobom vizualizovaným na obrázku pod textom.
inputs.txt
sú v prvom riadku
parametre $s$, $t$ a $n$. V druhom až štvrtom riadku sú zadané indexy vchodov a východov 3 tunelov.
Po načítaní vstupných parametrov a rozmiestnení tunelov začína samotný závod, v ktorom súperia 2 pretekári. Na začiatku závodu majú obaja pretekári umiestnené auto mimo závodnej dráhy. Počas závodu ich budeme označovať ako hráč 1 a 2. Hráči sa striedajú v ťahoch. Ako prvý je na ťahu hráč 1.
Pretekár, ktorý je na ťahu vždy hodí 2 kockami $R_1$ a $R_2$. Na každej kocke padne náhodné číslo v intervale $\langle 1,6\rangle$. Detaily generovania pseudo-náhodných čísel sú vysvetlené v časti Generovanie pseudo-náhodných čísiel.
Na začiatku závodu je pretekár mimo dráhy. Vtedy budeme jeho pozíciu označovať hodnotou -1. Aby mohol pretekár vstúpiť na závodnú dráhu a začať pretekať (resp. nastaviť svoje auto naspäť na začiatok dráhy po eliminácii), musí v rámci jeho ťahu hodiť kockami súčet čísel, pre ktorý platí $R_1 + R_2 \gt 7$. Ak splní túto podmienku, tak si môže svoje auto umiestniť na štartovaciu pozíciu, t.j. políčko s indexom $R_1 + R_2 - 7$.
Ak hráč má v rámci jeho ťahu auto umiestnené na závodnej dráhe, tak môže nastať jeden z nasledovných prípadov.
\begin{equation} \begin{split} P_{h,t+1} = P_{o,t}\\ P_{o,t+1} = P_{h,t} \end{split} \end{equation}
\begin{equation} P_{h,t+1}=P_{h,t}+d \end{equation}
Keďže máme na závodnej dráhe rozmiestnené tunely, môže počas závodu dôjsť k teleportácii pretekára. Teleportácia nastáva, keď auto hráča, ktorý je na ťahu vstúpi na políčko dráhy, ktoré je označené ako vstup do tunela (t.j. keď $P_{h,t+1}$ sa zhoduje s indexom niektorého z vchodov rozmiestnených tunelov). V takomto prípade bude pretekár teleportovaný z políčka vchodu do tunela na políčko východu z tunela. Po teleportácii bude platiť, že $P_{h,t+1}$ bude rovné indexu políčka, kde sa nachádza východ z tunela.
Poznámka: možnosť teleportácie treba vyšetriť po každej zmene pozície pretekára na dráhe, t.j. pri štandardnom posune o $d$ políčok alebo aj pri vstupe pretekára na začiatok závodnej dráhy.
Počas závodu môže nastať situácia, kedy je auto oponenta eliminované (postavené mimo dráhu) autom hráča, ktorý je práve na ťahu. K eliminácii dochádza vtedy, keď auto hráča na ťahu narazí do auta oponenta, t.j. keď platí $P_{h,t+1} = P_{o,t}$. Po eliminácii sa auto oponenta môže opäť zapojiť do pretekov po splnení podmienok pre vstup na závodnú dráhu, ktoré sú opísané v časti Vstup na závodnú dráhu.
Poznámka: možnosť eliminácie oponenta treba vyšetriť po každej zmene pozície pretekára na dráhe, t.j. pri štandardnom posune o $d$ políčok alebo pri vstupe pretekára na závodnú dráhu. Nezabudnite, že k eliminácii oponenta môže dôjsť aj po teleportácii, t.j. ak auto oponenta stojí na políčku, kde sa nachádza východ z tunela.
Víťazom závodu sa stáva hráč, ktorého auto ako prvé prekoná dĺžku závodnej dráhy, t.j. platí $P_{h,t+1} \geq n$.
Po skončení závodu sa zobrazí štatistika návštevnosti jednotlivých políčok závodnej dráhy. Hodnota návštevnosti políčka hovorí o tom, koľkokrát bolo dané políčko počas závodu navštívené obidvomi pretekajúcimi autami. Na začiatku závodu má každé políčko závodnej dráhy hodnotu návštevnosti 0.
Situácie, kedy započítame návštevu políčka závodnej dráhy:
Na realizáciu hodu kockami $R_1$ a $R_2$ je nutné použiť dodané funkcie na generovanie pseudo-náhodných čísel.
////////////////// NEMENIT !!! /////////////////////
// Vo vasom rieseni vyuzite tieto tieto funkcie na
// generovanie pseudo-nahodnych cisiel.
//
// Funkcia srnd(seed):
// * Zavolajte 1-krat na zaciatku programu na
// inicializaciu generovanej postupnosti cisiel.
//
// Funkcia rnd(from, to):
// * Sluzi na vygenerovanie dalsieho nahodneho
// cisla z intervalu <from,to>.
#define R_MAX 2147483647 // vsetky generovane cisla su mensie ako R_MAX
static long long unsigned int SEED = 0x1; // seed generatora
void srnd(int seed) { SEED = seed; }
int rnd(int from, int to) {
SEED = SEED * 16807 % R_MAX;
return from + (int) SEED % (to - from + 1);
}
/////////////////////////////////////////////////////////////
Funkciu srnd
je nutné zavolať v programe len 1-krát pred začiatkom
závodu. Do funkcie srnd
odovzdáme načítaný parameter $s$. V opačnom
prípade získate inú postupnosť generovaných čísel ako sa očakáva a vaše výstupy sa nebudú zhodovať s
očakávanými. Funkcia rnd
vráti ďalšie vygenerované pseudo-náhodné číslo
z intervalu $\langle from,to \rangle$.
Výstup programu môžeme rozdeliť do 4 častí, ktoré musia spĺňať predpísaný formát.
Po spustení programu sa načítajú vstupné parametre a následne sa vypíše všetkých $t$ používateľom umiestnených tunelov. Každý tunel je reprezentovaný dvojicou, ktorú tvorí index vchodu a index východu. Všetky tunely sa vypíšu v jednom riadku. Tunely musia byť vo výpise zoradené vzostupne (z angl. ascending) podľa indexu vchodu do tunela.
TUNNELS: [enter,exit] [enter,exit] ... [enter,exit]
Ak dráha neobsahuje žiadny tunel, v prvom riadku sa vypíše len text
TUNNELS:
Závod sa skladá zo striedajúcich sa ťahov jednotlivých pretekárov. Počas závodu vypisujeme každý ťah. Výpis jedného ťahu sa uskutoční na jednom riadku a má nasledovný formát:
[round,player_num] [pos_before] [r1,r2] [pos_after]
round
- číslo ťahu (ťahy sa začínajú číslovať od 1)player_num
- číslo hráča (strieda sa hráč 1 a 2)pos_before
- pozícia hráča (index políčka) na ťahu pred vykonaním
ťahu
r1,r2
- čísla, ktoré v rámci ťahu padli na kockách $R_1$ a $R_2$
pos_after
- pozícia hráča (index políčka) na ťahu po vykonaní ťahu
Špeciálne výpisy ťahu:
S
.
[round,player_num] [pos_before] [r1,r2] [pos_after] S
T
.
[round,player_num] [pos_before] [r1,r2] [pos_after] T
E
.
[round,player_num] [pos_before] [r1,r2] [pos_after] E
T E
. Táto situácia vznikne, keď hráč v rámci
svojho ťahu vstúpi na políčko s vchodom do tunela, teleportuje sa na jeho východ a na políčku s
východom z tunela je umiestnený oponent, ktorého následne eliminuje.
[round,player_num] [pos_before] [r1,r2] [pos_after] T E
Ťahy vypisujeme až pokiaľ niektorý z pretekárov nezvíťazí, t.j. bude platiť $P_{h,t+1} \geq n$.
Pretekár, ktorý ako prvý prekoná dĺžku dráhy sa stáva víťazom. Výpis víťaza predstavuje 1 riadok s nasledovným formátom:
WINNER: player_num
Namiesto player_num
sa vypíše číslo hráča, ktorý vyhral závod.
Posledným výpisom v rámci programu je štatistika návštevnosti jednotlivých políčok závodnej dráhy. Tento výpis predstavuje 1 riadok, v ktorom sa zobrazí pole hodnôt návštevnosti políčok závodnej dráhy. Nenavštívené políčka majú hodnotu 0. Viac o tejto štatistike nájdete v časti Záverečná štatistika. Formát výpisu záverečnej štatistiky je nasledovný:
VISITS: v0 v1 v2 v3 ... vn-1
Namiesto v0 v1 v2 v3 ... vn-1
sa vypíšu jednotlivé hodnoty návštevnosti
políčok dráhy.
gcc z2.c -o z2 -Wall -Wextra
./z2
70 3 84
21 41
32 2
3 16
TUNNELS: [3,16] [21,41] [32,2]
[1,1] [-1] [5,2] [-1]
[2,2] [-1] [5,1] [-1]
[3,1] [-1] [4,6] [16] T
[4,2] [-1] [4,4] [1]
[5,1] [16] [4,6] [22]
[6,2] [1] [5,3] [6]
[7,1] [22] [3,1] [25]
[8,2] [6] [4,2] [10]
[9,1] [25] [1,5] [30]
[10,2] [10] [3,1] [13]
[11,1] [30] [2,5] [35]
[12,2] [13] [2,4] [17]
[13,1] [35] [6,1] [41]
[14,2] [17] [1,4] [41] T E
[15,1] [-1] [4,4] [1]
[16,2] [41] [2,4] [45]
[17,1] [1] [3,2] [4]
[18,2] [45] [6,3] [51]
[19,1] [4] [3,1] [7]
[20,2] [51] [4,6] [57]
[21,1] [7] [6,1] [13]
[22,2] [57] [3,3] [60]
[23,1] [13] [6,4] [19]
[24,2] [60] [1,4] [64]
[25,1] [19] [6,5] [25]
[26,2] [64] [4,6] [70]
[27,1] [25] [1,4] [29]
[28,2] [70] [4,4] [74]
[29,1] [29] [3,1] [2] T
[30,2] [74] [4,1] [78]
[31,1] [2] [2,6] [8]
[32,2] [78] [1,5] [83]
[33,1] [8] [6,1] [14]
[34,2] [83] [1,1] [14] S
[35,1] [83] [1,6] [89]
WINNER: 1
VISITS: 0 2 1 0 1 0 1 1 1 0 1 0 0 2 2 0 1 1 0 1 0 0 1 0 0 2 0 0 0 1 1 0 0 0 0 1 0 0 0 0 0 2 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 1 0 0 0 1 0 0 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 0 2
main
bude 0.Odovzdávací systém otestuje a ohodnotí nasledovné oblasti funkcionality vášho programu. Na získanie bodov z konkrétneho testovacieho scenára je nutné, aby testom prešli všetky testovacie prípady v danom scenári.
Scenár 1
Zadanie neplatných vstupných parametrov.
|
0.5 b |
Scenár 2
Zadanie neplatného tunela.
|
1 b |
Scenár 3
Výpis tunelov.
|
0.5 b |
Scenár 4
Výpis závodu. Nenastane špeciálny prípad, teleportácia ani
eliminácia oponenta.
|
2 b |
Scenár 5
Výpis závodu. Nastane špeciálny prípad 1 a 2.
|
1 b |
Scenár 6
Výpis závodu. Nastane teleportácia cez tunel.
|
1.5 b |
Scenár 7
Výpis závodu. Nastane eliminácia oponenta.
|
1 b |
Scenár 8
Výpis závodu. Nastanú všetky udalosti: špeciálny prípad,
teleportácia aj eliminácia oponenta.
|
1 b |
Scenár 9
Výpis víťaza.
|
0.5 b |
Scenár 10
Výpis záverečnej štatistiky.
|
1 b |
Súčet | 10 b |
Aby váš program prešiel automatizovaným testovaním, jeho výstup musí mať nasledovnú štruktúru a výpisy sa musia zobrazovať na očakávaných pozíciách.
Blok 1
Situácia so zadaním neplatných vstupných parametrov. Očakáva sa, že program skončí bez výstupu a vráti hodnotu 1. V Linux termináli si viete skontrolovať návratovú hodnotu posledného skončeného príkazu pomocou echo $?
.
Vstup:
-6 2 95
Neplatná hodnota $s=-6$. Program skončí bez výstupu s návratovou hodnotou 1.
Vstup:
3 4 14
Neplatná hodnota $t=4$. Program skončí bez výstupu s návratovou hodnotou 1.
Vstup:
61 2 103
Neplatná hodnota $n=103$. Program skončí bez výstupu s návratovou hodnotou 1.
Blok 2
Situácia so zadaním neplatného tunela. Očakáva sa, že program skončí bez výstupu a vráti hodnotu 2. V Linux termináli si viete skontrolovať návratovú hodnotu posledného skončeného príkazu pomocou echo $?
.
Vstup:
31 2 50
5 41
0 20
Druhý tunel mal neplatný index vchodu (hodnota 0) - umiestnený na prvom políčku dráhy, čo je zakázané. Program skončí bez výstupu s návratovou hodnotou 2.
Vstup:
500 3 80
5 16
71 14
5 22
Prvý a tretí tunel majú rovnaký index vchodu, čo je zakázané. Program skončí bez výstupu s návratovou hodnotou 2.
Vstup:
432 4 51
7 43
15 26
23 1
48 7
Východ štvrtého tunela (index 7) je zhodný s indexom vchodu do prvého tunela. Je zakázané, aby bol východ tunela zároveň vchodom do iného tunela. Program skončí bez výstupu s návratovou hodnotou 2.
Vstup:
7316 1 36
5 35
Východ tunela je na poslednom políčku dráhy (index 35), čo je zakázané. Program skončí bez výstupu s návratovou hodnotou 2.
Vstup:
66 1 88
41 250
Východ tunela má index mimo platného rozsahu dráhy (index 250), čo je zakázané. Program skončí bez výstupu s návratovou hodnotou 2.
Vstup:
84 1 46
19 19
Vchod a východ tunela majú rovnaký index, čo je zakázané. Program skončí bez výstupu s návratovou hodnotou 2.
Blok 3
Priebeh závodu, kedy nenastane špeciálny prípad, teleportácia ani eliminácia oponenta.
Blok 4
Priebeh závodu, kedy nastane špeciálny prípad 1 a 2.
Blok 5
Priebeh závodu, kedy nastane teleportácia cez tunel.
Blok 6
Priebeh závodu, kedy nastane eliminácia oponenta.
Blok 7
Priebeh závodu, kedy nastanú všetky udalosti: špeciálny prípad, teleportácia aj eliminácia oponenta.
Blok 8
Priebeh závodu, kedy nastane v jednom ťahu teleportácia a následná eliminácia oponenta, ktorý stojí na východe z tunela.
Nasledujúce zdroje vám môžu pomôcť pri riešení zadania. Odporúčame si tieto zdroje pozrieť/preštudovať. Na prístup k niektorým zdrojom potrebujete byť prihlásení vo vašom Google G-Suite STU konte.