<s> from weakref import WeakKeyDictionary , ref <EOL> from flax . component import IPortal <EOL> from flax . geometry import Point <EOL> from flax . entity import Entity , Layer , Player <EOL> class Map : <EOL> def __init__ ( self , size ) : <EOL> self . rect = size . to_rect ( Point . origin ( ) ) <EOL> self . entity_positions = WeakKeyDictionary ( ) <EOL> self . portal_index = { } <EOL> self . tiles = { <EOL> point : Tile ( self , point ) <EOL> for point in self . rect . iter_points ( ) <EOL> } <EOL> _player = None <EOL> @ property <EOL> def player ( self ) : <EOL> assert self . _player is not None , "<STR_LIT>" <EOL> return self . _player <EOL> @ player . setter <EOL> def player ( self , value ) : <EOL> assert self . _player is None , ( <EOL> "<STR_LIT>" . format ( <EOL> id ( self . _player ) , id ( value ) ) ) <EOL> self . _player = value <EOL> @ player . deleter <EOL> def player ( self ) : <EOL> assert self . _player is not None , "<STR_LIT>" <EOL> del self . _player <EOL> @ property <EOL> def rows ( self ) : <EOL> for y in self . rect . range_height ( ) : <EOL> yield ( self . tiles [ Point ( x , y ) ] for x in self . rect . range_width ( ) ) <EOL> def place ( self , entity , position ) : <EOL> assert entity not in self . entity_positions <EOL> self . entity_positions [ entity ] = position <EOL> self . tiles [ position ] . attach ( entity ) <EOL> if entity . isa ( Player ) : <EOL> self . player = entity <EOL> if IPortal in entity . type . components : <EOL> dest = IPortal ( entity ) . destination <EOL> assert dest not in self . portal_index <EOL> self . portal_index [ dest ] = entity <EOL> def find ( self , entity ) : <EOL> assert isinstance ( entity , Entity ) <EOL> pos = self . entity_positions [ entity ] <EOL> return self . tiles [ pos ] <EOL> def move ( self , entity , position ) : <EOL> old_position = self . entity_positions [ entity ] <EOL> old_tile = self . tiles [ old_position ] <EOL> old_tile . detach ( entity ) <EOL> self . entity_positions [ entity ] = position <EOL> new_tile = self . tiles [ position ] <EOL> new_tile . attach ( entity ) <EOL> def remove ( self , entity ) : <EOL> position = self . entity_positions . pop ( entity ) <EOL> self . tiles [ position ] . detach ( entity ) <EOL> if entity . isa ( Player ) : <EOL> del self . player <EOL> if IPortal in entity . type . components : <EOL> dest = IPortal ( entity ) . destination <EOL> del self . portal_index [ dest ] <EOL> def __contains__ ( self , position ) : <EOL> return position in self . rect <EOL> class Tile : <EOL> def __init__ ( self , map , position ) : <EOL> self . _map = ref ( map ) <EOL> self . position = position <EOL> self . architecture = None <EOL> self . creature = None <EOL> self . items = [ ] <EOL> @ property <EOL> def map ( self ) : <EOL> return self . _map ( ) <EOL> @ property <EOL> def entities ( self ) : <EOL> if self . creature : <EOL> yield self . creature <EOL> for item in self . items : <EOL> yield item <EOL> yield self . architecture <EOL> def attach ( self , entity ) : <EOL> """<STR_LIT>""" <EOL> if entity . layer is Layer . architecture : <EOL> assert self . architecture is None <EOL> self . architecture = entity <EOL> elif entity . layer is Layer . item : <EOL> self . items . append ( entity ) <EOL> elif entity . layer is Layer . creature : <EOL> assert self . creature is None <EOL> self . creature = entity <EOL> else : <EOL> raise TypeError ( <EOL> "<STR_LIT>" <EOL> . format ( entity . layer , entity ) ) <EOL> def detach ( self , entity ) : <EOL> """<STR_LIT>""" <EOL> if entity . layer is Layer . architecture : <EOL> assert self . architecture is entity <EOL> self . architecture = None <EOL> elif entity . layer is Layer . item : <EOL> self . items . remove ( entity ) <EOL> elif entity . layer is Layer . creature : <EOL> assert self . creature is entity <EOL> self . creature = None <EOL> else : <EOL> raise TypeError ( <EOL> "<STR_LIT>" <EOL> . format ( entity . layer , entity ) ) <EOL> def multiplex_event ( self ) : <EOL> """<STR_LIT>""" <EOL> return self . entities </s>
