TerraBot - let's explore and save the planet !
-
-
Data publicării BETA testing: 21.10.2025
Deadline HARD BETA testing: 10.11.2025
Data publicării oficiale: 10.11.2025
Deadline HARD oficial: 30.11.2025
Ultima modificare (cerință, schelet sau teste): 21.10.2025
-
Soluția voastră trebuie implementată folosind
principiile programării orientate pe obiecte (OOP), nu în stil imperativ, ca în limbajul C.
Scopul exercițiului este să demonstrați înțelegerea conceptelor OOP, nu doar să obțineți un rezultat funcțional.
Dacă aveți 100p pe checker, însă soluția voastră nu este OOP, atunci veți obține o depunctare majoră conform baremului public!
Pentru detalii consultați acest ghid care conține baremul de corectare și alte guidelines.
Regulamentul pentru perioada de dezvoltare BETA îl găsiți
aici.
Informațiile de tip [Nice to know] din laborator vă pot ajuta la depanare sau la rezolvarea temei mai eficient.
Tema a fost concepută pentru a fi rezolvată folosind laboratoarele 1-6, dar puteți folosi concepte și din laboratoarele următoare.
Pentru perioada BETA, puteți folosi laboratoarele din anii trecuți pentru a găsi diverse informații, dar vă recomandăm să aprofundați doar următoarele concepte pentru această temă:
Obiective
Familiarizarea cu Java și conceptele de bază ale POO.
Fundamentarea practică a constructorilor și a agregării/moștenirii.
Dezvoltarea unor abilități de bază de organizare și design orientat obiect.
Scrierea unui cod cât mai generic, ce va permite ulterior adăugarea de noi funcționalități.
Familiarizarea conceptelor de polimorfism, abstractizare și încapsulare.
Utilizarea colecțiilor din Java.
Folosirea claselor speciale și a bibliotecii standard Java.
Respectarea unui stil de codare și de comentare.
Dezvoltarea aptitudinilor de depanare a problemelor în cod.
Introducere
TerraBot, robotul nostru explorator creat de NASA, are o misiune deosebită: să descopere o nouă planetă și să o pregătească pentru viitoarea colonizare. El trebuie să exploreze cât mai mult din suprafața planetei, să adune informații esențiale despre mediul înconjurător și să contribuie la îmbunătățirea condițiilor de viață. Totuși, fiți atenți, deoarece energia lui TerraBot este limitată, așa că fiecare acțiune trebuie planificată cu grijă pentru a garanta succesul misiunii!
Misiunea lui TerraBot
Odată lansat în misiune, TerraBot intră într-un mediu complet necunoscut, unde fiecare regiune a planetei ascunde provocări și condiții diferite. Robotul nostru este programat să efectueze simulări experimentale, fiecare având scopul de a observa cum evoluează ecosistemul, de a colecta date despre plante, animale, apă și sol, și de a aplica diferite metode pentru a menține mediul sănătos și sustenabil.
Pe parcursul fiecărei simulări, TerraBot experimentează, analizează datele obținute și ia decizii autonome pentru a-și îndeplini obiectivele. O simulare reprezintă o rundă completă de explorare: mediul se modifică în timp real, resursele sunt limitate, iar robotul trebuie să acționeze eficient și adaptabil. Astfel, în cadrul testelor pot exista una sau mai multe simulări, permițându-vă să evaluați performanța TerraBot în scenarii
diferite.
Fiecare test are următoarea structură:
Se generează preambulul – se creează harta planetei, cu toate entitățile poziționate pe celule (vezi secțiunea Desfășurarea simulării).
Se inițiază simularea.
Se desfășoară simularea propriu-zisă – TerraBot primește comenzi, reacționează la mediu și se actualizează starea planetei.
Se finalizează simularea.
Se repetă pașii de mai sus pentru fiecare simulare indicată în cadrul testului.
Desfășurarea unei simulări
Fiecare simulare trebuie să înceapă cu comanda startSimulation și să se încheie cu endSimulation.
1. Evoluția automată a mediului
Se produce independent de acțiunile TerraBot și reflectă procese naturale:
calitatea aerului, solului și apei se modifică în timp (în această ordine)
plantele cresc sau se ofilesc
animalele se deplasează și își schimbă starea (consumă plante sau apă)
2. Acțiunile TerraBot
Se execută pe baza comenzilor trimise:
se deplasează pe hartă
scanează mediul și învață informații (facts)
colectează plante, animale sau apă în inventar
aplică metode de îmbunătățire a mediului
explorează noi zone în funcție de calitatea mediului
Ce este o iterație?
O simulare este împărțită în iterații (unități de timp).
La fiecare iterație se execută ambele procese în această ordine: evoluția mediului și acțiunile robotului.
1 iterație = 1 timestamp
O simulare este considerată validă doar dacă toate iterațiile sunt corect procesate.
Doar comenzile aflate între aceste două marcaje sunt considerate valide și vor fi executate. Prin urmare, o simulare trebuie să aibă atât un început, cât și un sfârșit.
Condițiile inițiale ale simulării
La începutul fiecărei simulări:
La începutul fiecărui test, veți primi harta completă împreună cu toți parametrii inițiali.
Harta simulării
Imaginea de mai sus prezintă structura hărții și pozițiile exemplificative pentru TerraBot și elementele mediului.
Pentru detalii despre mișcările robotului, acțiuni și comenzile disponibile, consultați secțiunea Comenzi
.
Entități
Există mai multe tipuri de entități care se pot afla pe o pătrățică:
Plant
Animal
Water
Air
Soil
Caracteristici comune pentru toate entitățile
Toate entitățile de mai sus au următoarele atribute comune:
| Nume | Descriere | Tip |
| name | Numele entității | String |
| mass | În funcție de tipul clasei:
- soil: greutatea totală a solului
- air: greutatea tuturor gazelor găsite în acel tip de aer
- water: greutatea apei lichide dintr-un rezervor (lac, râu, iaz).
- animal: greutatea animalului.
- plant: biomasa plantei. | double |
Plant
Tipurile de plante sunt impărțite în 5 categorii:
FloweringPlants
GymnospermsPlants
Ferns
Mosses
Algae
Interactiuni cu mediul
O plantă are un singur tip de efect: ea crește nivelul de oxigen din aer, interacționând direct cu mediul atmosferic.
Fiecare plantă generează oxigen în atmosferă în funcție de:
oxigen_level += (maturity_oxigen_rate + oxigen_from_plant)
Tabel combinat – Oxigen generat de plante
| Categorie plantă | O₂ din categorie | Young (+0.2) | Mature (+0.7) | Old (+0.4) |
| FloweringPlants | 6.0 | 6.2 | 6.7 | 6.4 |
| GymnospermsPlants | 0 | 0.2 | 0.7 | 0.4 |
| Ferns | 0 | 0.2 | 0.7 | 0.4 |
| Mosses | 0.8 | 1.0 | 1.5 | 1.2 |
| Algae | 0.5 | 0.7 | 1.2 | 0.9 |
Când nivelul de oxigen devine
mai mare de o unitate (1.0), planta va trece la următorul nivel de maturitate:
Posibilitatea de a bloca TerraBot
Fiecare categorie de plantă are asociat un procentaj care indică probabilitatea ca roboțelul să se agațe de acea plantă.
plant_possibility / 100.0
Probabilitate de agățare
| Tip | Posibilitate |
| Flowering Plants (Angiosperms) | 90% |
| Gymnosperms | 60% |
| Ferns | 30% |
| Mosses | 40% |
| Algae | 20% |
Animal
Animalele se deplasează pe hartă și consumă plantele întâlnite, ceea ce le permite să producă îngrășământ și să îmbunătățească calitatea solului.
Doar animalele scanate vor realiza acțiuni automate pe hartă, indiferent de proximitatea lor față de robot. Mai întâi se procesează mișcările, apoi hrănirea.
Mișcarea pe hartă
Animalul se mută pe una din pătrățelele vecine la fiecare 2 iterații pentru a se hrăni. Algoritmul de alegere este:
Se caută pătrățica care are plantă și apă. Dacă există mai multe, se alege cea cu calitatea apei mai bună.
Dacă nu există, se caută pătrățica care are plantă sau apă:
Dacă există plante, se alege prima pătrățică conform parcurgerii (sus, dreapta, jos, stânga).
Dacă nu există plante, se alege pătrățica cu apă, prioritar cea cu calitate mai bună.
Nu există situații de test cu calitate egală a apei între pătrățele sau fără pătrățică cu apă sau plantă.
Starea animalului și producția de îngrășământ
Animalul poate fi în una din stările:
| Stare | Condiție | Efect |
| hungry | Nu a mâncat sau nu a băut apă | Nu produce îngrășământ |
| well-fed | A mâncat Plant, Water sau Animal | Produce îngrășământ |
| sick | Aerul este toxic | Nu produce îngrășământ |
Algoritmul de hrănire
dacă animalul este de tip Carnivore sau Parasite
se va mânca animalul de pe pătrățica curentă dacă există:
se va crește masa animalului curent: animalMass += preyMass.
entitatea Soil de pe pătrățica curentă va primi +0.5 organicMatter.
animalul mâncat va dispărea de pe hartă.
dacă nu există un animal:
dacă entitea Water și entitea Plant de pe pătrățică au fost deblocate deja la un pas anterior sau prezent de către robot:
planta va muri.
se va calcula nivelul de apă de băut: waterToDrink = Math.min(animalMass * intakeRate, waterMass), intakeRate = 0.08.
se va actualiza masa apei: waterMass -= waterToDrink.
se va crește masa animalului curent: animalMass += (waterToDrink + plantMass).
entitatea Soil de pe pătrățica curentă va primi +0.8 organicMatter.
se va mânca entitatea Water sau Plant, în funcție de care entitate este deblocată prima de robot:
dacă se va mânca planta:
dacă se va bea apă:
se va calcula nivelul de apă de băut: waterToDrink = Math.min(animalMass * intakeRate, waterMass), intakeRate = 0.08.
se va actualiza masa apei: waterMass -= waterToDrink.
se va crește masa animalului curent: animalMass += waterToDrink.
entitatea Soil de pe pătrățica curentă va primi +0.5 organicMatter.
dacă nicio entitate de pe pătrățica curentă nu a fost deblocată la un pas anterior sau prezent de către robot nu se va mânca nimic.
dacă animalul nu este de tip Carnivore sau Parasite:
Un animal consumă doar entitățile deblocate de robot; animalele străine sunt mâncate imediat dacă este cazul.
Posibilitatea de a ataca TerraBot
Animalele pot ataca robotul chiar dacă nu au fost deblocate.
attack_probability = (100 - animal_possibility_to_attack) / 10.0
Tabel de probabilități
| Tip | Posibilitate |
| Herbivores | 85% |
| Carnivores | 30% |
| Omnivores | 60% |
| Detritivores | 90% |
| Parasites | 10% |
Water
Apa este o resursă esențială în ecosistem, influențând direct solul, aerul, plantele și animalele. Fără apă, ciclurile biologice nu pot funcționa.
Caracteristici principale
| Câmp | Descriere | Tip |
| salinity | Concentrația de sare a apei | double |
| pH | Aciditatea/alcalinitatea apei | double |
| purity | Nivelul de puritate al apei, în procente | double |
| turbidity | Nivelul de turbiditate al apei | int |
| contaminantIndex | Indice ce indică concentrația contaminanților | double |
| isFrozen | Indică dacă apa este înghețată | boolean |
Interactiuni cu mediul
Apa influențează direct celelalte entități ale ecosistemului:
| Entitate | Efect | Rată / Iterație |
| Soil | Crește waterRetention | +0.1 timp de 2 iterații |
| Air | Crește humidity | +0.1 timp de 2 iterații |
| Plant | Contribuie la creștere | +0.2 la fiecare iterație |
Calculul calității apei
Calitatea apei se determină în doi pași:
Normalizarea factorilor:
purity_score = purity / 100
pH_score = 1 - abs(pH - 7.5) / 7.5
salinity_score = 1 - (salinity / 350)
turbidity_score = 1 - (turbidity / 100)
contaminant_score = 1 - (contaminantIndex / 100)
frozen_score = isFrozen ? 0 : 1
Formula finală:
water_quality =
(0.3 * purity_score
+ 0.2 * pH_score
+ 0.15 * salinity_score
+ 0.1 * turbidity_score
+ 0.15 * contaminant_score
+ 0.2 * frozen_score) * 100
Interpretare rezultat
| Interval | Calitate apă |
| 70–100% | Good |
| 40–70% | Moderate |
| < 40% | Poor |
Soil
Solul este esențial pentru creșterea plantelor și îmbunătățirea mediului. Acesta își poate crește calitatea prin absorbția apei și prin primirea de îngrășământ.
Caracteristici principale
| Câmp | Descriere | Tip |
| nitrogen | Conținutul de azot (%) | double |
| waterRetention | Capacitatea solului de a reține apa | double |
| soilpH | Nivelul de aciditate/alcalinitate al solului | double |
| organicMatter | Conținutul de materie organică (%) | double |
Interacțiuni cu mediul
Solul interacționează cu plantele și apa:
| Entitate | Efect | Rată / Iterație |
| Plant | Creștere +0.2 | la fiecare iterație |
| Water | Absorbție +0.1 apă | la fiecare 2 iterații dacă există sursă de apă |
Calculul calității solului
Formula de calcul depinde de tipul solului:
| Tip sol | Formula |
| ForestSoil | (nitrogen * 1.2) + (organicMatter * 2) + (waterRetention * 1.5) + (leafLitter * 0.3) |
| SwampSoil | (nitrogen * 1.1) + (organicMatter * 2.2) - (waterLogging * 5) |
| DesertSoil | (nitrogen * 0.5) + (waterRetention * 0.3) - (salinity * 2) |
| GrasslandSoil | (nitrogen * 1.3) + (organicMatter * 1.5) + (rootDensity * 0.8) |
| TundraSoil | (nitrogen * 0.7) + (organicMatter * 0.5) - (permafrostDepth * 1.5) |
Normalizarea scorului
normalizeScore = Math.max(0, Math.min(100, score))
Interpretare scor
| Interval | Calitate sol |
| 70–100% | Good |
| 40–70% | Moderate |
| <40% | Poor |
Probabilitate de a bloca TerraBot
| Tip sol | Formulă probabilitate |
| ForestSoil | (waterRetention * 0.6 + leafLitter * 0.4) / 80 * 100 |
| SwampSoil | waterLogging * 10 |
| DesertSoil | (100 - waterRetention + salinity) / 100 * 100 |
| GrasslandSoil | ((50 - rootDensity) + waterRetention * 0.5) / 75 * 100 |
| TundraSoil | (50 - permafrostDepth) / 50 * 100 |
Air
Aerul este esențial pentru ecosistem, permițând animalelor să respire și să interacționeze cu mediul. Monitorizarea calității aerului este crucială pentru sănătatea animalelor și funcționarea TerraBot.
Caracteristici principale
| Câmp | Descriere | Tip |
| humidity | Umiditate relativă (%) | double |
| temperature | Temperatură ambientală (°C) | double |
| oxygenLevel | Concentrație de oxigen | double |
Calitatea aerului și toxicitatea
Calitatea aerului este calculată diferit pentru fiecare tip, folosind câmpurile specifice:
| Tip de aer | Câmp specific | Formula calitate aer |
| tropical | co2Level | (oxygenLevel*2) + (humidity*0.5) - (co2Level*0.01) |
| polar | iceCrystalConcentration | (oxygenLevel*2) + (100-Math.abs(temperature)) - (iceCrystalConcentration*0.05) |
| temperat | pollenLevel | (oxygenLevel*2) + (humidity*0.7) - (pollenLevel*0.1) |
| de desert | dustParticles | (oxygenLevel*2) - (dustParticles*0.2) - (temperature*0.3) |
| montan | altitude | oxygenFactor = oxygenLevel - (altitude/1000*0.5) (oxygenFactor*2) + (humidity*0.6) |
Interpretarea scorurilor
| Valoare | Interpretare |
| 70-100% | good |
| 40-70% | moderate |
| <40 | poor |
Calculul toxicității aerului
Nivelul de toxicitate se calculează astfel:
toxicityAQ = 100 * (1 - airQualityScore / maxScore)
finalResult = Math.round(toxicityAQ * 100.0) / 100.0
| Tip de aer | MaxScore |
| Tropical | 82 |
| Polar | 142 |
| Temperate | 84 |
| Desert | 65 |
| Mountain | 78 |
Schimbări meteo
Evenimentele meteorologice modifică calitatea aerului:
| Tip de aer | Eveniment | Formula actualizare |
| tropical | rainfall | normal_air_quality + (rainfall*0.3) |
| polar | polarStorm | normal_air_quality - (windSpeed*0.2) |
| temperat | newSeason | seasonPenalty = season.equalsIgnoreCase("Spring") ? 15 : 0 normal_air_quality - seasonPenalty |
| de desert | desertStorm | normal_air_quality - (desertStorm ? 30 : 0) |
| montan | peopleHiking | normal_air_quality - (numberOfHikers*0.1) |
Rotunjirea scorurilor pentru calitate cât și pentru toxicitate se face astfel:
Math.round(score * 100.0) / 100.0
Posibilitatea de a afecta TerraBot
Toxicitatea aerului și calitatea acestuia pot influența animalele și TerraBot. Se folosesc formulele din secțiunea Interacțiuni cu mediul pentru calcul.
Interacțiuni între entități
În simulare, entitățile din mediu (Air, Soil, Water, Plant, Animal) pot interacționa între ele, influențându-se reciproc în timp.
Ordinea exactă în care sunt aplicate interacțiunile și actualizările este mereu aceeași:
Air
Soil
Water
Plant
Animal
Toate interacțiunile cu Plant, Animal și Water sunt posibile doar după ce TerraBot a scanat entitatea respectivă. Abia după scanare pot începe actualizările automate asociate acelei entități.
Frecvența interacțiunilor automate
| Interacțiune | Efect | Frecvență |
| Air → Animal | Dacă aerul devine toxic → animalul devine sick | Verificat la fiecare iterație |
| Soil → Plant | +0.2 creștere la plantă | La fiecare iterație |
| Water → Air | +0.1 humidity | La fiecare 2 iterații |
| Water → Soil | +0.1 waterRetention | La fiecare 2 iterații |
| Water → Plant | +0.2 creștere la plantă | La fiecare iterație |
| Plant → Air | + oxigen în aer | La fiecare iterație |
| Animal → Soil | + organicMatter în sol dacă animalul devine well-fed | Verificat la fiecare iterație |
| Animal → Water | +0.3 îngrășământ în apă | La fiecare iterație |
| Animal → Plant | Animalul mănâncă planta | Doar după ce planta a fost scanată |
Exemplu de întârziere a interacțiunilor
Dacă la timestamp 3 se primește comanda scanObject pentru apă, atunci:
Abia la timestamp 5 vor începe actualizările (conform frecvențelor de mai sus) pentru:
Comanda de la timestamp 5 se execută doar după aplicarea tuturor actualizărilor automate.
Reguli generale pentru interacțiuni
Fiecare simulare este independentă. Nu se păstrează inventarul robotului, energia sau starea mediului între simulări.
Simulările se execută una după alta, nu există simulări în paralel.
Comenzile trimise între endSimulation și următorul startSimulation sunt ignorate.
Fiecare celulă de pe hartă poate conține:
maxim 1 plantă
maxim 1 animal
maxim 1 sursă de apă
Air și Soil vor fi limitate tot doar la o singură entitate per tip, doar că acestea sunt complet disponibile de la începutul simulării, pe când restul entităților trebuie scanate înainte de a face anumite acțiuni cu alte entități.
Comenzi
Comenzi pentru simulare
startSimulation
Mesaje posibile pentru această comandă:
"Simulation has started."
"ERROR: Simulation already started. Cannot perform action"
Click pentru input startSimulation
Click pentru input startSimulation
{
"command": "startSimulation",
"timestamp": 1
}
Output
Click pentru output startSimulation
Click pentru output startSimulation
{
"command": "startSimulation",
"message": "Simulation has started.",
"timestamp": 1
}
endSimulation
Mesaje posibile pentru această comandă:
-
"ERROR: Simulation not started. Cannot perform action"
Click pentru input startSimulation
Click pentru input startSimulation
{
"command": "endSimulation",
"timestamp": 10
}
Output
Click pentru output startSimulation
Click pentru output startSimulation
{
"command": "endSimulation",
"message": "Simulation has ended.",
"timestamp": 10
}
Comenzi pentru mediu
changeWeatherConditions
Schimbarea meteo se ia în considerare DOAR pentru celulele care au acel tip de aer.
Mesaje posibile pentru această comandă:
"The weather has changed."
"ERROR: The weather change does not affect the environment. Cannot perform action"
"ERROR: Simulation not started. Cannot perform action"
Click pentru input changeWeatherConditions
Click pentru input changeWeatherConditions
{
"command": "changeWeatherConditions",
"type": "desertStorm",
"windSpeed": 25.0,
"timestamp": 10
},
{
"command": "changeWeatherConditions",
"type": "rainfall",
"rainfall": 12.5,
"timestamp": 11
},
{
"command": "changeWeatherConditions",
"type": "peopleHiking",
"numberOfHikers": 40,
"timestamp": 12
}
Output
Click pentru output changeWeatherConditions
Click pentru output changeWeatherConditions
{
"command": "changeWeatherConditions",
"message": "The weather has changed.",
"timestamp": 10
},
{
"command": "changeWeatherConditions",
"message": "The weather has changed.",
"timestamp": 11
},
{
"command": "changeWeatherConditions",
"message": "The weather has changed.",
"timestamp": 12
}
Comenzi pentru TerraBot
moveRobot
consumă energie
robotul se va muta pe pătrățelul cu scorul de calitate cel mai bun
nu se poate explora mai departe de dimensiunea maximă a matricei
se verifică dacă robotul are suficientă baterie pentru a se putea muta
se poate trece în timpul simulării prin aceeași pătrățică
consumul de baterie pentru mutare este raportat la scorul de calitate
Roboțelul nu poate să ramână pe pătrățica curentă. Dacă acesta mai are suficientă baterie pentru a efectua mutarea, atunci trebuie să aleagă neaparat una dintre pătrățelele vecine
Deplasare robot
Se va duce pe pătrățelul cu scorul de calitate cel mai bun (normalizat, de la 0 la 100, 100 find 0 scor la toate)
ordinea în care se verifică celulele: sus, dreapta, jos, stânga
pentru calcularea scorului, se vor lua în considerare următoarele lucruri
PossibilityToGetStuckInSoil
PossibilityToGetDamagedByAir
PossibilityToBeAttackedByAnimal
PossibiltyToGetStuckInPlants
scorul final se calculează ca și medie aritmetică din cele 4 scori pentru fiecare posibilitate
i se va scădea din baterie numărul de puncte echivalent cu valoarea scorulului obținut pentru celula pe care se va muta robotul (vezi exemplu mai jos)
double sum = sum(possibilityToGetStuckInSoil + possibilityToGetDamagedByAir + possibilityToBeAttackedByAnimal + possibiltyToGetStuckInPlants)
double mean = sum / count
int result = (int) Math.round(mean)
Dacă se obține același scor de calitate pentru una sau mai multe celule sau celula obținută este în afara hărții, atunci se alege prima din ordine în care s-au verificat celulele.
Se va verifica că robotul are suficientă baterie pentru a efectua mutarea.
Baterie robot
Robotul poate să rămână fără baterie înainte să se mute pe altă pătrățică
dacă robotul nu mai are baterie el nu se va deplasa până când nu se primește comada rechargeBattery pentru a-și încărca bateria, dar restul pașilor se vor executa, inclusiv cei de analiză și funcționalitățile automate din spate
bateria se va consuma pentru fiecare mișcare a robotului pe altă celulă
Exemplu
Scor total de calitate pasul trecut = 2 → se vor scădea 2 unități din baterie
Mesaje posibile pentru această comandă:
"The robot has successfully moved to position ${(coord_X, coord_Y)}."
"ERROR: Not enough battery left. Cannot perform action"
"ERROR: Robot still charging. Cannot perform action"
"ERROR: Simulation not started. Cannot perform action"
Click pentru input moveRobot
Click pentru input moveRobot
{
"command": "moveRobot",
"timestamp": 2
}
Output
Click pentru output moveRobot
Click pentru output moveRobot
{
"command": "moveRobot",
"message": "The robot has successfully moved to position (0,2)."
}
rechargeBattery
se pune pauză simulării curente în derulare pentru ca roboțelul să se încarce unde se află în mod curent (are panouri solare 😎)
se încarcă numărul de puncte de energie primite la input (1 punct de energie = 1min de încărcare)
Nu se poate pune pauză dacă o simulare tocmai s-a încheiat.
Dacă nu s-a terminat încărcarea, se va returna eroare că roboțelul este încă la încărcat pentru orice comandă pentru robot dată în această perioadă.
Mesaje posibile pentru această comandă:
"The simulation was paused until charging is finished."
"ERROR: Robot still charging. Cannot perform action"
"ERROR: Simulation not started. Cannot perform action"
Click pentru input rechargeBattery
Click pentru input rechargeBattery
{
"command": "rechargeBattery",
"timeToCharge": 20,
"timestamp": 10
}
Output
Click pentru output rechargeBattery
Click pentru output rechargeBattery
{
"command": "rechargeBattery",
"message": "The simulation was paused until charging is finished.",
"timestamp": 10
}
scanObject
consumă energie
scanează un obiect (plantă, animal, apă) și salvează rezultatul (se salvează în baza de date și în inventar)
se caută în harta salvată pentru secțiunea curentă de teritoriu dacă există un obiect de tipul respectiv pentru scanat (nu este garantat că se găsește pe hartă)
consumă 7 puncte energie
Roboțelul scanează obiectele de pe pătrățica curentă și determină tipul acestuia în funcție de 3 parametrii:
Combinațiile de parametrii pentru obiecte:
none + none + none = water
pink + sweet + none = plant
brown + earthy + muuu = animal
Se va verifica în baza de date că există pe pătrățică acel tip de obiect. Dacă da, se returnează restul de detalii pentru el și robotul va salva în baza de date și în inventarul sau noul obiect găsit. Dacă nu, se va returna eroare.
Un obiect începe să existe abia după ce a fost scanat. Așadar, o plantă/ animal vor începe să își schimbe statusul doar dupa ce au fost scanate
Exemplu: un animal nu poate să mănânce planta de pe pătrățica curentă până aceasta nu a fost scanată.
Mesaje posibile pentru această comandă:
"The scanned object is ${type_of_entity}"
"ERROR: Object not found. Cannot perform action"
"ERROR: Not enough battery left. Cannot perform action"
"ERROR: Simulation not started. Cannot perform action"
Click pentru input scanObject
Click pentru input scanObject
{
"command": "scanObject",
"color": "none",
"smell": "none",
"sound": "none",
"timestamp": 4
},
{
"command": "scanObject",
"color": "pink",
"smell": "sweet",
"sound": "none",
"timestamp": 5
},
{
"command": "scanObject",
"color": "brown",
"smell": "earthy",
"sound": "muu",
"timestamp": 6
}
Output
Click pentru output scanObject
Click pentru output scanObject
{
"command": "scanObject",
"message": "The scanned object is water.",
"timestamp": 4
},
{
"command": "scanObject",
"message": "The scanned object is a plant.",
"timestamp": 5
},
{
"command": "scanObject",
"message": "The scanned object is an animal.",
"timestamp": 6
}
learnFact
consumă energie
adaugă un nou fapt științific sub un anumit subiect
se primește un subiect și componentele pentru acel subiect, mai multe detalii la comanda de improveEnvironment
consumă 2 puncte energie
Exemplu
Dacă TerraBot a descoperit (scanat) o plantă nouă RedAlgae și se primește comanda de learnFact ce include în subiect RedAlgae, va căuta în obiectele salvate dacă există această plantă. Dacă da, va salva informația dată sub numele / subiectul acestei plante.
Nu se pot învăța facts până când TerraBot nu a scanat acel obiect
Mesaje posibile pentru această comandă:
"The fact has been successfully saved in the database."
"ERROR: Subject not yet saved. Cannot perform action"
"ERROR: Not enough battery left. Cannot perform action"
"ERROR: Simulation not started. Cannot perform action"
Click pentru input learnFact
Click pentru input learnFact
{
"command": "learnFact",
"subject": "Method to plant RedAlgae",
"components": "RedAlgae",
"timestamp": 4
},
{
"command": "learnFact",
"subject": "Characteristic of RedAlgae",
"components": "RedAlgae",
"timestamp": 5
}
Output
Click pentru output learnFact
Click pentru output learnFact
{
"command": "learnFact",
"message": "The fact has been successfully saved in the database.",
"timestamp": 4
},
{
"command": "learnFact",
"message": "The fact has been successfully saved in the database.",
"timestamp": 5
}
improveEnvironment
Putem avea 4 tipuri de improvement:
plantVegetation
fertilizeSoil
increaseHumidity
increaseMoisture
Ca să se efectueze comanda cu succes, trebuie să fie îndeplinite
2 condiții:
Hint: Practic e ca un fel de rețetă, trebuie să o cunoști și să ai ingredientele necesare ca să poți face improve.
Mesaje posibile pentru această comandă:
"The ${plant_name} was planted successfully."
"The ${improved_entity} was successfully ${fertilized /increased } using ${component_name}"
"ERROR: Subject not yet saved. Cannot perform action"
"ERROR: Fact not yet saved. Cannot perform action"
"ERROR: Not enough battery left. Cannot perform action"
"ERROR: Simulation not started. Cannot perform action"
Click pentru input improveEnvironment
Click pentru input improveEnvironment
{
"command": "improveEnvironment",
"improvementType": "plantVegetation",
"type": "Algae",
"name": "RedAlgae",
"timestamp": 6
},
{
"command": "improveEnvironment",
"improvementType": "fertilizeSoil",
"type": "Herbivores",
"name": "Cow",
"timestamp": 7
},
{
"command": "improveEnvironment",
"improvementType": "increaseHumidity",
"type": "river",
"name": "Blue River",
"timestamp": 8
},
{
"command": "improveEnvironment",
"improvementType": "increaseMoisture",
"type": "river",
"name": "Blue River",
"timestamp": 9
}
Output
Click pentru output improveEnvironment
Click pentru output improveEnvironment
{
"command": "improveEnvironment",
"message": "The RedAlgae was planted successfully.",
"timestamp": 6
},
{
"command": "improveEnvironment",
"message": "The soil was successfully fertilized using Cow.",
"timestamp": 7
},
{
"command": "improveEnvironment",
"message": "The humidity was successfully increased using Blue River.",
"timestamp": 8
},
{
"command": "improveEnvironment",
"message": "The moisture was successfully increased using Blue River.",
"timestamp": 9
}
Comenzi de debug
getEnergyStatus
Mesaje posibile pentru această comandă:
"TerraBot has ${energy_points} energy points left."
"ERROR: Simulation not started. Cannot perform action"
Click pentru input getEnergyStatus
Click pentru input getEnergyStatus
{
"command": "getEnergyStatus",
"timestamp": 8
}
Output
Click pentru output getEnergyStatus
Click pentru output getEnergyStatus
{
"command": "getEnergyStatus",
"message": "TerraBot has 189 energy points left.",
"timestamp": 8
}
printEnvConditions
Mesaje posibile pentru această comandă:
"ERROR: Simulation not started. Cannot perform action"
Click pentru input printEnvConditions
Click pentru input printEnvConditions
{
"command": "printEnvConditions",
"timestamp": 5
}
Output
Click pentru output printEnvConditions
Click pentru output printEnvConditions
{
"command" : "printEnvConditions",
"output" : {
"soil" : {
"type" : "ForestSoil",
"name" : "LightForestSoil",
"mass" : 1000.0,
"nitrogen" : 2.5,
"waterRetention" : 0.6,
"soilpH" : 6.7,
"organicMatter" : 0.3,
"soilQuality" : 4.56,
"leafLitter" : 0.2
},
"plants" : {
"type" : "FloweringPlants",
"name" : "Tulip",
"mass" : 0.5
},
"animals" : {
"type" : "Herbivores",
"name" : "Rabbit",
"mass" : 2.66
},
"water" : {
"type" : "pond",
"name" : "SmallPond",
"mass" : 29.84,
"purity" : "85.0",
"salinity" : "0.1",
"turbidity" : 2.0,
"contaminantIndex" : 0.5,
"temperature" : 15.0,
"pH" : 6.6,
"isFrozen" : false,
"volumeLiters" : 100.0
},
"air" : {
"type" : "TemperateAir",
"name" : "Spring Air",
"mass" : 900000.0,
"humidity" : 60.1,
"temperature" : 15.0,
"oxygenLevel" : 26.2,
"airQuality" : 93.47,
"pollenLevel" : 10.0
}
},
"timestamp" : 5
}
printMap
Mesaje posibile pentru această comandă:
"ERROR: Simulation not started. Cannot perform action"
Click pentru input printMap
Click pentru input printMap
{
"command": "printMap",
"timestamp": 23
}
Output
Click pentru output printMap
Click pentru output printMap
{
"command": "printMap",
"output": [
{
"section": [0,0],
"totalNrOfObjects": 1,
"airQuality": "good",
"soilQuality": "good"
},
{
"section": [0,1],
"totalNrOfObjects": 0,
"airQuality": "good",
"soilQuality": "good"
},
{
"section": [0,2],
"totalNrOfObjects": 2,
"airQuality": "moderate",
"soilQuality": "good"
},
{
"section": [1,0],
"totalNrOfObjects": 0,
"airQuality": "poor",
"soilQuality": "poor"
},
{
"section": [1,1],
"totalNrOfObjects": 3,
"airQuality": "good",
"soilQuality": "good"
},
{
"section": [1,2],
"totalNrOfObjects": 1,
"airQuality": "moderate",
"soilQuality": "poor"
},
{
"section": [2,0],
"totalNrOfObjects": 2,
"airQuality": "good",
"soilQuality": "moderate"
},
{
"section": [2,1],
"totalNrOfObjects": 3,
"airQuality": "moderate",
"soilQuality": "good"
},
{
"section": [2,2],
"totalNrOfObjects": 0,
"airQuality": "poor",
"soilQuality": "poor"
}
],
"timestamp": 23
}
printKnowledgeBase
Mesaje posibile pentru această comandă:
"ERROR: Simulation not started. Cannot perform action"
Click pentru input printKnowledgeBase
Click pentru input printKnowledgeBase
{
"command": "printKnowledgeBase",
"timestamp": 17
}
Output
Click pentru output printKnowledgeBase
Click pentru output printKnowledgeBase
{
"command": "printKnowledgeBase",
"output" : [
{
"topic": "RedAlgae",
"facts": [ "Method to plant RedAlgae", "Characteristic of RedAlgae"
]
}
],
"timestamp": 17
}
Exemplu simulare
Pentru a ilustra mai bine ordinea și efectul operațiilor din secțiunile anterioare, vă atașăm un exemplu minimal al unei simulări.
Click pentru input simulare
Click pentru input simulare
{
"simulationParams": [
{
"territoryDim": "3x3",
"energyPoints": 22,
"territorySectionParams": {
"soil": [
{
"type": "ForestSoil",
"name": "LightForestSoil",
"mass": 1000.0,
"nitrogen": 2.5,
"waterRetention": 0.5,
"soilpH": 6.7,
"organicMatter": 0.3,
"leafLitter": 0.2,
"sections": [
{
"x": 0,
"y": 0
},
{
"x": 0,
"y": 1
},
{
"x": 0,
"y": 2
}
]
},
{
"type": "SwampSoil",
"name": "WetPeat",
"mass": 1100.0,
"nitrogen": 2.0,
"waterRetention": 0.7,
"soilpH": 6.3,
"organicMatter": 0.5,
"waterLogging": 0.6,
"sections": [
{
"x": 1,
"y": 0
},
{
"x": 1,
"y": 1
},
{
"x": 1,
"y": 2
}
]
},
{
"type": "DesertSoil",
"name": "DrySand",
"mass": 800.0,
"nitrogen": 0.8,
"waterRetention": 0.15,
"soilpH": 7.2,
"organicMatter": 0.1,
"salinity": 0.05,
"sections": [
{
"x": 2,
"y": 0
},
{
"x": 2,
"y": 1
},
{
"x": 2,
"y": 2
}
]
}
],
"plants": [
{
"type": "FloweringPlants",
"name": "Tulip",
"mass": 0.5,
"sections": [
{
"x": 0,
"y": 0
},
{
"x": 1,
"y": 1
},
{
"x": 2,
"y": 2
},
{
"x": 0,
"y": 1
}
]
}
],
"animals": [
{
"type": "Herbivores",
"name": "Rabbit",
"mass": 2,
"sections": [
{
"x": 1,
"y": 0
},
{
"x": 2,
"y": 1
},
{
"x": 0,
"y": 1
}
]
}
],
"water": [
{
"type": "pond",
"name": "SmallPond",
"mass": 30.0,
"purity": 85.0,
"salinity": 0.1,
"turbidity": 2,
"contaminantIndex": 0.5,
"pH": 6.6,
"isFrozen": false,
"sections": [
{
"x": 0,
"y": 2
},
{
"x": 1,
"y": 2
},
{
"x": 0,
"y": 1
},
{
"x": 1,
"y": 0
}
]
}
],
"air": [
{
"type": "TemperateAir",
"name": "Spring Air",
"mass": 900000.0,
"humidity": 60.0,
"temperature": 15.0,
"oxygenLevel": 20,
"pollenLevel": 10.0,
"sections": [
{
"x": 0,
"y": 0
},
{
"x": 1,
"y": 1
},
{
"x": 2,
"y": 2
},
{
"x": 0,
"y": 1
},
{
"x": 1,
"y": 0
},
{
"x": 2,
"y": 1
},
{
"x": 0,
"y": 2
},
{
"x": 1,
"y": 2
},
{
"x": 2,
"y": 0
}
]
}
]
}
}
],
"commands": [
{
"command": "startSimulation",
"timestamp": 1
},
{
"command": "moveRobot",
"timestamp": 2
},
{
"command": "scanObject",
"color": "pink",
"smell": "sweet",
"sound": "none",
"timestamp": 3
},
{
"command": "printEnvConditions",
"timestamp": 4
},
{
"command": "learnFact",
"subject": "Method to plant Tulip",
"components": "Tulip",
"timestamp": 5
},
{
"command": "improveEnvironment",
"improvementType": "plantVegetation",
"type": "FloweringPlants",
"name": "Tulip",
"timestamp": 6
},
{
"command": "printEnvConditions",
"timestamp": 7
},
{
"command": "getEnergyStatus",
"timestamp": 8
},
{
"command": "printMap",
"timestamp": 9
},
{
"command": "endSimulation",
"timestamp": 10
},
{
"command": "moveRobot",
"timestamp": 11
}
]
}
Schimbarea datelor pentru hartă constă în actualizarea parametrilor pentru mediu - air, soil, water (în această ordine) - și apoi plantele și animalele (în această ordine)
Recomandăm rotunjirea fiecărui rezultat final de tip
double înainte de a actuliza câmpurile unui obiect cu acesta. Puteți folosi formula de mai jos:
Math.round(result * 100.0) / 100.0
Desfășurarea simulării
startSimulation
Se încarcă datele pentru simularea curentă
Se începe simularea de pe poziția (0, 0).
Încă nu s-au scanat obiecte, deci nu se vor face schimbări automate pentru mediu sau entități.
moveRobot
Se fac actualizările automate pentru interacțiuni, plante și animale
Se fac actualizările automate pentru mediu - sol și aer
Se calculează doar calitatea aerului și a solului, întrucât robotul încă nu a scanat o entitate
Avem TemperateAir → se aplică formula specifică acestui tip de aer
Avem ForestSoil → se aplică formula specifică acestui tip de sol
Se identifică pătrățelele vecine: (0, 1) și (1, 0)
Se parcurg pătrățelele vecine în ordinea sus, dreapta, jos, stânga ⇒ se va parcurge (0, 1) și apoi (1, 0)
Celula (0, 1) are: animal, ForestSoil, apă, TemperateAir, plantă
Celula (1, 0) are: animal, SwampSoil, apă, TemperateAir
Se calculează fiecare posibilitate de daune pentru robot:
| Category | Celula (1, 0) | Celula (0, 1) |
| PossibilityToGetStuckInSoil | 6.0 | 0.475 |
| PossibilityToGetDamagedByAir | 3.57 | 3.57 |
| PossibilityToBeAttackedByAnimal | 1.5 | 1.5 |
| PossibilityToGetStuckInPlants | 0 | 0.9 |
Scorul final pentru pătrățica (1, 0): Math.round(3.69) = 4
Scorul final pentru pătrățica (0, 1): Math.round(1.61125) = 2
Scorul pentru pătrățica (0, 1) este mai bun ⇒ robotul se mută pe pătrățica (0, 1)
Se verifică dacă robotul mai are suficientă baterie pentru a se muta
nu s-au efectuat alte comenzi care să consume baterie, așadar robotul are 22 puncte energie
încă are suficientă baterie, deci se va afișa mesaj de succes
Se actulizează cantitatea de baterie necesară pentru mutare: 22 - 2 = 20
scanObject
Se fac actualizările automate pentru interacțiuni, plante și animale
Se fac actualizările automate pentru mediu - sol și aer
Se verifică dacă robotul are minim 7 puncte de energie rămase pentru a efectua comanda
Se actulizează cantitatea de baterie: 20 - 7 = 13
Robotul scanează un obiect
Pe baza celor 3 parametrii scanați se determină că obiectul scanat este o plantă (pink + sweet + none)
Se caută în baza de date a simulării dacă există planta pe celula curentă (0, 1)
Se salvează planta Tulip în inventar
printEnvConditions
Se fac actualizările automate pentru interacțiuni, plante și animale
interacțiuni
Soil → Plant
Plant → Air
aerul este de tip TemperateAir și are oxygenLevel = 20 (este valoarea de la citire nemodificată)
planta are statusul “young” → improveRate = 0.2
planta este de tipul FloweringPlants → oxygenFromPlant = 6.0
se va actualiza nivelul de oxigen: oxygenLevel = 20 + 6.0 + 0.2 = 26.2
Se fac actualizările automate pentru mediu - sol și aer
noile valori pentru mediu: airQuality = 93.4 și soilQuality = 4.41
întrucât doar aerul a suferit modificări, doar calitatea acestuia se va actuliza, iar pentru sol va rămâne la fel
Se printează toate detaliile despre pătrățica curentă
learnFact
Se fac actualizările automate pentru interacțiuni, plante și animale
interacțiuni
Soil → Plant
Plant → Air
oxygenLevel = 26.2
planta are statusul “young” → improveRate = 0.2
planta este de tipul FloweringPlants → oxygenFromPlant = 6.0
se va actualiza nivelul de oxigen: oxygenLevel = 26.2 + 6.0 + 0.2 = 32.4
Se fac actualizările automate pentru mediu - sol si aer
Se verifică dacă robotul are minim 2 puncte de energie rămase pentru a efectua comanda
Se actulizează cantitatea de baterie: 13 - 2 = 11
Se verifică dacă obiectul pentru care s-a dat fact-ul există în inventarul robotului (ce este în câmpul de “components”)
Fact-ul se va salva în baza de date a robotului sub obiectul Tulip
improveEnvConditions
Se fac actualizările automate pentru interacțiuni, plante și animale
interacțiuni
Soil → Plant
Plant → Air
oxygenLevel = 32.4
planta are statusul “young” → improveRate = 0.2
planta este de tipul FloweringPlants → oxygenFromPlant = 6.0
se va actualiza nivelul de oxigen: oxygenLevel = 32.4 + 6.0 + 0.2 = 38.6
Se fac actualizările automate pentru mediu - sol si aer
Se verifică dacă robotul are minim 10 puncte de energie rămase pentru a efectua comanda
* Se actulizează cantitatea de baterie: 11 - 10 = 1
Se verifică cele 2 conditii pentru comandă:
Cum cele 2 condiții sunt îndeplinite, se va aplica improvement-ul pe pătrățică
aerul este de tip TemperateAir și are oxygenLevel = 38.6
tipul de improvement este “plantVegetation” → trebuie actulatizat oxygenLevel cu + 0.3
oxygenLevel = 38.6 + 0.3 = 38.9
se va printa mesajul de succes pentru comandă
printEnvConditions
Se fac actualizările automate pentru interacțiuni, plante și animale
interacțiuni
Soil → Plant
Plant → Air
oxygenLevel = 38.6
planta are statusul “young” → improveRate = 0.2
planta este de tipul FloweringPlants → oxygenFromPlant = 6.0
se va actualiza nivelul de oxigen: oxygenLevel = 38.6 + 6.0 + 0.2 = 45.1
Se fac actualizările automate pentru mediu - sol si aer
Se printează toate detaliile despre pătrățica curentă
getEnergyStatus
Se fac actualizările automate pentru interacțiuni, plante și animale
interacțiuni
Soil → Plant
solul ajută planta să crească cu 0.2 ⇒ growthRate = 0.8 + 0.2 = 1.0
s-a ajuns la growthRate = 1.0, deci trebuie schimbat statusul pentru plantă → din “young” va deveni “mature”
se va reseta growthRate la 0
Plant → Air
oxygenLevel = 45.1
planta are statusul “mature” → improveRate = 0.7
planta este de tipul FloweringPlants → oxygenFromPlant = 6.0
se va actualiza nivelul de oxigen: oxygenLevel = 45.1 + 6.0 + 0.7 = 51.8
Se fac actualizările automate pentru mediu - sol și aer
Se printează bateria rămasă a robotului la momentul curent
printMap
Se fac actualizările automate pentru interacțiuni, plante și animale
interacțiuni
Soil → Plant
Plant → Air
oxygenLevel = 51.8
planta are statusul “mature” → improveRate = 0.7
planta este de tipul FloweringPlants → oxygenFromPlant = 6.0
se va actualiza nivelul de oxigen: oxygenLevel = 51.8 + 6.0 + 0.7 = 58.5
Se fac actualizările automate pentru mediu - sol și aer
Se printează pentru fiecare pătrățică numărul de entități optionale - plantă, animal, apă - și calitatea solului și a aerului până la momentul curent
endSimulation
moveRobot
Output
Click pentru output simulare
Click pentru output simulare
[
{
"command": "startSimulation",
"message": "Simulation has started.",
"timestamp": 1
},
{
"command": "moveRobot",
"message": "The robot has successfully moved to position (0, 1).",
"timestamp": 2
},
{
"command": "scanObject",
"message": "The scanned object is a plant.",
"timestamp": 3
},
{
"command": "printEnvConditions",
"output": {
"soil": {
"type": "ForestSoil",
"name": "LightForestSoil",
"mass": 1000.0,
"nitrogen": 2.5,
"waterRetention": 0.5,
"soilpH": 6.7,
"organicMatter": 0.3,
"soilQuality": 4.41,
"leafLitter": 0.2
},
"plants": {
"type": "FloweringPlants",
"name": "Tulip",
"mass": 0.5
},
"animals": {
"type": "Herbivores",
"name": "Rabbit",
"mass": 2.0
},
"water": {
"type": "pond",
"name": "SmallPond",
"mass": 30.0,
"purity": 85.0,
"salinity": 0.1,
"turbidity": 2.0,
"contaminantIndex": 0.5,
"temperature": 15.0,
"pH": 6.6,
"isFrozen": false
},
"air": {
"type": "TemperateAir",
"name": "Spring Air",
"mass": 900000.0,
"humidity": 60.0,
"temperature": 15.0,
"oxygenLevel": 26.2,
"airQuality": 93.4,
"pollenLevel": 10.0
}
},
"timestamp": 4
},
{
"command": "learnFact",
"message": "The fact has been successfully saved in the database.",
"timestamp": 5
},
{
"command": "improveEnvironment",
"message": "The Tulip was planted successfully.",
"timestamp": 6
},
{
"command": "printEnvConditions",
"output": {
"soil": {
"type": "ForestSoil",
"name": "LightForestSoil",
"mass": 1000.0,
"nitrogen": 2.5,
"waterRetention": 0.5,
"soilpH": 6.7,
"organicMatter": 0.3,
"soilQuality": 4.41,
"leafLitter": 0.2
},
"plants": {
"type": "FloweringPlants",
"name": "Tulip",
"mass": 0.5
},
"animals": {
"type": "Herbivores",
"name": "Rabbit",
"mass": 2.0
},
"water": {
"type": "pond",
"name": "SmallPond",
"mass": 30.0,
"purity": 85.0,
"salinity": 0.1,
"turbidity": 2.0,
"contaminantIndex": 0.5,
"temperature": 15.0,
"pH": 6.6,
"isFrozen": false
},
"air": {
"type": "TemperateAir",
"name": "Spring Air",
"mass": 900000.0,
"humidity": 60.0,
"temperature": 15.0,
"oxygenLevel": 45.1,
"airQuality": 100.0,
"pollenLevel": 10.0
}
},
"timestamp": 7
},
{
"command": "getEnergyStatus",
"message": "TerraBot has 1 energy points left.",
"timestamp": 8
},
{
"command": "printMap",
"output": [
{
"section": [
0,
0
],
"totalNrOfObjects": 1,
"airQuality": "good",
"soilQuality": "poor"
},
{
"section": [
1,
0
],
"totalNrOfObjects": 2,
"airQuality": "good",
"soilQuality": "poor"
},
{
"section": [
2,
0
],
"totalNrOfObjects": 0,
"airQuality": "good",
"soilQuality": "poor"
},
{
"section": [
0,
1
],
"totalNrOfObjects": 3,
"airQuality": "good",
"soilQuality": "poor"
},
{
"section": [
1,
1
],
"totalNrOfObjects": 1,
"airQuality": "good",
"soilQuality": "poor"
},
{
"section": [
2,
1
],
"totalNrOfObjects": 1,
"airQuality": "good",
"soilQuality": "poor"
},
{
"section": [
0,
2
],
"totalNrOfObjects": 1,
"airQuality": "good",
"soilQuality": "poor"
},
{
"section": [
1,
2
],
"totalNrOfObjects": 1,
"airQuality": "good",
"soilQuality": "poor"
},
{
"section": [
2,
2
],
"totalNrOfObjects": 1,
"airQuality": "good",
"soilQuality": "poor"
}
],
"timestamp": 9
},
{
"command": "endSimulation",
"message": "Simulation has ended.",
"timestamp": 10
},
{
"command": "moveRobot",
"message": "ERROR: Simulation not started. Cannot perform action",
"timestamp": 11
}
]
Scheletul de cod
În rezolvarea temei va fi nevoie de folosirea unor obiecte pentru stocarea și maparea datelor primite în format JSON. Scheletul temei vă oferă mai multe clase utile pentru citirea și rularea temei. Acestea se regăsesc în cadrul scheletului, astfel:
Clasele de input din cadrul pachetului fileio: Acestea se vor folosi pentru parsarea datelor de input. Astfel, preluați toate informațiile necesare pentru a crea propriile clase pentru rezolvarea temei.
Clasa Main care este punctul de intrare pentru logica de rezolvare a temei.
Pentru a întelege mai bine cum funcționează citirea/scrierea în fișierele JSON vă recomandăm să citiți Json & Jackson sau Jackson Object Mapper tutorial (Baeldung).
Implementarea voastră va începe din metoda Main.action, unde veți adăuga în ArrayNode output pe parcursul execuției toate output-urile comezilor date. De asemenea, aveți un mic exemplu în schelet despre cum puteți face asta.
Aveți în fișierul pom.xml toate dependințele necesare pentru rularea temei, mai exact bibliotecile Jackson și câteva dependințe folosite pentru testare.
Output-ul
nu trebuie formatat ca în ref-uri, fiindcă se verifică conținutul obiectelor și array-urilor JSON, nu textul efectiv.
Totuși vă recomandăm să utilizați PrettyPrinter dacă folosiți Jackson pentru că vă ajută la depanare ( Documentație PrettyPrinter).
Totodată, pentru a înțelege cum se poate realiza scrierea în fișierele JSON de output, vă sugerăm să consultați JSON Array.
Dacă aveți probleme cu proiectul vostru
vă recomandăm următoarele soluții:
Să închideți proiectul din IntelliJ, să ștergeți din file explorer folderele .idea și target și să deschideți din nou folderul proiectului cu IntelliJ (File → open → selectați folderul în care se află pom.xml). Acest pas vă regenerează configurația IntelliJ-ului.
Să apăsați pe iconița “M” din dreapta în IntelliJ, după care să apăsați pe item-ul din listă, apoi pe lifecycle și apoi dublu click pe install. Acest pas vă reinstalează dependințele proiectului.
Să apăsați pe File → Invalidate cache și să bifați toate opțiunile. Proiectul o să se reîncarce ștergând toate configurațiile și fișierele cached.
Execuția temei
Pentru a rula checker-ul intrați în fișierul “src/test/java/TestRunner” și rulați clasa.
O să vi se deschidă un panou în IntelliJ de unde puteți vedea statusul tuturor testelor. De asemenea, vi se va afișa și eroarea sau diferența rezultatului pe care îl aveți pentru fiecare test în parte.
Pentru ca checker-ul să funcționeze trebuie să deschideți tema din Intellij la calea unde se află fișierul “pom.xml”.
Recomandări
Tema a fost concepută pentru a vă testa cunoștințele dobândite în urma parcurgerii laboratoarelor 1-6, aceasta putând fi rezolvată doar cu noțiunile invățate din acele laboratoare.
Tema fiind o specificație destul de stufoasă recomandăm citirea de cel putin două ori a enunțului inainte de inceperea implementării.
Verificați periodic această pagină, deoarece scheletul/cerința pot suferi modificări în urma unor erori din partea noastră.
Utilizarea LLM-urilor (ChatGPT, Gemini, Claude etc.)
Puteți folosi modele de limbaj (LLM-uri) pentru asistență în realizarea temei doar ca instrument suplimentar, de exemplu pentru clarificări, explicații sau verificarea ideilor.
Totuși, recomandarea noastră este să încercați să rezolvați tema pe cont propriu, fără a depinde de astfel de instrumente. Scopul exercițiului este să învățați și să vă dezvoltați abilitățile, iar progresul real vine doar prin înțelegere și practică personală.
Puteți folosi LLM-uri pentru:
NU este acceptat să:
trimiteți soluții generate integral de un LLM.
folosiți cod sau text pe care nu îl înțelegeți.
copiați fără să puteți explica ce ați făcut în cod.
generați README-ul folosind un LLM.
Evaluare
Punctajul constă din:
80p implementare - trecerea testelor
10p coding style (vezi checkstyle)
5p README.md clar, concis, explicații axate pe design (flow, interacțiuni)
5p folosire git pentru versionarea temei
Depunctările pentru temă sunt acoperite în barem, totuși pot apărea depunctări care nu se află în imaginile furnizate.
Bonusuri:
La evaluare, putem oferi bonusuri pentru design foarte bun, cod bine documentat dar și pentru diverse elemente suplimentare.
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.
Puteți folosi LLM-uri (ChatGPT, Gemini etc.) doar pentru clarificări sau fragmente mici de cod, însă menționați în README unde și cum au fost folosite pentru a evita orice scenariu de copiat.
Git
Folosirea git pentru versionare va fi verificata din folderul .git pe care trebuie să îl includeți în arhiva temei. Punctajul se va acorda dacă ați făcut minim 3 commit-uri relevante și cu mesaj sugestiv. NU este permis să aveți repository-urile de git publice până la deadline-ul hard.
Pentru a primi punctajul pentru Git, după ce ați terminat tema și ați făcut toate commit-urile, executați comanda git log > git_log.txt in rădăcina proiectului și adăugați fisierul in arhiva trimisă.
Pentru folosirea tool-ului
Git vă punem la dispoziție un
tutorial actualizat și amplu și aveți de asemenea și un
tutorial despre comenzile pe care puteți să le dați din IntelliJ la acest.
După ce clonați repo-ul de pe GitHub, vă rugăm să vă faceți un repository propriu privat cu conținutul temei sau să faceți un fork privat. Dacă nu folosiți un repository sau fork propriu nu o să puteți să urcați schimbările din Git în GitHub, deoarece vă aflați în rădăcina repository-ului echipei de POO și aveți riscul să vă expuneți soluția.
Vă rugăm să vă generați un .gitignore cu template-ul Maven dacă nu folosiți gitignore-ul inclus în temă. Acesta vă ajută să definiți fișiere care să nu fie luate în considerare la diff check când rulați git status/git commit sau alte comenzi de git.
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 (care se află în pom.xml ca dependență).
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 = 100 și nr_erori = 200 ⇒ nota_finala = 90
punctaj_total = 100 și nr_erori = 29 ⇒ nota_finala = 100
punctaj_total = 80 și nr_erori = 30 ⇒ nota_finala = 80
punctaj_total = 80 și nr_erori = 31 ⇒ nota_finala = 70
Teste
test01_initialize_entities.json
test02_initialize_entities_errors.json
test03_move_robot.json
test04_move_robot_errors.json
test05_env_condition.json
test06_update_battery.json
test07_update_battery_errors.json
test08_change_weather.json
test09_scan_plant.json
test10_scan_water.json
test11_scan_animal.json
test12_scan_object_errors.json
test13_learn_fact.json
test14_improve_environment.json
test15_improve_environment_errors.json
test16_medium.json
test17_multiple_simulations.json
test18_multiple_simulations_errors.json
test19_complex.json
test20_complex_errors.json
test21_complex_combined.json
Unele teste nu sunt încă disponibile în checker. Acestea vor fi publicate în zilele următoare.
Upload temă
Arhiva o veţi urca pe Code Devmind, unde sunt si informații despre structura ei.
Checker-ul din cloud nu a fost publicat încă! Vă vom comunica pe Teams când acesta devine disponibil.
FAQ
Q: Pot folosi biblioteca “X”?
A: Dacă doriți să folosiți o anumită bibliotecă vă recomandăm să întrebați pe forum, ca apoi să o validăm și să o includem și în pom-ul de pe Code Devmind.
Q: Pot folosi GSON în loc de Jackson?
A: Sigur, contează doar să aveți output-ul corect și să respectați convențiile de coding style și modularitate.
Q: Am descoperit edge case-ul “Y”, trebuie să îl tratez?
A: Nu. Toate datele necesare pentru soluționarea temei vă sunt date in cerință. Dacă totuși am omis ceva ne puteți contacta pe forum.
Q: Pot folosi clase de tip “Enum” pentru constante?
A: Da.
Q: Ce JDK recomandați?
A: 25
Q: Pot să fac în orice ordine testele?
A: Depinde. Testele au fost concepute sa fie cât mai decuplate și să testeze câte o funcționalitate în întregime. Cu toate astea, vă recomandăm să implementați mai întâi testele 01, 02, 03 deoarece reprezintă funcționalitățile de bază pentru rezolvarea următoarelor teste mai complexe.
Resurse și linkuri utile