Table of Contents

Proiect - Etapa 1 - Sistem energetic

Obiective

Scenariu

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.

Consumatori

Distribuitori

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.

Mecanismul simulării

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.

Formulele:

Cerinte

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.

Input

Atât inputul, cât și outputul vor fi de tip json. Mai multe informații despre citirea fișierelor json aici.

Click pentru exemplu input

Click pentru exemplu input

{
  "numberOfTurns": 3,
  "initialData": {
	"consumers": [{
	  "id": 0,
	  "initialBudget": 10,
	  "monthlyIncome": 30
	},{
	  "id": 1,
	  "initialBudget": 100,
	  "monthlyIncome": 20
	}],
	"distributors": [{
	  "id": 0,
	  "contractLength": 1,
	  "initialBudget": 200,
	  "initialInfrastructureCost": 20,
	  "initialProductionCost": 10
	},{
	  "id": 1,
	  "contractLength": 3,
	  "initialBudget": 100,
	  "initialInfrastructureCost": 10,
	  "initialProductionCost": 5
	}]
  },
  "monthlyUpdates": [{
	"newConsumers": [{
	  "id": 2,
	  "initialBudget": 5,
	  "monthlyIncome": 1
	}],
	"costsChanges": [{
	  "id": 0,
	  "infrastructureCost": 5,
	  "productionCost": 5
	}]
  },{
	"newConsumers": [],
	"costsChanges": [{
	  "id": 1,
	  "infrastructureCost": 15,
	  "productionCost": 5
	}]
  },{
	"newConsumers": [],
	"costsChanges": []
  }]
}

Output

Click pentru exemplu output

Click pentru exemplu output

{
  "consumers" : [ {
    "id" : 0,
    "isBankrupt" : false,
    "budget" : 71
  }, {
    "id" : 1,
    "isBankrupt" : false,
    "budget" : 121
  }, {
    "id" : 2,
    "isBankrupt" : true,
    "budget" : 7
  } ],
  "distributors" : [ {
    "id" : 0,
    "budget" : 167,
    "isBankrupt" : false,
    "contracts" : [ {
      "consumerId" : 0,
      "price" : 11,
      "remainedContractMonths" : 0
    }, {
      "consumerId" : 1,
      "price" : 11,
      "remainedContractMonths" : 0
    } ]
  }, {
    "id" : 1,
    "budget" : 116,
    "isBankrupt" : false,
    "contracts" : [ ]
  } ]
}

Indicații

Testarea soluției

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.

Evaluare

Punctajul constă din:

Pe pagina Indicații pentru teme găsiți indicații despre scrierea readme-ului și depunctările generale pentru teme

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.

Temele vor fi testate împotriva plagiatului. Orice tentativă de copiere va duce la anularea punctajului de pe parcursul semestrului şi repetarea materiei atât pentru sursă(e) cât şi pentru destinație(ii), fără excepție.

Checkstyle

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:

Upload temă

Arhiva pe care o veţi urca pe VMChecker va trebui să conţină în directorul rădăcină:

Resurse și linkuri utile