def find_candidate_placements(tile, border, candidate_tiles, max_candidates = -1, force_edge_label = None): assert isinstance(tile, Tile) assert isinstance(border, Boundary) assert len(border) > 0 assert isinstance(candidate_tiles, CandidateTiles) assert len(candidate_tiles) > 0 candidate_placements = [] for pos_tile in candidate_tiles.iterate(): (i0, j0, L0) = pos_tile.get_segment() assert L0 > 0 tile_border = pos_tile.get_boundary(list(tile.desc)) # Recompute PositionedTile because the common segment's 'i' index will not match pos_tile = PositionedTile(pos_tile.pos, border.common_segments(tile_border)) (i1, j1, L1) = pos_tile.get_segment() if (j0, L0) != (j1, L1): warn('Incoherent common segments for tile at {} in candidate_tiles: {} and computed against the current border: {}'.format(pos_tile.pos, (i0, j0, L0), (i1, j1, L1))) continue if force_edge_label is not None and force_edge_label not in Boundary.label_getter(border.iter_slice(i1, i1 + L1)): continue for r in border.find_matching_rotations(tile_border, pos_tile.get_segment()): placed_tile = PlacedTile.from_positioned_tile(pos_tile, tile, r) if validate_tile_placement(placed_tile, border): candidate_placements.append(placed_tile) if max_candidates > 0 and len(candidate_placements) >= max_candidates: break return candidate_placements
def validate_tile_placement(placed_tile, border): # Trivial except for river tiles if 'R' in Boundary.label_getter(placed_tile.iter_segment()): test_border = border.copy() test_border.merge(placed_tile.get_boundary()) for (point, edge, label) in placed_tile.iter_complement_segment(): if label == 'R': test_tile_border = boundary.from_edge(point, edge, Orientation.COUNTERCLOCKWISE, Domain.EXTERIOR) common_segments = test_border.common_segments(test_tile_border) if len(common_segments) != 1: return False (_, _, L) = common_segments[0] if L != 1: return False return True
def test_segment_labels(self): placed_tile = PlacedTile(self.test_tile, Vect(2, 1), r = 0, segment = (42, 1, 2)) self.assertEqual(list(Boundary.label_getter(placed_tile.iter_segment())), list('PT')) self.assertEqual(list(Boundary.label_getter(placed_tile.iter_complement_segment())), list('PF')) placed_tile = PlacedTile(self.test_tile, Vect(2, 1), r = 1, segment = (42, 1, 2)) self.assertEqual(list(Boundary.label_getter(placed_tile.iter_segment())), list('FP')) self.assertEqual(list(Boundary.label_getter(placed_tile.iter_complement_segment())), list('TP')) placed_tile = PlacedTile(self.test_tile, Vect(2, 1), r = 0, segment = (42, 1, 0)) self.assertEqual(list(Boundary.label_getter(placed_tile.iter_segment())), []) self.assertEqual(list(Boundary.label_getter(placed_tile.iter_complement_segment())), list('PTPF'))