§
    @ê¥jR  ã                   ól  — d Z ddlZddlmc mZ ddlZddlZddl	m
Z
mZ ddlmZ ej                             d e ee¦  «                             ¦   «         j        j        ¦  «        ¦  «          G d„ de
¦  «        Z G d„ d¦  «        Z G d	„ d
ej        ¦  «        Zedk    r ej        ¦   «          dS dS )aì  
AutoPOE2 - Unit Test for Closed-Loop Map Runner Waystone Row 1 Farm (Doc 48)
Verifies:
1. Coordinate transform math between 1080p reference and 1440p real screen.
2. Exact center points for Slots 0..4 in Row 1 matching Ground-Truth.
3. Optical classification logic distinguishing Waystone (AvgRGB > 50) vs Empty (AvgRGB < 15).
4. FSM State transitions for 8-state closed loop and mission completion.
5. Invariant enforcement: INV-TOWN-PORTAL-KEY uses '.' (VK 0xBE), INV-UI-MAP-DEVICE delay.
é    N)ÚEnumÚauto)ÚPathc                   óÂ   — e Zd Z e¦   «         Z e¦   «         Z e¦   «         Z e¦   «         Z e¦   «         Z e¦   «         Z	 e¦   «         Z
 e¦   «         Z e¦   «         ZdS )ÚMapFarmStateN)Ú__name__Ú
__module__Ú__qualname__r   ÚCHECK_INVENTORY_ROW1ÚOPEN_MAP_DEVICEÚINSERT_WAYSTONEÚACTIVATE_MAPÚENTER_PORTALÚAUTONOMOUS_CLEAR_MAPÚTOWN_PORTAL_RETURNÚTRANSITION_TO_HIDEOUTÚ	COMPLETED© ó    ú4C:\Projects\AutoPOE2\tests\test_waystone_row1_fsm.pyr   r      su   € € € € € Ø˜4™6œ6ÐØ�d‘f”f€OØ�d‘f”f€OØ�4‘6”6€LØ�4‘6”6€LØ˜4™6œ6ÐØ˜™œÐØ ˜D™FœFÐØ�‘”€I€I€Ir   r   c                   ó   — e Zd ZdZd„ Zd„ ZdS )ÚClosedLoopMapRunnerFSMzEMock FSM simulating the 8-state autonomous map farming loop (Doc 48).c                 ól   — t           j        | _        t          |¦  «        | _        d| _        d| _        d S )Néÿÿÿÿr   )r   r   ÚstateÚlistÚinventory_row1Úcurrent_target_slotÚmaps_completed)ÚselfÚinitial_waystone_slotss     r   Ú__init__zClosedLoopMapRunnerFSM.__init__   s3   € Ý!Ô6ˆŒ
Ý"Ð#9Ñ:Ô:ˆÔØ#%ˆÔ ØˆÔÐÐr   c                 ót  — | j         t          j        k    r[d„ t          | j        ¦  «        D ¦   «         }|st          j        | _         dS |d         | _        t          j        | _         d| j        › �S | j         t          j        k    rt          j        | _         dS | j         t          j        k    r*d| j        | j        <   t          j	        | _         d| j        › �S | j         t          j	        k    rt          j
        | _         dS | j         t          j
        k    rt          j        | _         d	S | j         t          j        k    rt          j        | _         d
S | j         t          j        k    rt          j        | _         dS | j         t          j        k    r+| xj        dz  c_        t          j        | _         d| j        › �S dS )Nc                 ó   — g | ]	\  }}|¯|‘Œ
S r   r   )Ú.0ÚiÚhas_ws      r   ú
<listcomp>z/ClosedLoopMapRunnerFSM.step.<locals>.<listcomp>'   s!   € ÐSÐSÐS™x˜q %ÈUÐS˜ÐSÐSÐSr   r   r   ÚFOUND_WAYSTONE_SLOT_ÚMAP_DEVICE_OPENEDFÚINSERTED_SLOT_ÚMAP_ACTIVATED_WAIT_2500MSÚENTERED_MAP_INSTANCEÚMAP_CLEAREDÚPORTAL_KEY_DOT_PRESSEDé   ÚRETURNED_TO_HIDEOUT_TOTAL_ÚIDLE)r   r   r   Ú	enumerater   r   r   r   r   r   r   r   r   r   r   )r    Ú	waystoness     r   ÚstepzClosedLoopMapRunnerFSM.step%   sŒ  € ØŒ:�Ô:Ò:Ð:ØSÐS­9°TÔ5HÑ+IÔ+IÐSÑSÔSˆIØð #Ý)Ô3�”
Ø"�{Ø'0°¤|ˆDÔ$Ý%Ô5ˆDŒJØD¨$Ô*BÐDÐDÐDàŒZ�<Ô7Ò7Ð7Ý%Ô5ˆDŒJØ&Ð&àŒZ�<Ô7Ò7Ð7à<AˆDÔ Ô 8Ñ9Ý%Ô2ˆDŒJØ> DÔ$<Ð>Ð>Ð>àŒZ�<Ô4Ò4Ð4Ý%Ô2ˆDŒJØ.Ð.àŒZ�<Ô4Ò4Ð4Ý%Ô:ˆDŒJØ)Ð)àŒZ�<Ô<Ò<Ð<Ý%Ô8ˆDŒJØ �=àŒZ�<Ô:Ò:Ð:Ý%Ô;ˆDŒJØ+Ð+àŒZ�<Ô=Ò=Ð=ØÐÔ 1Ñ$ÐÔÝ%Ô:ˆDŒJØE°Ô0CÐEÐEÐEàˆvr   N)r   r	   r
   Ú__doc__r"   r5   r   r   r   r   r      s8   € € € € € ØOÐOð ð  ð  ð)ð )ð )ð )ð )r   r   c                   ó2   — e Zd Zd„ Zd„ Zd„ Zd„ Zd„ Zd„ ZdS )ÚTestWaystoneRow1Farmc                 óh   — d| _         d| _        d| _        d| _        d| _        d| _        d| _        d S )Ni€  i8  g     à“@g     p‚@g     @J@é   )Úref_wÚref_hÚinv_origin_x_1080Úinv_origin_y_1080Úinv_cell_w_1080Úinv_cell_h_1080Úcols)r    s    r   ÚsetUpzTestWaystoneRow1Farm.setUpQ   s;   € àˆŒ
ØˆŒ
Ø!'ˆÔØ!&ˆÔØ#ˆÔØ#ˆÔØˆŒ	ˆ	ˆ	r   c                 óŠ  — d}d}| j         |z  }| j        |z  }| j        |z  }| j        |z  }|                      |dd¬¦  «         |                      |dd¬¦  «         |                      t          |¦  «        d¦  «         |                      |dd¬¦  «         |                      |dd¬¦  «         g d	¢}|D ]Œ\  }}	}
|||z  z   |d
z  z   }|d|z  z   |d
z  z   }|                      t          t          |¦  «        ¦  «        |	d|› d�¦  «         |                      t          t          |¦  «        ¦  «        |
d|› d�¦  «         Œ�dS )zGVerify 1080p reference coordinates scale exactly to 1440p ground-truth.çUUUUUUõ?g     €š@é   )ÚplacesgUUUUU•ˆ@r0   i  g     €Q@))r   iÃ  é6  )r0   i	  rG   )rE   iO  rG   )é   i•  rG   )é   iÛ  rG   g      à?r   úSlot z X mismatchz Y mismatchN)r=   r>   r?   r@   ÚassertAlmostEqualÚassertEqualÚroundÚint)r    Úscale_xÚscale_yÚorigin_x_1440Úorigin_y_1440Úcell_w_1440Úcell_h_1440Úexpected_centersÚcolÚexp_xÚexp_yÚcxÚcys                r   Ú test_coordinate_scaling_to_1440pz5TestWaystoneRow1Farm.test_coordinate_scaling_to_1440p[   s—  € à!ˆØ!ˆàÔ.°Ñ8ˆØÔ.°Ñ8ˆØÔ*¨WÑ4ˆØÔ*¨WÑ4ˆà×Ò˜}¨f¸QÐÑ?Ô?Ð?Ø×Ò˜}Ð.?ÈÐÑJÔJÐJØ×Ò�˜}Ñ-Ô-¨sÑ3Ô3Ð3Ø×Ò˜{¨D¸ÐÑ;Ô;Ð;Ø×Ò˜{¨D¸ÐÑ;Ô;Ð;ð
ð 
ð 
Ðð "2ð 	Nð 	NÑˆC�˜Ø  {Ñ!2Ñ2°kÀCÑ6GÑHˆBØ  [¡Ñ0°KÀ#Ñ4EÑFˆBØ×Ò�S¥ r¡¤™^œ^¨UÐ4L¸CÐ4LÐ4LÐ4LÑMÔMÐMØ×Ò�S¥ r¡¤™^œ^¨UÐ4L¸CÐ4LÐ4LÐ4LÑMÔMÐMÐMð		Nð 	Nr   c                 ó¶   — d}d}d}d}t          ||z  ¦  «        }t          ||z  ¦  «        }|                      |d¦  «         |                      |d¦  «         dS )zGVerify Map Device in Shoreline Hideout scales correctly to (1018, 203).rD   g     Ü‡@g     c@iú  éË   N)rM   rL   )r    rO   rP   Úref_xÚref_yÚx_1440Úy_1440s          r   Ú!test_map_device_coordinates_1440pz6TestWaystoneRow1Farm.test_map_device_coordinates_1440pz   sj   € à!ˆØ!ˆàˆØˆå�u˜w‘Ñ'Ô'ˆÝ�u˜w‘Ñ'Ô'ˆà×Ò˜ Ñ&Ô&Ð&Ø×Ò˜ Ñ%Ô%Ð%Ð%Ð%r   c                 ól   — d}d}|}|                       |d¦  «         |                      ||d¦  «         dS )zAVerify INV-TOWN-PORTAL-KEY requires key '.' (VK 0xBE), never 'T'.é¾   éT   z-Portal key must NOT be 'T' (Warcry conflict)!N)rL   ÚassertNotEqual)r    ÚVK_DOTÚVK_TÚ
portal_keys       r   Útest_town_portal_key_invariantz3TestWaystoneRow1Farm.test_town_portal_key_invariantˆ   sF   € àˆØˆàˆ
Ø×Ò˜ TÑ*Ô*Ð*Ø×Ò˜J¨Ð.]Ñ^Ô^Ð^Ð^Ð^r   c                 óf   — d}g d¢}|D ]'\  }}}||k    }|                       ||d|› d�¦  «         Œ(dS )zaVerify optical classification logic distinguishes Waystones (AvgRGB > 50) vs Empty (AvgRGB < 15).g      I@))r   gÍÌÌÌÌZ@T)r0   gš™™™™YY@T)rE   gÍÌÌÌÌ,[@T)rH   gfffffÆY@T)rI   gfffff¦Y@T)é   gš™™™™™ @F)é   g333333 @F)é   g      !@F)é   gš™™™™™@F)é	   gffffff @F)é
   gÍÌÌÌÌÌ @F)é   g       @FrJ   z classification mismatchN)rL   )r    Ú	thresholdÚground_truth_samplesÚslot_idxÚavg_rgbÚexpected_presentÚ
is_presents          r   Ú%test_optical_classification_thresholdz:TestWaystoneRow1Farm.test_optical_classification_threshold‘   ss   € àˆ	ð 
ð  
ð  
Ðð 4Hð 	gð 	gÑ/ˆH�gÐ/Ø  9Ò,ˆJØ×Ò˜ZÐ)9Ð;eÀ8Ð;eÐ;eÐ;eÑfÔfÐfÐfð	gð 	gr   c                 ó²  — dgdz  dgdz  z   }t          |¦  «        }d}d}|j        t          j        k    r:||k     r4|                     ¦   «          |dz  }|j        t          j        k    r||k     °4|                      |j        t          j        ¦  «         |                      |j        d¦  «         |                      t          |j	        ¦  «        ¦  «         dS )	zRVerify full 8-step FSM iterates through all 5 waystones and terminates gracefully.Trl   Frn   r   éd   r0   N)
r   r   r   r   r5   rL   r   ÚassertFalseÚanyr   )r    Úinitial_slotsÚfsmÚ	steps_runÚ	max_stepss        r   Ú.test_closed_loop_fsm_execution_all_5_waystoneszCTestWaystoneRow1Farm.test_closed_loop_fsm_execution_all_5_waystones§   sÚ   € ð ˜ ™
 e W¨q¡[Ñ0ˆÝ$ ]Ñ3Ô3ˆð ˆ	Øˆ	ØŒi�<Ô1Ò1Ð1°iÀ)Ò6KÐ6KØ�HŠH‰JŒJˆJØ˜‰NˆIð Œi�<Ô1Ò1Ð1°iÀ)Ò6KÐ6Kð 	×Ò˜œ¥LÔ$:Ñ;Ô;Ð;Ø×Ò˜Ô+¨QÑ/Ô/Ð/à×Ò�˜SÔ/Ñ0Ô0Ñ1Ô1Ð1Ð1Ð1r   N)	r   r	   r
   rB   r[   rb   rj   ry   r‚   r   r   r   r8   r8   P   sw   € € € € € ðð ð ðNð Nð Nð>&ð &ð &ð_ð _ð _ðgð gð gð,2ð 2ð 2ð 2ð 2r   r8   Ú__main__)r6   ÚbuiltinsÚ@py_builtinsÚ_pytest.assertion.rewriteÚ	assertionÚrewriteÚ
@pytest_arÚsysÚunittestÚenumr   r   Úpathlibr   ÚpathÚinsertÚstrÚ__file__ÚresolveÚparentr   r   ÚTestCaser8   r   Úmainr   r   r   ú<module>r–      sP  ððð ð € € € € € € € € € € € € €
€
€
€
Ø €€€Ø Ð Ð Ð Ð Ð Ð Ð Ø Ð Ð Ð Ð Ð à „‡‚��3�3�t�t˜H‘~”~×-Ò-Ñ/Ô/Ô6Ô=Ñ>Ô>Ñ ?Ô ?Ð ?ð	ð 	ð 	ð 	ð 	�4ñ 	ô 	ð 	ð1ð 1ð 1ð 1ð 1ñ 1ô 1ð 1ðfg2ð g2ð g2ð g2ð g2˜8Ô,ñ g2ô g2ð g2ðR ˆzÒÐØ€H„M�O„O€O€O€Oð Ðr   