Rețeaua de curent electric a unei țări este un sistem complex, format din producători, distribuitori, consumatori (casnici sau industriali) și instituții ale statului care reglementează și supraveghează buna funcționare a sistemului.
Proiectul se bazează pe simularea unui sistem energetic în care vom avea diferite entități cu atribuții bine definite, care vor fi introduse pe parcurs - producători, distribuitori, consumatori, etc. Toate aceste entități încearca să-și îndeplinească îndatoririle având drept scop final rămânerea pe piața și evitarea falimentului. Acesta este structurat pe două etape, deci este recomandat să aveți un cod cât mai generic, pentru a fi ușor de adaugat noi funcționalități la etapa următoare. În aceasta etapa vom lua în considerare 2 entități: distribuitori și consumatori.
Math.round(Math.floor(1.2*factura veche)) + factura nouă
Distribuitorii vor reprezenta companiile responsabile cu oferirea surselor de energie. Fiecare astfel de companie va fi vizitata în fiecare luna de consumatori dornici sa afle ce oferta pot obține. Un distribuitor poate schimba caracteristicile noilor contracte (costurile de întreținere și durata) în fiecare luna, noile valori regasindu-se in input. Distribuitorii vor avea și ei un buget de început, la care lunar se va adăuga profitul obtinut. Întrucât aceștia au de achitat preturi atat pentru infrastructură cât și pentru producție, formula prețului contractului diferă în funcție de numărul de clienți.
Prețul contractului va fi recalculat la începutul fiecărei luni folosind noile informații despre distribuitor primite in input. Costurile vor fi precizate în fișierul de intrare iar profitul va fi considerat 20% din costul de producție. Un distribuitor, indiferent dacă are sau nu clienți, va fi nevoit ca la finalul fiecărei luni sa plătească costurile pentru infrastructură companiei. Costul de producție va fi plătit doar dacă exista clienți la finalul acelei luni. Astfel, dacă o companie nu reușește sa atraga clienti pe un timp îndelungat, atunci aceasta va da faliment și va ieși din joc. Clienții firmei ce a dat faliment își vor căuta o nouă oferta luna viitoare.
Simularea este bazată pe runde reprezentate de luni. La finalul fiecărei luni, toți consumatorii înregistrați trebuie să aibă o sursa de electricitate, altfel se consideră că aceștia nu își pot permite și sunt dați afara din joc. La fel se întâmplă și cu distribuitorii ce rămân fără bani, cu precizarea ca în momentul falimentarii, toți consumatorii ce au contract cu acesta, vor trebui să își formeze alt contract incepand cu luna următoare.
La începutul fiecărei luni distribuitorii vor stabili noile prețuri, urmând ca după ce aceștia termină, să vina rândul consumatorilor, care vor alege un contract (dacă nu au deja unul), urmând ca la finalul lunii să plătească rata curentă. Simularea începe cu o runda inițială, unde sunt folosite datele primite la început, apoi sunt rulate numberOfTurns luni, care se folosesc de noile preturi primite la începutul fiecărei luni. Astfel, simularea se termină când au fost rulate numberOfTurns + 1 runde și se afișează starea curentă a simulării. În cazul în care toți distribuitorii dau faliment, jocul se va încheia.
Math.round(Math.floor(costul infrastructurii / numărul de consumatori curenți) + costul producției + profitul)
costul infrastructurii + costul producției + profitul
profit = Math.round(Math.floor(0.2 * costul producției))
Cost total = cost infrastructură + cost producție * număr de consumatori curenți
Ne dorim să modelăm această simulare în stilul orientat-obiect. Vom citi configurația și desfășurarea unui joc dintr-un fișier de intrare, vom rula jocul și vom scrie într-un fișier de ieșire stările entităților. În soluțiile voastre, entry-point-ul (metoda public static void main(String[] args)) va fi clasa numită Main, aflata în scheletul temei. Primul argument este numele fișierului de intrare, al doilea este numele fișierului de ieșire. Nu schimbați numele clasei Main sau ordinea argumentelor. Implementarea voastra va trebui sa contina in mod obligatoriu design pattern-urile Factory si Singleton. De asemenea, în README, trebuie să documentați în care parte/părți din implementare l-ați folosit și să explicați, într-un mod clar și concis, modul de abordare. În explicații să vă axati pe flow-ul programului și pe modul în care se leaga componentele.
Atât inputul, cât și outputul vor fi de tip json. Mai multe informații despre citirea fișierelor json aici.
Pentru testarea solutiei, rulati functia main a clasei Test. Aceasta va rula atat testele, cat si checkstyle-ul. Pentru rularea checkerului, aveti nevoie ca proiectul vostru sa aiba incarcate bibliotecile pentru citirea fisierelor json. Mai multe detalii aici.
Punctajul constă din:
Depunctarile pentru designul și organizarea codului se vor scădea din punctajul testelor. Dacă vor apărea depunctari specifice temei în momentul evaluării, nemenționate pe pagina cu depunctări generale, ele se vor încadra în limitele de maxim 15 pentru design, 10p pentru readme. Dacă tema nu respecta cerințele, sau are zero design OOP atunci se pot face depunctari suplimentare.
Bonusuri: La evaluare, putem oferi bonusuri pentru design foarte bun, cod bine documentat dar și pentru diverse elemente suplimentare alese de voi.
Unul din obiectivele temei este învățarea respectării code-style-ului limbajului pe care îl folosiți. Aceste convenții (de exemplu cum numiți fișierele, clasele, variabilele, cum indentați) sunt verificate pentru temă de către tool-ul checkstyle.
Pe pagina de Recomandări cod găsiți câteva exemple de coding style.
Dacă numărul de erori depistate de checkstyle depășește 30, atunci punctele pentru coding-style nu vor fi acordate. Dacă punctajul este negativ, acesta se trunchiază la 0.
Exemple:
punctaj_total = 125
și nr_erori = 200
⇒ nota_finala = 115
punctaj_total = 125
și nr_erori = 29
⇒ nota_finala = 125
punctaj_total = 80
și nr_erori = 30
⇒ nota_finala = 80
punctaj_total = 80
și nr_erori = 31
⇒ nota_finala = 70
Arhiva pe care o veţi urca pe VMChecker va trebui să conţină în directorul rădăcină:
README