| from collections import namedtuple | |
| WireInGrid = namedtuple('WireInGrid', 'tile grid_x grid_y wire') | |
| Connection = namedtuple('Connection', 'wire_a wire_b') | |
| class Connections(object): | |
| def __init__(self, tilegrid, tileconn, tile_wires): | |
| self.grid = tilegrid | |
| self.tile_wires = tile_wires | |
| self.coord_to_tile = {} | |
| self.coord_to_tile_type = {} | |
| for tile, tile_info in self.grid.items(): | |
| self.coord_to_tile[(tile_info['grid_x'], | |
| tile_info['grid_y'])] = tile | |
| self.coord_to_tile_type[(tile_info['grid_x'], | |
| tile_info['grid_y'])] = tile_info['type'] | |
| # Make sure we have tile type info for every tile in the grid. | |
| assert tile_info['type'] in self.tile_wires, ( | |
| tile_info['type'], self.tile_wires.keys()) | |
| self.potential_connections = {} | |
| for conn in tileconn: | |
| grid_deltas = conn['grid_deltas'] | |
| tile_types = conn['tile_types'] | |
| for pairs in conn['wire_pairs']: | |
| key = (tile_types[0], pairs[0]) | |
| if key not in self.potential_connections: | |
| self.potential_connections[key] = [] | |
| self.potential_connections[key].append( | |
| (grid_deltas, tile_types[1], pairs[1])) | |
| def all_possible_connections_from(self, wire_in_grid): | |
| tile_type = self.coord_to_tile_type[( | |
| wire_in_grid.grid_x, wire_in_grid.grid_y)] | |
| key = (tile_type, wire_in_grid.wire) | |
| if key not in self.potential_connections: | |
| return | |
| for relative_coord, target_tile_type, target_wire in ( | |
| self.potential_connections[key]): | |
| rel_x, rel_y = relative_coord | |
| target_coord = ( | |
| wire_in_grid.grid_x + rel_x, wire_in_grid.grid_y + rel_y) | |
| if target_coord in self.coord_to_tile_type: | |
| if self.coord_to_tile_type[target_coord] == target_tile_type: | |
| yield Connection( | |
| wire_in_grid, | |
| WireInGrid( | |
| tile=self.coord_to_tile[target_coord], | |
| grid_x=target_coord[0], | |
| grid_y=target_coord[1], | |
| wire=target_wire)) | |
| def get_connections(self): | |
| """ Yields Connection objects that represent all connections present in | |
| the grid based on tileconn """ | |
| for tile, tile_info in self.grid.items(): | |
| for wire in self.tile_wires[tile_info['type']]: | |
| wire_in_grid = WireInGrid( | |
| tile=tile, | |
| grid_x=tile_info['grid_x'], | |
| grid_y=tile_info['grid_y'], | |
| wire=wire) | |
| for potential_connection in self.all_possible_connections_from( | |
| wire_in_grid): | |
| yield potential_connection |