def _update_neighbour(self, network: _RailNetwork, position: Vector3[int]) -> Optional[PlacedBlock]: block = network.get_block(position) if block.type not in _RAIL_BLOCK_TYPES: position += (0, -1, 0) block = network.get_block(position) if block.type not in _RAIL_BLOCK_TYPES: return None if - position in _RAIL_TYPE[block.data].connector: return None connected_connector = network.get_conntected_connector(position) if len(connected_connector) == 2: return None has_corner = block.type == BlockType.RAIL if len(connected_connector) > 0: assert len(connected_connector) == 1 connected_connector = connected_connector[0] c = - position if position.y != 1 else position * (-1, 0, -1) for data in range(10) if has_corner else range(6): data, connector = _RAIL_TYPE[data] if connected_connector not in connector: continue if c in connector: return PlacedBlock(position, block.copy(data=data)) return None else: c = - position if position.y != 1 else position * (-1, 0, -1) for data in range(10) if has_corner else range(6): data, connector = _RAIL_TYPE[data] if c in connector: return PlacedBlock(position, block.copy(data=data)) return None
def get_additional_blocks(self, block: Block, linked_blocks: Sequence[Block]) -> Tuple[PlacedBlock, ...]: assert len(linked_blocks) == 2 left_side_lower_block, left_side_upper_block = linked_blocks right_side_mask = 0 if left_side_lower_block.type == block.type and self._get_face(left_side_lower_block) == self._get_face(block): if not self._is_right_side(left_side_upper_block): right_side_mask = self._IS_RIGHT_SIDE_MASK data = self._IS_UPPER_MASK | right_side_mask return PlacedBlock(Vector3(0, 0, 0), block), PlacedBlock(Vector3(0, 1, 0), block.copy(data=data))
def test_neighbour_rail_2(self): linked_blocks = dict(LINKED_BLOCKS) linked_blocks[Vector3(-1, -1, 0)] = RAIL.copy(data=0) blocks = self._get_additional_blocks(RAIL, linked_blocks) self.assertEqual(2, len(blocks)) self.assertEqual(PlacedBlock(Vector3(0, 0, 0), RAIL.copy(data=1)), blocks.pop(0)) self.assertEqual(PlacedBlock(Vector3(-1, -1, 0), RAIL.copy(data=2)), blocks.pop(0))
def test_neighbour_powered_rail_5(self): linked_blocks = dict(LINKED_BLOCKS) linked_blocks[Vector3(0, -1, -1)] = POWERED_RAIL.copy(data=1) blocks = self._get_additional_blocks(POWERED_RAIL, linked_blocks) self.assertEqual(2, len(blocks)) self.assertEqual( PlacedBlock(Vector3(0, 0, 0), POWERED_RAIL.copy(data=0)), blocks.pop(0)) self.assertEqual( PlacedBlock(Vector3(0, -1, -1), POWERED_RAIL.copy(data=5)), blocks.pop(0))
def test_rail_9_and_neighbour_rail_5_3(self): linked_blocks = dict(LINKED_BLOCKS) linked_blocks[Vector3(0, -1, -1)] = RAIL.copy(data=1) linked_blocks[Vector3(1, -1, 0)] = RAIL.copy(data=0) blocks = self._get_additional_blocks(RAIL, linked_blocks) self.assertEqual(3, len(blocks)) self.assertEqual(PlacedBlock(Vector3(0, 0, 0), RAIL.copy(data=9)), blocks.pop(0)) self.assertEqual(PlacedBlock(Vector3(0, -1, -1), RAIL.copy(data=5)), blocks.pop(0)) self.assertEqual(PlacedBlock(Vector3(1, -1, 0), RAIL.copy(data=3)), blocks.pop(0))
def test_rail_0(self): linked_blocks = dict(LINKED_BLOCKS) blocks = self._get_additional_blocks(RAIL, linked_blocks) self.assertEqual(1, len(blocks)) self.assertEqual(PlacedBlock(Vector3(0, 0, 0), RAIL), blocks.pop(0)) linked_blocks = dict(LINKED_BLOCKS) linked_blocks[Vector3(0, 0, -1)] = RAIL.copy(data=0) blocks = self._get_additional_blocks(RAIL, linked_blocks) self.assertEqual(1, len(blocks)) self.assertEqual(PlacedBlock(Vector3(0, 0, 0), RAIL), blocks.pop(0)) linked_blocks = dict(LINKED_BLOCKS) linked_blocks[Vector3(0, 0, 1)] = RAIL.copy(data=1) blocks = self._get_additional_blocks(RAIL, linked_blocks) self.assertEqual(2, len(blocks)) self.assertEqual(PlacedBlock(Vector3(0, 0, 0), RAIL), blocks.pop(0)) self.assertEqual(PlacedBlock(Vector3(0, 0, 1), RAIL), blocks.pop(0))
def get_additional_blocks(self, block: Block, linked_blocks: Sequence[Block]) -> Tuple[PlacedBlock, ...]: network = _RailNetwork(zip(_SURROUNDING, linked_blocks)) data = self._get_block_data(network, block.type == BlockType.RAIL) blocks = [PlacedBlock(Vector3(0, 0, 0), block.copy(data=data))] rail_type = _RAIL_TYPE[data] for connector in rail_type.connector: updated = self._update_neighbour(network, connector) if updated: blocks.append(updated) return tuple(blocks)
def test_powered_rail_3(self): linked_blocks = dict(LINKED_BLOCKS) linked_blocks[Vector3(-1, 1, 0)] = POWERED_RAIL.copy(data=1) blocks = self._get_additional_blocks(POWERED_RAIL, linked_blocks) self.assertEqual(2, len(blocks)) self.assertEqual( PlacedBlock(Vector3(0, 0, 0), POWERED_RAIL.copy(data=3)), blocks.pop(0)) self.assertEqual( PlacedBlock(Vector3(-1, 1, 0), POWERED_RAIL.copy(data=1)), blocks.pop(0)) # TODO remove linked_blocks = dict(LINKED_BLOCKS) linked_blocks[Vector3(-1, 1, 0)] = POWERED_RAIL.copy(data=0) blocks = self._get_additional_blocks(POWERED_RAIL, linked_blocks) self.assertEqual(2, len(blocks)) self.assertEqual( PlacedBlock(Vector3(0, 0, 0), POWERED_RAIL.copy(data=3)), blocks.pop(0)) self.assertEqual( PlacedBlock(Vector3(-1, 1, 0), POWERED_RAIL.copy(data=1)), blocks.pop(0))
def append(self, position: Vector3[int], block: Block, update: Callable[[], None]) -> None: self._action.append(_UpdateAction(PlacedBlock(position, block), update))
def get_additional_blocks(self, block: Block, linked_blocks: Sequence[Block]) -> Tuple[PlacedBlock, ...]: assert len(linked_blocks) == 1 base_side_block = linked_blocks[0] if base_side_block.type == block.type and base_side_block.data == block.data: block = block.copy(data=block.data ^ 1) return PlacedBlock(Vector3(0, 0, 0), block),
def get_additional_blocks(self, block: Block, linked_blocks: Sequence[Block]) -> Tuple[PlacedBlock, ...]: return PlacedBlock(Vector3(0, 0, 0), block), PlacedBlock(Vector3(0, 1, 0), block.copy(data=self._IS_UPPER_MASK))
def get_additional_blocks(self, block: Block, linked_blocks: Sequence[Block]) -> Tuple[PlacedBlock, ...]: return PlacedBlock(Vector3(0, 0, 0), block),