Jednostavni invertar
Napraviti funkcionalnost jednostavnog invertara u RPG igri. Invertar sadrži predmete, gde svaki predmet ima svoj naziv, težinu i vrednost.
Rešiti zadatak u više fajlova: main.c, item.h, item.c, inventory.h inventory.c.
Predmet (Item) treba da podržava sledeće funkcionalnosti:
Itemstruktura (sadrži naziv, težinu i vrednost);Item item_make(const char name[], int w, int v)kreira novi predmet;void item_print(Item it)ispisuje predmet na standardni izlaz;int item_cmp_by_weight(Item a, Item b)upoređuje dva predmeta po težini; iint item_cmp_by_value(Item a, Item b)upoređuje dva predmeta po vrednosti.
Invertar (Invertory) treba da podržava sledeće funkcionalnosti:
Inventorystruktura (sadrži niz predmeta i broj predmeta)Inventory inv_empty(void)pravi prazan invertar;Inventory inv_add(Inventory inv, Item it)dodaje redmet u invertar;void inv_print(Inventory inv)ispisuje invertar;int inv_total_weight(Inventory inv)vraća ukupnu težinu invertara;int inv_total_value(Inventory inv)vraća ukupnu vrednost invertara;Item inv_max_weight(Inventory inv)vraća najteži predmet invertara; iItem inv_max_value(Inventory inv)vraća najvredniji predmet invertara.
Dodatno: Proširiti funkcionalnosti invertara funkcijama po sopstvenom nahođenju.
Ulaz
Sa standardnog ulaza se unosi broj upita
a <name> <w> <v>- dodaje u invertar predmet sa datim nazivom, težinom i vrednošću;r <capacity>- iz invertara gramzivo izbacuje predmete ukoliko ukupana ukupna težina invertara premašuje<capacity>;p- ispisuje predmete inventara;w- ispisuje ukupnu težinu invertara;v- ispisuje ukupnu vrednost invertara;W- ispisuje najteži predmet invertara; iV- ispisuje najvredniji predmet invertara.
Pretpostaviti da naziv predmeta nije veći od
Izlaz
Na standardni izlaz ispisati, za svaki od upita w, i v odgovarajuću vrednost, za svaki od upita W i V ispisati odgovarajući predmet u formatu <name>{w=<w>,v=<v>}, i za svaki upit p ispisati invertar u formatu [ <it1>, <it2>, ..., <itn> ].
Primer
Ulaz
5
a sword 10 100
a shield 15 80
p
w
v
Izlaz
[ sword{w=10,v=100}, shield{w=15,v=80} ]
25
180
Primer
Ulaz
6
a apple 1 2
a rock 30 1
a gold 2 50
W
V
p
Izlaz
rock{w=30,v=1}
gold{w=2,v=50}
[ apple{w=1,v=2}, rock{w=30,v=1}, gold{w=2,v=50} ]
Rešenje
item.h
#ifndef ITEM_H
#define ITEM_H
#define MAX_NAME_LENGTH 20
typedef struct Item {
char name[MAX_NAME_LENGTH + 1];
int weight;
int value;
} Item;
Item item_make(char name[MAX_NAME_LENGTH + 1], int w, int v);
void item_print(Item it);
int item_cmp_by_weight(Item a, Item b);
int item_cmp_by_value(Item a, Item b);
#endif // ITEM_Hinventory.h
#ifndef INVENTORY_H
#define INVENTORY_H
#include "item.h"
#define MAX_INVENTORY_SIZE 50
typedef struct Inventory {
Item items[MAX_INVENTORY_SIZE];
int size;
} Inventory;
// Better to use pointers for passing and returning large structs (see later lectures)
Inventory inv_empty(void);
Inventory inv_add(Inventory inv, Item it);
void inv_print(Inventory inv);
int inv_total_weight(Inventory inv);
int inv_total_value(Inventory inv);
Item inv_max_weight(Inventory inv);
Item inv_max_value(Inventory inv);
#endif // INVENTORY_Hitem.c
#include "item.h"
#include <string.h>
#include <stdio.h>
Item item_make(char name[MAX_NAME_LENGTH + 1], int w, int v)
{
Item it;
strncpy(it.name, name, MAX_NAME_LENGTH);
it.name[MAX_NAME_LENGTH] = '\0';
it.weight = w;
it.value = v;
return it;
}
void item_print(Item it)
{
printf("%s{w=%d,v=%d}", it.name, it.weight, it.value);
}
int item_cmp_by_weight(Item a, Item b)
{
return a.weight - b.weight;
}
int item_cmp_by_value(Item a, Item b)
{
return a.value - b.value;
}inventory.c
#include "inventory.h"
#include <stdio.h>
Inventory inv_empty(void)
{
Inventory inv;
inv.size = 0;
return inv;
}
Inventory inv_add(Inventory inv, Item it)
{
if (inv.size < MAX_INVENTORY_SIZE) {
inv.items[inv.size] = it;
inv.size++;
}
return inv;
}
void inv_print(Inventory inv)
{
printf("[ ");
for (int i = 0; i < inv.size; i++) {
item_print(inv.items[i]);
if (i < inv.size - 1) {
printf(", ");
}
}
printf(" ]\n");
}
int inv_total_weight(Inventory inv)
{
int total_weight = 0;
for (int i = 0; i < inv.size; i++) {
total_weight += inv.items[i].weight;
}
return total_weight;
}
int inv_total_value(Inventory inv)
{
int total_value = 0;
for (int i = 0; i < inv.size; i++) {
total_value += inv.items[i].value;
}
return total_value;
}
Item inv_max_weight(Inventory inv)
{
Item max_item = { "", -1, 0 };
for (int i = 0; i < inv.size; i++) {
if (item_cmp_by_weight(inv.items[i], max_item)) {
max_item = inv.items[i];
}
}
return max_item;
}
Item inv_max_value(Inventory inv)
{
Item max_item = { "", 0, -1 };
for (int i = 0; i < inv.size; i++) {
if (item_cmp_by_value(inv.items[i], max_item)) {
max_item = inv.items[i];
}
}
return max_item;
}main.c
#include <stdio.h>
#include "item.h"
#include "inventory.h"
int main(void)
{
int q;
scanf("%d", &q);
Inventory inv = inv_empty();
while (q--) {
char op;
scanf(" %c", &op); // note the space before %c to skip previous newline
if (op == 'a') {
char name[MAX_NAME_LENGTH + 1];
int w, v;
scanf("%s %d %d", name, &w, &v);
inv = inv_add(inv, item_make(name, w, v));
} else if (op == 'p') {
inv_print(inv);
} else if (op == 'w') {
printf("%d\n", inv_total_weight(inv));
} else if (op == 'v') {
printf("%d\n", inv_total_value(inv));
} else if (op == 'W') {
Item it = inv_max_weight(inv);
item_print(it);
printf("\n");
} else if (op == 'V') {
Item it = inv_max_value(inv);
item_print(it);
printf("\n");
}
}
return 0;
}Makefile
CC = gcc
CFLAGS = -Wall -Wextra -pedantic
.PHONY: all clean
all: main
main: main.o item.o inventory.o
$(CC) $(CFLAGS) -o main main.o item.o inventory.o
main.o: main.c item.h inventory.h
$(CC) $(CFLAGS) -c main.c -o main.o
item.o: item.c item.h
$(CC) $(CFLAGS) -c item.c -o item.o
inventory.o: inventory.c inventory.h item.h
$(CC) $(CFLAGS) -c inventory.c -o inventory.o
clean:
rm -f main.o item.o inventory.o main