From 7592365228e00dcf3bb36f178fe39083c792b41c Mon Sep 17 00:00:00 2001 From: Jakub Pelc <jakub.pelc@email.cz> Date: Thu, 6 Mar 2025 09:37:45 +0100 Subject: [PATCH 1/2] =?UTF-8?q?Dal=C5=A1=C3=AD=20reformulace=20specifikace?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- specifikace.md | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/specifikace.md b/specifikace.md index 39754b4..c83bd6c 100644 --- a/specifikace.md +++ b/specifikace.md @@ -71,15 +71,19 @@ Kontrola délky instrukce se provádí porovnáním čtverců délky instrukce a ### 2) Řešení kolizí -Kolize se řeší v **1 až 5 podkrocích**. -V rámci každého podkroku se nejprve kontrolují kolize se všemi asteroidy a poté s ohraničujícím boxem. -Pokud dojde ke kolizi během podkroku, kolize se vyřeší (viz. níže) a **okamžitě se zahájí další podkrok,** dokud není dosažen limit (5). +Kolize se řeší v **1 až 5 podkrocích**. Každý podkrok má dvě fáze: -Pokud během celého kroku dojde ke kolizi, rychlost závodníka se sníží na polovinu. -Toto zpomalení může nastat nejvýše **jednou za krok**, bez ohledu na počet kolizí v individuálních podkrocích. +- kontrola kolizí s asteroidy - v této fázi dojde k **nejvýše jedné** kolizi +- kontrola kolizí s okraji mapy - kontrolujeme každý ze čtyř okrajů mapy + +Pokud v podkroku nedojde k žádné kolizi (ani s asteroidem, ani s okrajem mapy), považujeme kolize za vyřešené. Pokud ke kolizi dojde, provedeme další podkrok. Podkroků provedeme maximálně 5. + +Pokud v aspoň jednom podkroku dojde ke kolizi (ať už s asteroidem nebo s okrajem mapy), rychlost závodníka se sníží na polovinu. +Toto zpomalení může tedy nastat nejvýše **jednou za krok**, bez ohledu na počet kolizí v individuálních podkrocích. #### Asteroidy -Iterujeme přes všechny asteroidy `asteroid` v pořadí, v jakém byly přidány do simulace, a pro každý provádíme následující kroky: + +Iterujeme přes všechny asteroidy `asteroid` v **pořadí, v jakém byly přidány do simulace**, a pro každý provádíme následující kroky: - Pokud `euclidean_distance(asteroid, racer) > (asteroid.radius + racer.radius)`, kolize nenastala (pokračujeme k dalšímu asteroidu). - V případě kolize provedeme následující: @@ -87,6 +91,9 @@ Iterujeme přes všechny asteroidy `asteroid` v pořadí, v jakém byly přidán - Vektor k vytlačení závodníka: `vn = racer.position - asteroid.position`. - Vzdálenost posunutí: `push_by = distance - (asteroid.radius + racer.radius)`. - Posuneme závodníka: `racer.position -= (push_by * vn) / distance`. + - **Přestaneme iterovat** přes asteroidy a posuneme se do další fáze podkroku (řešení kolize s okrajem mapy). + +Pokud by tedy loď kolidovala s více asteroidy, vyhodnotíme kolizi pouze s tím, který má nejnižší index. #### Ohraničující box Pro každou stranu boxu zkontrolujeme kolizi (například pokud `racer.x - racer.radius < box.min_x` pro levou stranu). From 86afa8b3329aab23d1d539281925dc750963758d Mon Sep 17 00:00:00 2001 From: Jakub Pelc <jakub.pelc@email.cz> Date: Thu, 6 Mar 2025 10:03:56 +0100 Subject: [PATCH 2/2] =?UTF-8?q?Dal=C5=A1=C3=AD=20up=C5=99esn=C4=9Bn=C3=AD?= =?UTF-8?q?=20specifikace?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- specifikace.md | 31 +++++++++++++++++++++++++------ 1 file changed, 25 insertions(+), 6 deletions(-) diff --git a/specifikace.md b/specifikace.md index c83bd6c..e9f1053 100644 --- a/specifikace.md +++ b/specifikace.md @@ -42,6 +42,20 @@ class BoundingBox: # (okraj) max_y: int ``` +A tyto funkce: + +```python +def distance_squared(x1, y1, x2=0, y2=0) -> int: + """Squared Euclidean distance between two points.""" + return (int(x1) - int(x2)) ** 2 + (int(y1) - int(y2)) ** 2 +``` + +```python +def euclidean_distance(x1, y1, x2=0, y2=0): + """Integer Euclidean distance between two points. Uses integer square root.""" + return int(isqrt(distance_squared(x1, y1, x2, y2))) +``` + ## Simulace Každý krok simulace lze rozdělit do následujících tří fází: @@ -104,10 +118,15 @@ Iterujeme přes všechny cíle `goal` a označíme je jako dosažené, pokud `eu ### Poznámky -Všimněte si, že simulace používá několik neintuitivních zjednodušení: +Všimněte si, že simulace má několik neintuitivních zjednodušení a vlastností: -- při úvodním posunu lodi o její rychlost **nekontrolujeme** kolize -- kolize kontrolujeme až jako průsečík finální pozice lodi s asteroidy či cíle -- při kolizi s asteroidem se loď **neodrazí**, tedy nezmění se směr její rychlosti -- při řešení kolizí loď pouze posouváme ven z asteroidů -- při kolizi nezáleží na tom, v jaké fázi řešení podkroků vydělíme rychlost lodi dvěma +- Při úvodním posunu lodi o její rychlost **nekontrolujeme** kolize. +- Kolize kontrolujeme až jako průsečík finální pozice lodi s asteroidy či cíle. +- Při kolizi s asteroidem se loď **neodrazí**, tedy nezmění se směr její rychlosti. +- Při řešení kolizí loď pouze posouváme ven z asteroidů. +- Při kolizi nezáleží na tom, v jaké fázi řešení podkroků vydělíme rychlost lodi dvěma. + +Dále, pro detekci průsečíku lodi s asteroidem či cílem schválně používáme `euclidean_distance`, která má odmocninu zaokrouhlenou dolů. +Sice by kolize šly počítat exaktně pomocí druhých mocnin vzdálenosti, ale v okrajových případech bychom naráželi na limity velikosti čísel. + +Naše rustová (vyhodnocovadlo) i typescriptová (webová vizualizace) implementace používá místo exaktní `isqrt` klasickou float64 odmocninu, kterou poté zaokrouhlíme dolů na celé číslo.