This shows you the differences between two versions of the page.
|
poo-is-ab:tema:2025:03_test [2025/11/26 15:32] marius.trifu created |
poo-is-ab:tema:2025:03_test [2025/11/26 18:35] (current) marius.trifu |
||
|---|---|---|---|
| Line 31: | Line 31: | ||
| ===== 1. Descriere ===== | ===== 1. Descriere ===== | ||
| - | Administrezi o echipă de boți tactici într-o arenă rectangulară. Simularea rulează pe **runde (ticks)**, iar intrarea este o **succesiune de comenzi** trimise de arbitru (`REF`). După fiecare comandă procesată trebuie să **emiți propria ta decizie** (`PLAYER ...`) și să actualizezi scorul. | + | Jocul este un **battle royale simplu pe hartă 2D**. Ești un jucător într-o arenă rectangulară și te poți deplasa sau planta bombe. Simularea rulează pe **runde (ticks)**, iar intrarea este o **succesiune de comenzi** trimise de arbitru (`REF`). După fiecare comandă procesată trebuie să **emiți propria ta decizie** (`PLAYER ...`). |
| - | **🎯 Obiectiv:** Maximizează **TOTAL_SCORE** = energie colectată + damage util + stil - penalizări. | + | **🎯 Obiectiv:** Maximizează **TOTAL_SCORE** = damage dat adversarilor + supraviețuire - penalizări. |
| + | |||
| + | ==== Mecanica Jocului ==== | ||
| + | |||
| + | **Ticks și Acțiuni:** | ||
| + | * Un **tick** = o rundă în care fiecare jucător face **exact o acțiune** | ||
| + | * Acțiuni posibile: `MOVE` (deplasare o casetă), `PLANT_BOMB` (plantează bombă), `PLANT_WALL` (plantează perete), `WAIT` (stai pe loc) | ||
| + | * După fiecare `REF ...` primești, trebuie să răspunzi cu exact o acțiune `PLAYER ...` | ||
| + | |||
| + | **Hartă:** | ||
| + | * Arenă rectangulară de dimensiuni `LATIME × INALTIME` (coordonate 0-index) | ||
| + | * Fiecare celulă poate conține: un jucător, o bombă, un perete, sau nimic | ||
| + | |||
| + | **Mișcare:** | ||
| + | * Te poți deplasa cu **o casetă** pe rând în direcții: `N` (sus), `S` (jos), `E` (dreapta), `W` (stânga) | ||
| + | * **NU** poți merge pe diagonală | ||
| + | * Nu poți merge într-o celulă ocupată de alt jucător, bombă sau perete | ||
| + | |||
| + | **Bombe:** | ||
| + | * Poți planta o bombă în celula curentă cu acțiunea `PLANT_BOMB` | ||
| + | * Bomba explodează după `BOMB_TIMER` ticks de la plantare (ex: `BOMB_TIMER = 3` → explodează după 3 ticks) | ||
| + | * La explozie, toate celulele din **raza de explozie** (`BOMB_RADIUS = 2`) primesc damage | ||
| + | * **Raza de explozie = 2 casete:** Bomba afectează celulele la distanță 1 și 2 în toate direcțiile (N, S, E, W) | ||
| + | * Exemplu: Bomba la (5,5) afectează: (5,4), (5,3), (5,6), (5,7), (4,5), (3,5), (6,5), (7,5) - total 8 celule | ||
| + | * Damage-ul este `BOMB_DAMAGE` pentru fiecare celulă afectată | ||
| + | * Un jucător poate avea **maximum `MAX_BOMBS` bombe active simultan** | ||
| + | |||
| + | **Pereți:** | ||
| + | * Poți planta un perete în celula curentă cu acțiunea `PLANT_WALL` | ||
| + | * Peretele **blochează mișcările** (nu poți merge prin el) | ||
| + | * Peretele **blochează explozii** (dacă e între tine și bomba, primești mai puțin damage sau deloc, în funcție de poziție) | ||
| + | * Peretele are **rezistență:** Trebuie să fie lovit de **2 bombe** pentru a fi distrus | ||
| + | * Prima bombă care lovește peretele îl slăbește (primește damage) | ||
| + | * A doua bombă care lovește peretele îl distruge complet | ||
| + | * Un jucător poate avea **maximum `MAX_WALLS` pereți activi simultan** | ||
| + | * Peretele este **permanent** până când este distrus de 2 explozii | ||
| + | |||
| + | **Vizibilitate:** | ||
| + | * **Adversarul vede toate bombele** plantate (pentru strategie) | ||
| + | * Vezi pozițiile adversarilor când se deplasează (comenzi `REF MOVE`) | ||
| + | |||
| + | **Scor:** | ||
| + | * Primești puncte pentru damage dat adversarilor | ||
| + | * Primești bonus pentru supraviețuire (dacă rămâi în viață) | ||
| + | * Penalizări pentru comenzi invalide sau ieșire din arenă | ||
| ==== Fluxul unei simulari ==== | ==== Fluxul unei simulari ==== | ||
| - | 1. Citești configurarea arenei și profilurile boților. | + | 1. Citești configurarea arenei (dimensiuni, parametri bombe, număr runde). |
| - | 2. Primești comenzi `REF ...` una câte una (spawn, evenimente, atacuri rivale etc.). | + | 2. Primești comenzi de la arbitru una câte una (spawn adversar, mișcări, explozii etc.). |
| - | 3. După fiecare linie citită **trebuie** să răspunzi cu exact 1 linie `PLAYER ...` care descrie acțiunea echipei tale pentru acel tick. | + | 3. După fiecare linie citită **trebuie** să răspunzi cu exact 1 linie care descrie acțiunea ta pentru acel tick. |
| - | 4. La final raportezi tabela scorurilor și cine câștigă arena. | + | 4. La final raportezi tabela scorurilor și cine câștigă. |
| ===== 2. Formate Fișiere ===== | ===== 2. Formate Fișiere ===== | ||
| Line 49: | Line 93: | ||
| ^ arena.txt ^ | ^ arena.txt ^ | ||
| | <code> | | <code> | ||
| - | ARENA LATIME INALTIME ROUNDS MAX_ENERGY | + | ARENA LATIME INALTIME ROUNDS |
| - | RESUPPLY ENERGY_REGEN SHIELD_REGEN | + | BOMB_TIMER BOMB_RADIUS BOMB_DAMAGE MAX_BOMBS MAX_WALLS |
| - | BOTS N | + | PLAYER_HP INITIAL_X INITIAL_Y |
| - | nume_bot hp attack shield speed ability_cost ability_cd | + | |
| - | ... | + | |
| - | UPGRADES U | + | |
| - | upgrade_name energy_cost attack_bonus shield_bonus speed_bonus | + | |
| - | ... | + | |
| STREAM | STREAM | ||
| - | REF TICK <t> | + | TICK <t> |
| - | REF SPAWN <team> <bot_name> <id> <x> <y> | + | SPAWN <team> <x> <y> |
| - | REF MOVE <team> <id> <direction> <steps> | + | MOVE <team> <x> <y> |
| - | REF ATTACK <team> <id> <target_id> <dmg> | + | BOMB <team> <x> <y> <timer> |
| - | REF EVENT <type> <value> | + | EXPLODE <x> <y> |
| + | WALL <team> <x> <y> | ||
| + | WALL_HIT <x> <y> | ||
| + | WALL_BROKEN <x> <y> | ||
| + | HIT <x> <y> <dmg> | ||
| ... | ... | ||
| END | END | ||
| Line 68: | Line 111: | ||
| **Explicații:** | **Explicații:** | ||
| - | * `ARENA` – dimensiunile grilei (0-index), număr maxim de runde și energie totală. | + | * `ARENA` – dimensiunile grilei (0-index), număr maxim de runde. |
| - | * `RESUPPLY` – valori globale pentru refill-uri automate. | + | * `BOMB_TIMER` – numărul de ticks până bomba explodează (ex: 3 = explodează după 3 ticks de la plantare). |
| - | * `BOTS` – descrie șabloanele disponibile (max 12). `ability_cd` = număr de ticks până poate fi refolosită abilitatea. | + | * `BOMB_RADIUS` – raza de explozie (fixată la **2 casete** în toate direcțiile N, S, E, W). |
| - | * `UPGRADES` – boost-uri pe care le poți cumpăra când ai energie suficientă. | + | * `BOMB_DAMAGE` – damage-ul aplicat fiecărei celule afectate. |
| + | * `MAX_BOMBS` – numărul maxim de bombe active simultan pe jucător. | ||
| + | * `MAX_WALLS` – numărul maxim de pereți activi simultan pe jucător. | ||
| + | * `PLAYER_HP` – punctele de viață inițiale ale jucătorului. | ||
| + | * `INITIAL_X INITIAL_Y` – poziția inițială a jucătorului tău (echipa Alpha). | ||
| * `STREAM` – începe secvența de comenzi live. Liniile vin **în timp real / sequential**; nu există număr declarat, trebuie să citești până la `END`. | * `STREAM` – începe secvența de comenzi live. Liniile vin **în timp real / sequential**; nu există număr declarat, trebuie să citești până la `END`. | ||
| + | | ||
| + | **Notă:** `BOMB_RADIUS` este întotdeauna 2 în această temă (bomba afectează celulele la distanță 1 și 2 în direcțiile N, S, E, W). | ||
| - | **Direcții disponibile:** `N`, `S`, `E`, `W`, `NE`, `NW`, `SE`, `SW`. Coordonatele ies din arenă → comandă invalidă (penalizare). | + | **Direcții disponibile:** `N` (sus), `S` (jos), `E` (dreapta), `W` (stânga). **NU** sunt permise diagonalele. |
| - | ==== 2.2 Format comenzi REF ==== | + | **Exemplu:** |
| + | | <code> | ||
| + | ARENA 10 8 50 | ||
| + | 3 1 20 3 | ||
| + | 100 0 0 | ||
| + | STREAM | ||
| + | REF TICK 1 | ||
| + | REF SPAWN Beta 9 7 | ||
| + | REF MOVE Beta 9 6 | ||
| + | REF TICK 2 | ||
| + | REF MOVE Beta 9 5 | ||
| + | ... | ||
| + | END | ||
| + | </code> | | ||
| + | |||
| + | ==== 2.2 Format comenzi de intrare ==== | ||
| - | | Sintaxă | Semnificație | | + | | Comandă | Semnificație | |
| - | | REF TICK t | Semnalează începerea tick-ului `t`. | | + | | TICK t | Semnalează începerea tick-ului `t`. | |
| - | | REF SPAWN team bot id x y | Arbitru introduce un bot pentru `team` (Alpha/Beta). | | + | | SPAWN team x y | Arbitru introduce un jucător pentru `team` (Alpha/Beta) la coordonatele (x, y). | |
| - | | REF MOVE team id dir steps | Botul rival se deplasează. | | + | | MOVE team x y | Jucătorul rival (`team`) s-a deplasat la coordonatele (x, y). | |
| - | | REF ATTACK team id target dmg | Primești damage de la altă echipă / event. | | + | | BOMB team x y timer | Jucătorul `team` a plantat o bombă la (x, y) care explodează în `timer` ticks. | |
| - | | REF EVENT type value | Eveniment global (`EMP`, `STORM`, `ENERGY_DROP`, `RECHARGE`). | | + | | EXPLODE x y | O bombă a explodat la coordonatele (x, y). | |
| - | | REF CAPTURE team node_id energy | Altă echipă capturează un nod de energie. | | + | | WALL team x y | Jucătorul `team` a plantat un perete la coordonatele (x, y). | |
| + | | WALL_HIT x y | Un perete la (x, y) a fost lovit de o bombă (prima lovitură, peretele rămâne activ). | | ||
| + | | WALL_BROKEN x y | Un perete a fost distrus complet (a doua bombă) la coordonatele (x, y). | | ||
| + | | HIT x y dmg | Ai primit `dmg` damage la coordonatele (x, y) (de la explozie). | | ||
| - | Restul de linii vor urma aceeași structură `REF <ACTIUNE> ...`. Poți ignora tipuri necunoscute, dar trebuie să raportezi `PLAYER WAIT reason=UNKNOWN_COMMAND`. | + | **Observații:** |
| + | * Vezi toate mișcările adversarilor (`MOVE Beta ...`). | ||
| + | * Vezi toate bombele plantate (`BOMB Beta ...`). | ||
| + | * Vezi toți pereții plantați (`WALL Beta ...`). | ||
| + | * Primești notificări când bombele explodează (`EXPLODE ...`). | ||
| + | * Primești notificări când pereții sunt loviți (`WALL_HIT ...`) sau distruși (`WALL_BROKEN ...`). | ||
| + | * Primești damage când ești în raza de explozie (`HIT ...`). | ||
| + | |||
| + | **Elemente noi (extensibilitate):** | ||
| + | * Poți primi comenzi noi pentru elemente viitoare (ex: `TRAP team x y`, `POWERUP x y type`). | ||
| + | * Pentru comenzi necunoscute, răspunde cu `WAIT`. | ||
| ==== 2.3 Output obligatoriu (arena.out) ==== | ==== 2.3 Output obligatoriu (arena.out) ==== | ||
| Line 92: | Line 169: | ||
| ^ arena.out ^ | ^ arena.out ^ | ||
| | <code> | | <code> | ||
| - | PLAYER <tick> <action> <payload> | + | MOVE E |
| - | PLAYER <tick> <action> <payload> | + | BOMB |
| + | WALL | ||
| + | WAIT | ||
| ... | ... | ||
| SCOREBOARD | SCOREBOARD | ||
| - | ENERGY_COLLECTED: value | ||
| DAMAGE_DEALT: value | DAMAGE_DEALT: value | ||
| - | STYLE_POINTS: value | + | SURVIVAL_BONUS: value |
| PENALTIES: value | PENALTIES: value | ||
| TOTAL_SCORE: value | TOTAL_SCORE: value | ||
| Line 105: | Line 183: | ||
| **Reguli:** | **Reguli:** | ||
| - | * **Exact 1 linie `PLAYER ...` după fiecare linie `REF ...` procesată.** | + | * **Exact 1 linie după fiecare comandă de intrare procesată.** |
| - | * `action` ∈ {`SPAWN`, `MOVE`, `ATTACK`, `ABILITY`, `CHARGE`, `DEFEND`, `WAIT`, `UPGRADE`}. | + | * Acțiuni disponibile: `MOVE <direction>`, `BOMB`, `WALL`, `WAIT`. |
| - | * `payload` = argumentele tale (`bot_id`, coordonate țintă, energie cheltuită etc.). | + | * **`MOVE <direction>`** – te deplasezi cu o casetă în direcția `direction` (`N`, `S`, `E`, `W`). |
| - | * Output-ul trebuie să fie **determinist** (aceeași intrare → exact același output). Astfel putem lua fișierul rezultat și îl putem folosi ca **input pentru un nou run** (ex: `cat studentA.out | ./arena_bots`). | + | * **`BOMB`** – plantezi o bombă în celula curentă (dacă ai loc în `MAX_BOMBS`). |
| + | * **`WALL`** – plantezi un perete în celula curentă (dacă ai loc în `MAX_WALLS`). | ||
| + | * **`WAIT`** – stai pe loc (folosit când nu poți face altceva sau când comanda e necunoscută). | ||
| + | * Output-ul trebuie să fie **determinist** (aceeași intrare → exact același output). Astfel putem lua fișierul rezultat și îl putem folosi ca **input pentru un nou run** (ex: `cat studentA.out | ./arena`). | ||
| * Ultima parte `SCOREBOARD ...` apare **doar după `END`**. | * Ultima parte `SCOREBOARD ...` apare **doar după `END`**. | ||
| + | | ||
| + | **Notă:** Nu mai trebuie să incluzi tick-ul în output (se știe din context). | ||
| + | |||
| + | **Exemplu output:** | ||
| + | | <code> | ||
| + | MOVE E | ||
| + | BOMB | ||
| + | MOVE N | ||
| + | WAIT | ||
| + | SCOREBOARD | ||
| + | DAMAGE_DEALT: 60 | ||
| + | SURVIVAL_BONUS: 50 | ||
| + | PENALTIES: 0 | ||
| + | TOTAL_SCORE: 110 | ||
| + | WINNER: Alpha | ||
| + | </code> | | ||
| ==== 2.4 Refolosirea output-ului ca input ==== | ==== 2.4 Refolosirea output-ului ca input ==== | ||
| Line 115: | Line 212: | ||
| Pentru dueluri: | Pentru dueluri: | ||
| * Rulezi Student A → obții `arena.out`. | * Rulezi Student A → obții `arena.out`. | ||
| - | * Prefixezi liniile cu `REF` (script disponibil în `teste/scripturi/oficializeaza_transcriere.py`). | + | * Transformi output-ul în comenzi de intrare (script disponibil în `teste/scripturi/oficializeaza_transcriere.py`). |
| - | * Rulezi Student B cu acea transcriere suplimentară: `cat arena.out.refeed | ./arena`. | + | * Rulezi Student B cu acea transcriere: `cat arena.out.refeed | ./arena`. |
| - | * Programul tău trebuie să ignore liniile `PLAYER` întâlnite în input (sunt tratate ca mișcări deja consumate) și să genereze răspunsuri noi. | + | * Programul tău trebuie să ignore liniile de acțiune întâlnite în input (sunt tratate ca mișcări deja consumate) și să genereze răspunsuri noi. |
| + | |||
| + | ==== 2.5 Elemente noi (extensibilitate) ==== | ||
| + | |||
| + | Formatul permite adăugarea de elemente noi în viitor: | ||
| + | * **Capcane:** `TRAP team x y` - capcană plantată care dă damage când e activată | ||
| + | * **Power-ups:** `POWERUP x y type` - obiecte speciale care dau bonusuri (ex: `SPEED`, `SHIELD`, `EXTRA_BOMB`) | ||
| + | * **Teleport:** `TELEPORT team x1 y1 x2 y2` - jucătorul se teleportează | ||
| + | * **Alte elemente:** Orice comandă nouă poate fi adăugată | ||
| + | |||
| + | **Regulă:** Pentru comenzi necunoscute, răspunde cu `WAIT`. Programul tău trebuie să fie robust la comenzi noi. | ||
| ===== 3. Reguli de Validare ===== | ===== 3. Reguli de Validare ===== | ||
| - | ==== 🔋 Energie ==== | + | ==== 🗺️ Mișcare ==== |
| - | * Nu poți cheltui mai multă energie decât `MAX_ENERGY`. | + | * Poți merge doar în direcții: `N` (sus), `S` (jos), `E` (dreapta), `W` (stânga). |
| - | * `CHARGE` crește energia curentă până la limită. | + | * **NU** poți merge pe diagonală. |
| - | * `UPGRADE` consumă energia specificată și aplică bonusurile asupra unui bot activ. | + | * Nu poți merge într-o celulă ocupată de alt jucător, bombă sau perete. |
| + | * Nu poți ieși din arenă: coordonatele trebuie să fie în `[0, LATIME) × [0, INALTIME)`. | ||
| + | * Dacă comanda `MOVE` este invalidă → se tratează ca `WAIT` (penalizare). | ||
| + | |||
| + | ==== 💣 Bombe ==== | ||
| + | * Poți planta o bombă doar dacă ai **mai puțin de `MAX_BOMBS` bombe active**. | ||
| + | * Nu poți planta o bombă într-o celulă care deja conține o bombă sau perete. | ||
| + | * Bomba explodează după `BOMB_TIMER` ticks de la plantare (ex: timer=3 → explodează după 3 ticks). | ||
| + | * La explozie, toate celulele din **raza de explozie = 2 casete** primesc `BOMB_DAMAGE` damage. | ||
| + | * **Raza de explozie = 2 casete în direcțiile N, S, E, W:** | ||
| + | * Bomba la (x, y) afectează: (x, y-1), (x, y-2), (x, y+1), (x, y+2), (x-1, y), (x-2, y), (x+1, y), (x+2, y) | ||
| + | * Total: **8 celule** (4 direcții × 2 casete fiecare) | ||
| + | * Un jucător poate fi afectat de mai multe bombe simultan (damage se adună). | ||
| + | * **Pereții blochează explozii:** Dacă un perete e între tine și bomba, primești mai puțin damage sau deloc (în funcție de poziție). | ||
| + | * **Pereții pot fi slăbiți/distruși:** Dacă o bombă explodează în raza sa, peretele primește damage. După **2 bombe**, peretele este distrus. | ||
| - | ==== 🗺️ Arena ==== | + | ==== 🧱 Pereți ==== |
| - | * Fiecare celulă poate conține max. 1 bot pe echipă. | + | * Poți planta un perete doar dacă ai **mai puțin de `MAX_WALLS` pereți activi**. |
| - | * Mișcările trebuie să rămână în `[0, LATIME) × [0, INALTIME)`. | + | * Nu poți planta un perete într-o celulă care deja conține o bombă, perete sau jucător. |
| - | * Nodurile de energie (id numeric) se capturează cu acțiunea `CAPTURE node_id`. | + | * Peretele **blochează mișcările** (nu poți merge prin el). |
| + | * Peretele **blochează parțial explozii** (dacă e între tine și bomba, primești mai puțin damage sau deloc). | ||
| + | * Peretele are **rezistență:** Trebuie să fie lovit de **2 bombe** pentru a fi distrus: | ||
| + | * Prima bombă care lovește peretele (în raza sa) îl slăbește (peretele primește damage, dar rămâne activ) | ||
| + | * A doua bombă care lovește peretele îl distruge complet (peretele dispare, primești `REF WALL_DESTROYED`) | ||
| + | * Peretele este **permanent** până când este distrus de 2 explozii. | ||
| + | * **Strategie:** Poți încolți adversarul cu pereți, dar el poate distruge pereții cu 2 bombe. | ||
| - | ==== ⚔️ Luptă ==== | + | ==== ❤️ Viață și Damage ==== |
| - | * Damage efectiv = `attack + bonusuri - shield_target`. | + | * Jucătorul începe cu `PLAYER_HP` puncte de viață. |
| - | * Dacă damage ≤ 0 → este considerat **blocaj** și primești `STYLE_POINTS +1` pentru combinații defensive valide. | + | * Când primești damage (`REF DAMAGE ...`), scazi din HP. |
| - | * Abilitățile respectă cooldown-ul declarat și costul de energie. | + | * Dacă HP ≤ 0 → jucătorul moare și nu mai poate face acțiuni. |
| + | * Damage-ul se aplică **imediat** când bomba explodează. | ||
| ==== ⏱️ Sincronizare ==== | ==== ⏱️ Sincronizare ==== | ||
| - | * Pentru fiecare `REF TICK t` trebuie să setezi contextul curent. | + | * Pentru fiecare `TICK t` trebuie să setezi contextul curent. |
| - | * Comenzile `REF` cu alt tick decât cel curent sunt erori -> tratează-le ca `WAIT`. | + | * Comenzile cu alt tick decât cel curent sunt erori -> tratează-le ca `WAIT`. |
| - | * Două comenzi `REF` pot apărea cu același tick; le procesezi în ordine. | + | * Două comenzi pot apărea cu același tick; le procesezi în ordine. |
| ==== 🪙 Scoring logic ==== | ==== 🪙 Scoring logic ==== | ||
| - | * `ENERGY_COLLECTED` – sumă totală de energie netă acumulată. | + | * `DAMAGE_DEALT` – damage total aplicat adversarilor (când bombele tale explodează și îi lovesc). |
| - | * `DAMAGE_DEALT` – damage valid aplicat adversarilor (`ATTACK`, `ABILITY`). | + | * `SURVIVAL_BONUS` – bonus pentru supraviețuire (dacă rămâi în viață la final). |
| - | * `STYLE_POINTS` – bonusuri pentru combo-uri (abilitate după MOVE, contra atac etc.) conform fișierului de limite. | + | * `PENALTIES` – se adună pentru: |
| - | * `PENALTIES` – se adună pentru comenzi invalide, ieșire din arenă, lipsă răspuns. | + | * Comenzi invalide (MOVE în celulă ocupată, PLANT_BOMB când ai MAX_BOMBS, etc.) |
| + | * Ieșire din arenă | ||
| + | * Lipsă răspuns (nu ai emis `PLAYER ...` după un `REF ...`) | ||
| ===== 4. Implementare ===== | ===== 4. Implementare ===== | ||
| * `main.cpp` doar creează obiectul principal (`ArenaController controller; controller.run(argc, argv);`). | * `main.cpp` doar creează obiectul principal (`ArenaController controller; controller.run(argc, argv);`). | ||
| - | * Folosește clase pentru: `Arena`, `Bot`, `Command`, `Scoreboard`. | + | * Folosește clase pentru: `Arena` (hartă), `Player` (poziție, HP, bombe active, pereți activi), `Bomb` (poziție, timer), `Wall` (poziție), `Scoreboard`. |
| * Tratează intrarea ca flux: citești linie → parsezi → execuți → produci output imediat. | * Tratează intrarea ca flux: citești linie → parsezi → execuți → produci output imediat. | ||
| - | * Este permisă bufferizarea, dar output-ul trebuie să păstreze ordinea exactă a liniilor `REF`. | + | * Este permisă bufferizarea, dar output-ul trebuie să păstreze ordinea exactă a comenzilor de intrare. |
| - | * Comenzile necunoscute -> `PLAYER <tick> WAIT reason=UNKNOWN_COMMAND`. | + | * Comenzile necunoscute -> `WAIT`. |
| - | * Folosește `std::getline` și `std::istringstream` proprii (nu STL – scrie un parser minimal). | + | * **Gestionare bombe:** Menține o listă de bombe active cu timer-uri. La fiecare tick, decrementezi timer-ul. Când timer = 0, bomba explodează cu raza 2 (celule la distanță 1 și 2 în direcțiile N, S, E, W). |
| + | * **Gestionare pereți:** Menține o listă de pereți activi cu un contor de damage. Când o bombă explodează în raza sa, peretele primește damage. După 2 bombe, peretele este distrus. | ||
| + | * **Blocare explozii:** Când o bombă explodează, verifică dacă pereții blochează damage-ul către anumite celule (dacă un perete e între bomba și jucător, damage-ul este redus sau blocat). | ||
| + | * **Vizibilitate:** Toate bombele și pereții plantați sunt vizibili (vezi `REF BOMB_PLANTED ...`, `REF WALL_PLANTED ...`), deci poți planifica strategia. | ||
| + | * Poți folosi STL (vector, map, etc.) pentru a gestiona bombele, pereții și jucătorii. | ||
| ===== 5. Punctaj ===== | ===== 5. Punctaj ===== | ||
| Line 179: | Line 313: | ||
| Programul vostru trebuie să fie robust la: | Programul vostru trebuie să fie robust la: | ||
| - | * Comenzi duplicat (ex: același `REF SPAWN` repetat). | + | * Comenzi duplicat (ex: același `SPAWN` repetat). |
| - | * Ticks lipsă (trebuie să faceți `PLAYER WAIT` până revine). | + | * Ticks lipsă (trebuie să faceți `WAIT` până revine). |
| - | * Output folosit ca input (linii `PLAYER` în stream). | + | * Output folosit ca input (linii de acțiune în stream). |
| - | ===== 7. Încărcare și Testare ===== | + | ===== 7. Comunicare în Timp Real între Programe ===== |
| + | |||
| + | Pentru dueluri live sau testare interactivă, ai mai multe opțiuni: | ||
| + | |||
| + | ==== 7.1 Named Pipes (FIFO) - Timp Real ==== | ||
| + | |||
| + | **Creezi un pipe și conectezi programele:** | ||
| + | |||
| + | <code bash> | ||
| + | # Creează pipe-ul | ||
| + | mkfifo /tmp/arena_pipe | ||
| + | |||
| + | # Rulează Student A (scrie în pipe) | ||
| + | ./arena_studentA < input.txt > /tmp/arena_pipe & | ||
| + | |||
| + | # Rulează Student B (citește din pipe) | ||
| + | ./arena_studentB < /tmp/arena_pipe > output.txt | ||
| + | |||
| + | # Curăță după | ||
| + | rm /tmp/arena_pipe | ||
| + | </code> | ||
| + | |||
| + | **Avantaje:** Comunicare instantanee, fără fișiere intermediare. | ||
| + | **Dezavantaje:** Trebuie să gestionezi procesele manual. | ||
| + | |||
| + | ==== 7.2 Pipe Normal + tee (Salvare + Redirecționare) ==== | ||
| + | |||
| + | **Scrie în fișier ȘI trimite mai departe simultan:** | ||
| + | |||
| + | <code bash> | ||
| + | # Student A scrie la stdout, tee salvează în fișier ȘI trimite la Student B | ||
| + | ./arena_studentA < input.txt | tee arena_studentA.out | ./arena_studentB > arena_studentB.out | ||
| + | </code> | ||
| + | |||
| + | **Avantaje:** Simplu, salvează ambele output-uri. | ||
| + | **Dezavantaje:** Nu e "timp real" strict (bufferizare posibilă). | ||
| + | |||
| + | ==== 7.3 Process Substitution (Bash) ==== | ||
| + | |||
| + | **Bash creează automat pipe-uri temporare:** | ||
| + | |||
| + | <code bash> | ||
| + | # Student A scrie într-un "fișier virtual" care e de fapt input pentru Student B | ||
| + | ./arena_studentB < <(./arena_studentA < input.txt) > output.txt | ||
| + | |||
| + | # SAU invers: Student B primește output-ul lui A ca input | ||
| + | ./arena_studentB <(./arena_studentA < input.txt) > output.txt | ||
| + | </code> | ||
| + | |||
| + | **Avantaje:** Sintaxă curată, bash gestionează pipe-urile. | ||
| + | **Dezavantaje:** Funcționează doar în bash, nu în sh. | ||
| + | |||
| + | ==== 7.4 Exemplu Makefile pentru Dueluri ==== | ||
| + | |||
| + | <code makefile> | ||
| + | # Duel între două executabile | ||
| + | duel: arena_studentA arena_studentB | ||
| + | @echo "🚀 Pornesc duelul..." | ||
| + | @mkfifo /tmp/duel_pipe 2>/dev/null || true | ||
| + | @timeout 30 ./arena_studentA < teste/input/test01.in | \ | ||
| + | tee out/studentA.log | \ | ||
| + | ./arena_studentB > out/studentB.log || true | ||
| + | @rm -f /tmp/duel_pipe | ||
| + | @echo "✅ Duel terminat. Verifică out/studentA.log și out/studentB.log" | ||
| + | |||
| + | # Duel cu named pipe explicit | ||
| + | duel-fifo: arena_studentA arena_studentB | ||
| + | @mkfifo /tmp/arena_fifo | ||
| + | @./arena_studentA < teste/input/test01.in > /tmp/arena_fifo & \ | ||
| + | ./arena_studentB < /tmp/arena_fifo > out/duel_result.out; \ | ||
| + | rm -f /tmp/arena_fifo | ||
| + | </code> | ||
| + | |||
| + | **Format pentru dueluri:** Output-ul lui Student A trebuie transformat în comenzi de intrare înainte de a fi dat lui Student B. Vezi secțiunea 6 pentru scriptul de transcriere. | ||
| + | |||
| + | ===== 8. Încărcare și Testare ===== | ||
| **Comenzi Make:** | **Comenzi Make:** | ||
| Line 197: | Line 406: | ||
| GitHub Actions rulează `make` + trimite rezultatele la `rezultate.eu`. Output-ul scriptului `trimite_rezultate.py` va include `TOTAL_SCORE`, nickname etc. | GitHub Actions rulează `make` + trimite rezultatele la `rezultate.eu`. Output-ul scriptului `trimite_rezultate.py` va include `TOTAL_SCORE`, nickname etc. | ||
| - | ===== 8. Exemplu Simplificat ===== | + | ===== 9. Exemplu Simplificat ===== |
| + | |||
| + | **Scenariu:** Arenă 6×6, bombe cu timer 3, raza 2, damage 20, max 2 bombe, max 3 pereți. Tu (Alpha) ești la (0,0), adversarul (Beta) la (5,5). | ||
| ^ Input ^ | ^ Input ^ | ||
| | <code> | | <code> | ||
| - | ARENA 4 3 5 200 | + | ARENA 6 6 10 |
| - | RESUPPLY 5 2 | + | 3 2 20 2 3 |
| - | BOTS 2 | + | 100 0 0 |
| - | Scout 40 8 2 3 20 2 | + | |
| - | Guardian 80 5 6 1 35 3 | + | |
| - | UPGRADES 1 | + | |
| - | Overclock 50 4 0 2 | + | |
| STREAM | STREAM | ||
| - | REF TICK 1 | + | TICK 1 |
| - | REF SPAWN Beta Scout 10 1 1 | + | SPAWN Beta 5 5 |
| - | REF MOVE Beta 10 E 1 | + | MOVE Beta 5 4 |
| - | REF TICK 2 | + | TICK 2 |
| - | REF ATTACK Beta 10 0 6 | + | MOVE Beta 5 3 |
| - | REF EVENT EMP 2 | + | BOMB Beta 5 3 3 |
| + | TICK 3 | ||
| + | MOVE Beta 5 2 | ||
| + | WALL Beta 4 2 | ||
| + | TICK 4 | ||
| + | MOVE Beta 4 1 | ||
| + | TICK 5 | ||
| + | EXPLODE 5 3 | ||
| + | HIT 5 3 20 | ||
| + | HIT 5 2 20 | ||
| + | HIT 5 4 20 | ||
| + | HIT 5 1 20 | ||
| + | HIT 4 3 20 | ||
| + | HIT 3 3 20 | ||
| + | WALL_HIT 4 2 | ||
| + | TICK 6 | ||
| + | EXPLODE 2 0 | ||
| + | HIT 2 0 20 | ||
| + | HIT 1 0 20 | ||
| + | HIT 0 0 20 | ||
| + | HIT 3 0 20 | ||
| + | WALL_BROKEN 4 2 | ||
| END | END | ||
| </code> | | </code> | | ||
| Line 220: | Line 448: | ||
| ^ Output ^ | ^ Output ^ | ||
| | <code> | | <code> | ||
| - | PLAYER 1 SPAWN Alpha Scout id=1 x=0 y=0 | + | MOVE E |
| - | PLAYER 1 MOVE 1 N 1 | + | MOVE E |
| - | PLAYER 1 DEFEND id=1 shield=+2 | + | BOMB |
| - | PLAYER 2 ATTACK id=1 target=10 dmg=9 | + | WALL |
| - | PLAYER 2 ABILITY id=1 type=SCAN radius=2 | + | MOVE N |
| + | WAIT | ||
| SCOREBOARD | SCOREBOARD | ||
| - | ENERGY_COLLECTED: 28 | + | DAMAGE_DEALT: 20 |
| - | DAMAGE_DEALT: 9 | + | SURVIVAL_BONUS: 50 |
| - | STYLE_POINTS: 3 | + | |
| PENALTIES: 0 | PENALTIES: 0 | ||
| - | TOTAL_SCORE: 40 | + | TOTAL_SCORE: 70 |
| WINNER: Alpha | WINNER: Alpha | ||
| </code> | | </code> | | ||
| - | ===== 9. Tips & Checklist ===== | + | **Explicație:** |
| + | * Tick 1: Te deplasezi spre dreapta (E) pentru a te apropia de adversar. | ||
| + | * Tick 2: Continui spre dreapta. | ||
| + | * Tick 3: Plantezi o bombă la (2,0) care va exploda în 3 ticks (raza 2 = afectează celulele la distanță 1 și 2). | ||
| + | * Tick 4: Plantezi un perete la (1,0) pentru a te proteja de explozia adversarului. | ||
| + | * Tick 5: Bomba adversarului explodează la (5,3) cu raza 2, peretele tău la (4,2) primește prima lovitură (`REF WALL_DAMAGED`). | ||
| + | * Tick 6: Bomba ta explodează la (2,0) cu raza 2, peretele adversarului la (4,2) primește a doua lovitură și este distrus (`REF WALL_DESTROYED`). | ||
| + | * La final: Ai supraviețuit, ai dat damage adversarului, și ai distrus peretele adversarului cu 2 bombe. | ||
| + | |||
| + | ===== 10. Tips & Checklist ===== | ||
| * ✅ Stochează istoric comenzi pentru a putea reface dueluri. | * ✅ Stochează istoric comenzi pentru a putea reface dueluri. | ||
| * ✅ Normalizează toate coordonatele/ids. | * ✅ Normalizează toate coordonatele/ids. | ||