§
    Æ“»j¨0  ã                   óö   — d Z ddlZddlZddlmZmZmZ ddlmZm	Z	m
Z
 ddlmZmZ ddlmZmZmZmZmZmZmZ ddlmZmZmZmZ ddlmZmZmZ  G d	„ d
ej        ¦  «        Z e!dk    r ej"        ¦   «          dS dS )uH  
Unit tests for FreeExile Endgame Infinite World Map & Map Content System.
Verifies:
1. Endgame Phase unlock conditions upon completing basic quests/campaign.
2. Infinite Procedural Node Graph generation with deterministic seeds.
3. Node progression: depth scaling, tier allocation (T1 to T16+ Ãœber), monster levels.
4. Procedural Map Content generation: random count (1-5) and distinct savage encounters per map.
5. Node lifecycle: ACCESSIBLE -> IN_PROGRESS -> CLEARED -> Frontier Expansion.
6. Server-Authoritative traversal rules and integration with 6-Portal Hideout Map Device.
é    N)ÚListÚDictÚSet)ÚQuestEngineÚcreate_default_quest_engineÚQuestStatus)ÚHideoutEngineÚHideoutTheme)ÚEndGameStatusÚMapBiomeTypeÚContentTypeÚMapNodeStatusÚ
MapContentÚMapNodeÚAtlasWorldState)ÚALL_CONTENT_TYPESÚCONTENT_DEFINITIONSÚget_content_definitionÚ calculate_content_count_for_tier)ÚEndGameAtlasEngineÚCAMPAIGN_COMPLETION_MIN_LEVELÚCAMPAIGN_COMPLETION_QUEST_IDc                   ó\   — e Zd Zd„ Zd„ Zd„ Zd„ Zd„ Zd„ Zd„ Z	d„ Z
d	„ Zd
„ Zddeddfd„ZdS )ÚTestEndGameAtlasSystemc                 ó    — t          ¦   «         | _        t          ¦   «         | _        t	          | j        | j        ¬¦  «        | _        d| _        d S )N)Úquest_engineÚhideout_engineÚexile_pioneer_01)r   r   r	   r   r   Úatlas_engineÚ	player_id)Úselfs    ú=C:\Projects\FreeExile\tests\unit\test_endgame_atlas_system.pyÚsetUpzTestEndGameAtlasSystem.setUp)   sL   € Ý7Ñ9Ô9ˆÔÝ+™oœoˆÔÝ.ØÔ*ØÔ.ð
ñ 
ô 
ˆÔð ,ˆŒˆˆó    c                 ó0  — | j                              | j        d¬¦  «         | j                             | j        ¦  «        }|                      |d¦  «         | j                             | j        ¦  «        }|                      |t          j	        ¦  «         dS )zENew players with no completed quests must have Endgame status LOCKED.é   ©Úplayer_levelzDNew player level 1 without campaign completion cannot unlock EndgameN)
r   Úinitialize_playerr    r   Úcheck_endgame_eligibilityÚassertFalseÚget_endgame_statusÚassertEqualr   ÚLOCKED)r!   Ú
can_unlockÚstatuss      r"   Ú,test_endgame_locked_initially_for_new_playerzCTestEndGameAtlasSystem.test_endgame_locked_initially_for_new_player2   s†   € àÔ×+Ò+¨D¬NÈÐ+ÑKÔKÐKØÔ&×@Ò@ÀÄÑPÔPˆ
Ø×Ò˜Ð%kÑlÔlÐlàÔ"×5Ò5°d´nÑEÔEˆØ×Ò˜¥Ô!5Ñ6Ô6Ð6Ð6Ð6r$   c                 óœ  — | j                              | j        t          ¬¦  «         dD ]Ÿ}| j                              | j        |t          ¬¦  «         | j                              | j        |¦  «        }|rT|j                             ¦   «         D ])}|                     |j	        ¦  «        |j        |j
        <   Œ*t          j        |_        Œ | j                              | j        t          t          ¬¦  «         | j                              | j        dd¬¦  «         | j                              | j        t          ¦  «        }|                      |¦  «         |                      |j        t          j        ¦  «         | j                             | j        ¦  «        }|                      |d¦  «         | j                             | j        d¬¦  «        }|                      |j        ¦  «         |                      | j                             | j        ¦  «        t0          j        ¦  «         |                      t7          |j        ¦  «        d	d
¦  «         dS )z@Completing the final basic campaign quest unlocks Endgame phase.r'   ©Ú!quest_norm_01_thuc_tinh_tang_kiemÚ!quest_norm_02_khai_thong_dan_dienÚ!quest_norm_03_luyen_khi_hoa_thachÚ quest_norm_04_diet_u_hon_kiem_noÚaction_vault_instant_buyoutr&   ©Úcountz@Player who completed campaign quest must be eligible for Endgamei9  ©Úseedr   z(Atlas must generate initial node clusterN)r   r)   r    r   Úaccept_questÚget_player_questÚ
objectivesÚvaluesÚwith_incrementÚtarget_countÚobjective_idr   Ú	COMPLETEDr0   r   Úrecord_actionÚassertIsNotNoner-   r   r*   Ú
assertTrueÚunlock_endgameÚis_endgame_unlockedr,   r   ÚUNLOCKEDÚassertGreaterÚlenÚnodes)r!   Úq_idÚqÚobjÚis_eligibleÚatlas_states         r"   Ú,test_endgame_unlocks_when_campaign_completedzCTestEndGameAtlasSystem.test_endgame_unlocks_when_campaign_completed;   s!  € àÔ×+Ò+¨D¬NÕIfÐ+ÑgÔgÐgð
ð 	1ð 	1ˆDð Ô×*Ò*¨4¬>¸4ÕNkÐ*ÑlÔlÐlØÔ!×2Ò2°4´>À4ÑHÔHˆAØð 1Øœ<×.Ò.Ñ0Ô0ð Zð Z�CØ58×5GÒ5GÈÔHXÑ5YÔ5Y�A”L Ô!1Ñ2Ð2Ý&Ô0�”øð 	Ô×&Ò& t¤~Õ7SÕbÐ&ñ  	Aô  	Að  	AØÔ×'Ò'ØŒNØ)Øð 	(ñ 	
ô 	
ð 	
ð Ô×.Ò.¨t¬~Õ?[Ñ\Ô\ˆØ×Ò˜QÑÔÐØ×Ò˜œ¥;Ô#8Ñ9Ô9Ð9ð Ô'×AÒAÀ$Ä.ÑQÔQˆØ�Š˜Ð%gÑhÔhÐhð Ô'×6Ò6°t´~ÈDÐ6ÑQÔQˆØ�Š˜Ô7Ñ8Ô8Ð8Ø×Ò˜Ô*×=Ò=¸d¼nÑMÔMÍ}ÔOeÑfÔfÐfØ×Ò�3˜{Ô0Ñ1Ô1°1Ð6`ÑaÔaÐaÐaÐar$   c                 ó
  — |                       d¬¦  «         | j                             | j        ¦  «        }|                      |¦  «         |j                             |j        ¦  «        }|                      |d¦  «         |                      |j	        d¦  «         |                      |j
        d¦  «         |                      |j        t          j        t          j        f¦  «         |                      t#          |j        ¦  «        d¦  «         |j        D ]l}|j                             |¦  «        }|                      |d|› d�¦  «         |                      |j	        d¦  «         |                      |j
        d¦  «         Œmd	S )
z^Initial Atlas cluster must contain origin node at Depth 0 and branching children at Depth 1-2.iÍ� r;   zOrigin node must existr   r&   é   zChild node z must exist in stateN)Ú_unlock_player_endgamer   Úget_atlas_stater    rF   rM   ÚgetÚcurrent_origin_node_idr-   ÚdepthÚtierÚassertInr0   r   Ú
ACCESSIBLEÚCLEAREDÚassertGreaterEqualrL   Úconnected_node_ids)r!   ÚstateÚoriginÚchild_idÚchilds        r"   Ú2test_infinite_atlas_initial_node_cluster_structurezITestEndGameAtlasSystem.test_infinite_atlas_initial_node_cluster_structureb   sl  € à×#Ò#¨Ð#Ñ/Ô/Ð/ØÔ!×1Ò1°$´.ÑAÔAˆØ×Ò˜UÑ#Ô#Ð#ð ”—’ Ô!=Ñ>Ô>ˆØ×Ò˜VÐ%=Ñ>Ô>Ð>Ø×Ò˜œ qÑ)Ô)Ð)Ø×Ò˜œ aÑ(Ô(Ð(Ø�Š�f”m¥mÔ&>ÅÔ@UÐ%VÑWÔWÐWð 	×Ò¥ FÔ$=Ñ >Ô >ÀÑBÔBÐBØÔ1ð 	3ð 	3ˆHØ”K—O’O HÑ-Ô-ˆEØ× Ò  Ð(T°hÐ(TÐ(TÐ(TÑUÔUÐUØ×Ò˜Uœ[¨!Ñ,Ô,Ð,Ø×#Ò# E¤J°Ñ2Ô2Ð2Ð2ð		3ð 	3r$   c                 ó’  — |                       d¬¦  «         | j                             | j        ¦  «        }|j                             ¦   «         D ]w}d|j        z   }|                      |j        |d|j	        › d|j        › d|› �¦  «         |  
                    |j        t          dt          d|j        ¦  «        ¦  «        ¦  «         Œxd	S )
zMNode tier and monster level must scale proportionally with depth from origin.é*   r;   éC   úNode z tier z must have monster level r&   é   N)rV   r   rW   r    rM   r@   r[   r-   Úmonster_levelÚnode_idr_   ÚmaxÚminrZ   )r!   ra   ÚnodeÚexpected_monster_lvls       r"   Ú*test_node_depth_scaling_and_monster_levelszATestEndGameAtlasSystem.test_node_depth_scaling_and_monster_levelsw   sÞ   € à×#Ò#¨Ð#Ñ,Ô,Ð,ØÔ!×1Ò1°$´.ÑAÔAˆð ”K×&Ò&Ñ(Ô(ð 	Lð 	LˆDØ#%¨¬	¡>Ð Ø×ÒØÔ"Ø$Øf˜œÐfÐf¨D¬IÐfÐfÐPdÐfÐfñô ð ð ×#Ò# D¤I­s°1µc¸"¸d¼jÑ6IÔ6IÑ/JÔ/JÑKÔKÐKÐKð	Lð 	Lr$   c                 ó*  — |                       d¬¦  «         | j                             | j        ¦  «        }|j                             ¦   «         D �]B}|j        }t          |j        ¦  «        \  }}|  	                    t          |¦  «        |d|j        › d|j        › d|› d�¦  «         |                      t          |¦  «        |d|j        › d|j        › d|› d�¦  «         |D ]®}|                      |j        t          ¦  «         |                      t          |j        ¦  «        dk    ¦  «         |                      t          |j        ¦  «        dk    ¦  «         |  	                    |j        d	¦  «         |                      |j        d
¦  «         Œ¯�ŒDdS )zSEvery map node must generate a random count of contents (1 to 5) scaling with tier.i+  r;   ri   z (Tier z) must have at least z	 contentsz) must not exceed r   r&   é   N)rV   r   rW   r    rM   r@   Úcontentsr   r[   r_   rL   rl   ÚassertLessEqualr\   Úcontent_typer   rG   ÚnameÚdescriptionÚdifficulty_rating)r!   ra   ro   rt   Úmin_cÚmax_cÚcontents          r"   Ú0test_random_map_content_density_and_tier_scalingzGTestEndGameAtlasSystem.test_random_map_content_density_and_tier_scaling‡   s­  € à×#Ò#¨Ð#Ñ-Ô-Ð-ØÔ!×1Ò1°$´.ÑAÔAˆà”K×&Ò&Ñ(Ô(ð 	Cñ 	CˆDØ”}ˆHÝ;¸D¼IÑFÔF‰LˆE�5Ø×#Ò#Ý�H‘”ØØ]˜œÐ]Ð]¨T¬YÐ]Ð]ÈUÐ]Ð]Ð]ñô ð ð
 × Ò Ý�H‘”ØØZ˜œÐZÐZ¨T¬YÐZÐZÈ%ÐZÐZÐZñô ð ð $ð Cð C�Ø—’˜gÔ2Õ4EÑFÔFÐFØ—’¥ G¤LÑ 1Ô 1°AÒ 5Ñ6Ô6Ð6Ø—’¥ GÔ$7Ñ 8Ô 8¸1Ò <Ñ=Ô=Ð=Ø×'Ò'¨Ô(AÀ1ÑEÔEÐEØ×$Ò$ WÔ%>ÀÑBÔBÐBÐBñCð	Cð 	Cr$   c                 óÆ  — |                       d¬¦  «         | j                             | j        ¦  «        }|j        }|j        }| j                             | j        |¦  «        }|                      |d         ¦  «         |                      |d         d¦  «         | j                             | j        ¦  «        }|                      |j        |dz   ¦  «         |                      |j	        d¦  «         |j
        |         }|                      |j        t          j        ¦  «         |j        D ]4}|j
        |         }|                      |j        t          j        ¦  «         Œ5dS )z^Clearing a node transitions it to CLEARED, awards 1 Atlas Passive Point, and unlocks children.i	  r;   ÚsuccessÚatlas_points_awardedr&   N)rV   r   rW   r    rY   Úatlas_passive_pointsÚcomplete_map_noderG   r-   Útotal_maps_clearedrM   r0   r   r^   r`   r]   )	r!   ra   Ú	origin_idÚinitial_pointsÚresultÚupdated_stateÚorigin_noderc   rd   s	            r"   Ú;test_clearing_node_unlocks_adjacent_and_grants_atlas_pointszRTestEndGameAtlasSystem.test_clearing_node_unlocks_adjacent_and_grants_atlas_points¢   sW  € à×#Ò#¨Ð#Ñ-Ô-Ð-ØÔ!×1Ò1°$´.ÑAÔAˆØÔ0ˆ	ØÔ3ˆð Ô"×4Ò4°T´^ÀYÑOÔOˆØ�Š˜˜yÔ)Ñ*Ô*Ð*Ø×Ò˜Ð 6Ô7¸Ñ;Ô;Ð;àÔ)×9Ò9¸$¼.ÑIÔIˆØ×Ò˜Ô;¸^ÈaÑ=OÑPÔPÐPØ×Ò˜Ô9¸1Ñ=Ô=Ð=ð $Ô)¨)Ô4ˆØ×Ò˜Ô+­]Ô-BÑCÔCÐCð $Ô6ð 	Eð 	EˆHØ!Ô'¨Ô1ˆEØ×Ò˜Uœ\­=Ô+CÑDÔDÐDÐDð	Eð 	Er$   c                 óš  — |                       d¬¦  «         | j                             | j        ¦  «        }t	          |j        ¦  «        }| j                             | j        |j        ¦  «         | j                             | j        ¦  «        }|j        |j                 }|j        d         }| j                             | j        |¦  «        }|  	                    |d         ¦  «         | j                             | j        ¦  «        }|  
                    t	          |j        ¦  «        |d¦  «         |                      |j        d¦  «         dS )z_Clearing child nodes expands the infinite frontier, generating deeper depths deterministically.iê  r;   r   r   zNFrontier expansion must add newly discovered/accessible nodes at deeper depthsrU   N)rV   r   rW   r    rL   rM   r‚   rY   r`   rG   rK   r_   Úunlocked_depth)r!   ra   Úinitial_node_countrˆ   Údepth_1_node_idÚresÚ	new_states          r"   Ú+test_infinite_frontier_procedural_expansionzBTestEndGameAtlasSystem.test_infinite_frontier_procedural_expansion»   s-  € à×#Ò#¨Ð#Ñ.Ô.Ð.ØÔ!×1Ò1°$´.ÑAÔAˆÝ  ¤Ñ-Ô-Ðð 	Ô×+Ò+¨D¬N¸EÔ<XÑYÔYÐYØÔ!×1Ò1°$´.ÑAÔAˆØ”k %Ô">Ô?ˆð &Ô8¸Ô;ˆØÔ×1Ò1°$´.À/ÑRÔRˆØ�Š˜˜IœÑ'Ô'Ð'ð Ô%×5Ò5°d´nÑEÔEˆ	Ø×ÒÝ�	”Ñ Ô ØØ\ñ	
ô 	
ð 	
ð
 	×Ò 	Ô 8¸!Ñ<Ô<Ð<Ð<Ð<r$   c                 ó^  — |                       d¬¦  «         | j                             | j        ¦  «        }|j        }| j                             | j        |¦  «        }|                      |d         ¦  «         |                      |d         d¦  «         |                      d|¦  «         | j	         
                    | j        ¦  «        }|                      |j        j        d¦  «         |                      |j        j        ¦  «         |                      |j        j        j        d¦  «         dS )	zWActivating an accessible node configures the Hideout Map Device with exactly 6 Portals.ée   r;   r   Úportals_openedé   Úinstance_idr&   N)rV   r   rW   r    rY   Úactivate_map_noderG   r-   r\   r   Úget_or_create_hideoutÚ
map_deviceÚportals_remainingrF   Ú
active_mapr[   )r!   ra   r„   Ú
activationÚhideouts        r"   Ú8test_node_activation_opens_six_portals_in_hideout_devicezOTestEndGameAtlasSystem.test_node_activation_opens_six_portals_in_hideout_deviceÔ   s  € à×#Ò#¨Ð#Ñ-Ô-Ð-ØÔ!×1Ò1°$´.ÑAÔAˆØÔ0ˆ	ð Ô&×8Ò8¸¼ÈÑSÔSˆ
Ø�Š˜
 9Ô-Ñ.Ô.Ð.Ø×Ò˜Ð$4Ô5°qÑ9Ô9Ð9Ø�Š�m ZÑ0Ô0Ð0ð Ô%×;Ò;¸D¼NÑKÔKˆØ×Ò˜Ô+Ô=¸qÑAÔAÐAØ×Ò˜WÔ/Ô:Ñ;Ô;Ð;Ø×Ò˜Ô+Ô6Ô;¸QÑ?Ô?Ð?Ð?Ð?r$   c                 óä   — |                       d¬¦  «         d}| j                             | j        |¦  «        }|                      |d         ¦  «         |                      |d         d¦  «         dS )zLAttempting to activate an unreachable/locked node must be strictly rejected.iç  r;   Únode_d99_b99_faker   ÚerrorÚNODE_NOT_FOUNDN)rV   r   r–   r    r+   r-   )r!   Úfake_node_idrŽ   s      r"   Ú<test_server_authoritative_traversal_rejects_unreachable_nodezSTestEndGameAtlasSystem.test_server_authoritative_traversal_rejects_unreachable_nodeæ   sq   € à×#Ò#¨Ð#Ñ-Ô-Ð-à*ˆØÔ×1Ò1°$´.À,ÑOÔOˆØ×Ò˜˜YœÑ(Ô(Ð(Ø×Ò˜˜WœÐ'7Ñ8Ô8Ð8Ð8Ð8r$   é90  r<   ÚreturnNc                 ót  — | j                              | j        t          ¬¦  «         dD ]Ÿ}| j                              | j        |t          ¬¦  «         | j                              | j        |¦  «        }|rT|j                             ¦   «         D ])}|                     |j	        ¦  «        |j        |j
        <   Œ*t          j        |_        Œ | j                              | j        t          t          ¬¦  «         | j                              | j        dd¬¦  «         | j                             | j        |¬¦  «         d S )Nr'   r3   r8   r&   r9   r;   )r   r)   r    r   r=   r>   r?   r@   rA   rB   rC   r   rD   r0   r   rE   r   rH   )r!   r<   rN   rO   rP   s        r"   rV   z-TestEndGameAtlasSystem._unlock_player_endgameð   s@  € ØÔ×+Ò+¨D¬NÕIfÐ+ÑgÔgÐgð
ð 	1ð 	1ˆDð Ô×*Ò*¨4¬>¸4ÕNkÐ*ÑlÔlÐlØÔ!×2Ò2°4´>À4ÑHÔHˆAØð 1Øœ<×.Ò.Ñ0Ô0ð Zð Z�CØ58×5GÒ5GÈÔHXÑ5YÔ5Y�A”L Ô!1Ñ2Ð2Ý&Ô0�”øàÔ×&Ò& t¤~Õ7SÕbÐ&ñ  	Aô  	Að  	AØÔ×'Ò'ØŒNØ)Øð 	(ñ 	
ô 	
ð 	
ð
 	Ô×(Ò(¨¬¸dÐ(ÑCÔCÐCÐCÐCr$   )r¤   )Ú__name__Ú
__module__Ú__qualname__r#   r1   rS   re   rq   r}   r‰   r�   r�   r£   ÚintrV   © r$   r"   r   r   (   sê   € € € € € ð,ð ,ð ,ð7ð 7ð 7ð%bð %bð %bðN3ð 3ð 3ð*Lð Lð Lð Cð Cð Cð6Eð Eð Eð2=ð =ð =ð2@ð @ð @ð$9ð 9ð 9ðDð D¨3ð D¸4ð Dð Dð Dð Dð Dð Dr$   r   Ú__main__)#Ú__doc__ÚunittestÚtimeÚtypingr   r   r   Úserver.world.quest_enginer   r   r   Úserver.world.hideout_enginer	   r
   Úserver.world.endgame_typesr   r   r   r   r   r   r   Ú$server.world.endgame_content_catalogr   r   r   r   Ú!server.world.endgame_atlas_enginer   r   r   ÚTestCaser   r§   Úmainr«   r$   r"   ú<module>r¸      s£  ðð	ð 	ð €€€Ø €€€Ø "Ð "Ð "Ð "Ð "Ð "Ð "Ð "Ð "Ð "à [Ð [Ð [Ð [Ð [Ð [Ð [Ð [Ð [Ð [Ø CÐ CÐ CÐ CÐ CÐ CÐ CÐ Cðð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ðð ð ð ð ð ð ð ð ð ð ð ðð ð ð ð ð ð ð ð ð ð]Dð ]Dð ]Dð ]Dð ]D˜XÔ.ñ ]Dô ]Dð ]Dð@ ˆzÒÐØ€H„M�O„O€O€O€Oð Ðr$   