GeoGuessr¶
Autor zadatka: Rade Radišić <radisic.rade@uns.ac.rs>
Pokušaj korisnika u igri GeoGuessr predstavljen je preko strukture pomoću sledećih polja:
korisničko ime (jedna reč, maksimalno 20 karaktera)
relativna udaljenost pogotka izražena u metrima (celobrojna vrednost)
Učitati zadate podatke u binarno stablo pretrage (struktura sadrži potrebna polja za formiranje čvora binarnog stabla).
Kriterijum za formiranje stabla je korisničko ime igrača u rastućem redosledu (koristiti funkciju strcmp
za poređenje korisničkih imena).
U izlaznu datoteku ispisati relativnu udaljenost pogotka i korisničko ime u formatu "%4dm %s"
.
Pronaći igrače čija su korisnička imena zadata kao argumenti komandne linije i ispisati apsolutnu razdaljinu između njih (koristiti funkciju abs
),
ukoliko postoje igrači sa zadatim korisničkim imenima.
U slučaju da barem jedan od igrača ne postoji, ispisati sledeći sadržaj: "\nNe postoji bar jedan igrac od zadatih korisnickih imena!\n"
Primer ulaznog fajla pokusaji.txt
:
Raisan 103
Keffer 15
Dianernan 97
Covelsmar 1450
Jeanite 231
Quahassu 489
Thegamy 3482
Alatec 746
Gnomera 431
Primer poziva programa:
./resenje pokusaji.txt rezultati.txt Alatec Jeanite
Primer izlazne datoteke rezultati.txt
:
746m Alatec
1450m Covelsmar
97m Dianernan
431m Gnomera
231m Jeanite
15m Keffer
489m Quahassu
103m Raisan
3482m Thegamy
Razdaljina izmedju pogodataka igraca Alatec i Jeanite je 515m.
Primer poziva programa kada jedan od traženih korisnika ne postoji:
./resenje pokusaji.txt rezultati-nema-igraca.txt Alatec Shiyaut
Primer izlazne datoteke rezultati-nema-igraca.txt
:
746m Alatec
1450m Covelsmar
97m Dianernan
431m Gnomera
231m Jeanite
15m Keffer
489m Quahassu
103m Raisan
3482m Thegamy
Ne postoji bar jedan igrac od zadatih korisnickih imena!
Primer rešenja¶
1#include <stdio.h>
2#include <string.h>
3#include <stdlib.h>
4
5#define MAX_KOR_IME 21
6
7typedef struct pokusaj_st {
8 char korisnicko_ime[MAX_KOR_IME];
9 int rel_ud_pogotka;
10 struct pokusaj_st *levi;
11 struct pokusaj_st *desni;
12} POKUSAJ;
13
14FILE *safe_fopen(char *, char *, int);
15void ucitaj_pokusaje(FILE *, POKUSAJ **);
16void ispisi_rezultate(FILE *, POKUSAJ *);
17
18void inicijalizacija(POKUSAJ **);
19POKUSAJ *napravi_cvor(char *, int);
20void dodaj_u_stablo(POKUSAJ **, POKUSAJ *);
21POKUSAJ *pronadji_cvor(POKUSAJ *, char *);
22void obrisi_stablo(POKUSAJ **);
23
24int main(int argc, char **argv) {
25 POKUSAJ *koren;
26
27 if(argc != 5) {
28 printf("Primer poziva: %s pokusaji.txt rezultati.txt Alatec Jeanite\n", argv[0]);
29 exit(EXIT_FAILURE);
30 }
31
32 inicijalizacija(&koren);
33
34 FILE *ulazna = safe_fopen(argv[1], "r", 3);
35 ucitaj_pokusaje(ulazna, &koren);
36 fclose(ulazna);
37
38 FILE *izlazna = safe_fopen(argv[2], "w", 4);
39 ispisi_rezultate(izlazna, koren);
40 POKUSAJ *prvi_igrac = pronadji_cvor(koren, argv[3]);
41 POKUSAJ *drugi_igrac = pronadji_cvor(koren, argv[4]);
42 if(prvi_igrac != NULL && drugi_igrac != NULL) {
43 int raz_izm_pogotka = abs(prvi_igrac->rel_ud_pogotka - drugi_igrac->rel_ud_pogotka);
44 fprintf(izlazna, "\nRazdaljina izmedju pogodataka igraca %s i %s je %dm.\n",
45 prvi_igrac->korisnicko_ime, drugi_igrac->korisnicko_ime, raz_izm_pogotka);
46 } else {
47 fprintf(izlazna, "\nNe postoji bar jedan igrac od zadatih korisnickih imena!\n");
48 }
49 fclose(izlazna);
50
51 obrisi_stablo(&koren);
52
53 return EXIT_SUCCESS;
54}
55
56FILE *safe_fopen(char *name, char *mode, int error_code) {
57 FILE *fp = fopen(name, mode);
58
59 if(fp == NULL) {
60 printf("Nije moguce otvoriti fajl %s!\n", name);
61 exit(error_code);
62 }
63
64 return fp;
65}
66
67void ucitaj_pokusaje(FILE *ulazna, POKUSAJ **pkoren) {
68 char tmp_korisnicko_ime[MAX_KOR_IME];
69 int tmp_rel_ud_pogotka;
70
71 while(fscanf(ulazna, "%s %d",
72 tmp_korisnicko_ime,
73 &tmp_rel_ud_pogotka
74 ) != EOF) {
75 POKUSAJ *novi = napravi_cvor(tmp_korisnicko_ime, tmp_rel_ud_pogotka);
76 dodaj_u_stablo(pkoren, novi);
77 }
78}
79
80void ispisi_rezultate(FILE *izlazna, POKUSAJ *koren) {
81 if(koren != NULL) {
82 ispisi_rezultate(izlazna, koren->levi);
83 fprintf(izlazna, "%4dm %s\n", koren->rel_ud_pogotka, koren->korisnicko_ime);
84 ispisi_rezultate(izlazna, koren->desni);
85 }
86}
87
88void inicijalizacija(POKUSAJ **pkoren) {
89 *pkoren = NULL;
90}
91
92POKUSAJ *napravi_cvor(char *korisnicko_ime, int rel_ud_pogotka) {
93 POKUSAJ *novi = (POKUSAJ *)malloc(sizeof(POKUSAJ));
94
95 if(novi == NULL) {
96 printf("Greska prilikom zauzimanja memorije!\n");
97 exit(2);
98 }
99
100 strcpy(novi->korisnicko_ime, korisnicko_ime);
101 novi->rel_ud_pogotka = rel_ud_pogotka;
102 novi->levi = NULL;
103 novi->desni = NULL;
104
105 return novi;
106}
107
108void dodaj_u_stablo(POKUSAJ **pkoren, POKUSAJ *novi) {
109 if(*pkoren == NULL) {
110 *pkoren = novi;
111 } else {
112 if(strcmp((*pkoren)->korisnicko_ime, novi->korisnicko_ime) > 0) {
113 dodaj_u_stablo(&(*pkoren)->levi, novi);
114 } else {
115 dodaj_u_stablo(&(*pkoren)->desni, novi);
116 }
117 }
118}
119
120POKUSAJ *pronadji_cvor(POKUSAJ *koren, char *korisnicko_ime) {
121 POKUSAJ *nadjen = NULL;
122
123 if(koren != NULL) {
124 if(strcmp(koren->korisnicko_ime, korisnicko_ime) == 0) {
125 nadjen = koren;
126 } else {
127 if(strcmp(koren->korisnicko_ime, korisnicko_ime) > 0) {
128 nadjen = pronadji_cvor(koren->levi, korisnicko_ime);
129 } else {
130 nadjen = pronadji_cvor(koren->desni, korisnicko_ime);
131 }
132 }
133 }
134
135 return nadjen;
136}
137
138void obrisi_stablo(POKUSAJ **pkoren) {
139 if(*pkoren != NULL) {
140 obrisi_stablo(&(*pkoren)->levi);
141 obrisi_stablo(&(*pkoren)->desni);
142 free(*pkoren);
143 *pkoren = NULL;
144 }
145}
146