Пример #1
0
    def _get_changes_to_fit(
        self, destination_index: int, destination: StagingPalette
    ) -> Optional[List['ColorRemapsIntoStagingPalettesEvaluator.ChangeList']]:
        # Check this remap to see if it has a palette assigned.  If it does, does it match the destination?
        assigned_palette = self.source.get_intention(
            ColorRemap.INTENTION_PALETTE)
        if (assigned_palette
                is not None) and (assigned_palette != destination_index):
            # We have a remap that wants to be assigned to a specific palette, and it's not this one.
            return None

        # Take the colors in the source and execute a solver to map them to the palette's colors.
        palette_colors = destination.color_entries

        solver = ConstraintSolver(self.source.color_entries, palette_colors,
                                  ColorsIntoColorsEvaluator, None)
        while solver.is_exhausted() == False:
            solver.update()

        # Did we have any solutions?
        solutions = solver.solutions
        if len(solutions) == 0:
            # No solutions means we can't fit.
            return None

        change_lists = []
        # Each solution is a possible way to fit the remap into the palette
        for solution in solutions:
            # A solution is just a list of Moves.  Make each solution into its own ChangeList.
            change_list = ColorRemapsIntoStagingPalettesEvaluator.ChangeList(
                solution)
            change_lists.append(change_list)

        return change_lists
    color_remap={})

# COLOR REMAPS
color_remaps = [font_color_remap, flags_color_remap]

##############################################################################
# STAGING PALETTES
staging_palette_sprites = StagingPalette(16)
staging_palette_bg_only = StagingPalette(16)

staging_palettes = [staging_palette_sprites, staging_palette_bg_only]

##############################################################################
# SOLUTION FOR COLOR REMAPS -> STAGING PALETTES
remap_to_staging_solver = ConstraintSolver(
    color_remaps, staging_palettes, ColorRemapsIntoStagingPalettesEvaluator,
    None)
while (len(remap_to_staging_solver.solutions)
       == 0) and (remap_to_staging_solver.is_exhausted() == False):
    remap_to_staging_solver.update()

# TODO find the best one.
remap_to_staging_solution = remap_to_staging_solver.solutions[0]

for move in remap_to_staging_solution:
    # Let the corresponding color remap process these moves.
    source_remap = color_remaps[move.source_index]
    source_remap.remap_to_staging_palette(move, staging_palettes)

# Now apply the solution to the staging palettes.
remap_to_staging_solver.apply_solution(remap_to_staging_solution)
interval_enemy_sprite = Interval(begin=0, end=255, length=2)
interval_bg1 = Interval(begin=0, end=447, length=1)
interval_bg2 = Interval(begin=256, end=447, length=1)
interval_bg3 = Interval(begin=256, end=447, length=1)
intervals.append(interval_font)
intervals.append(interval_player_sprite)
intervals.append(interval_enemy_sprite)
intervals.append(interval_bg1)
intervals.append(interval_bg2)
intervals.append(interval_bg3)

bitsets = []
VRAMPositions = BitSet(448)
bitsets.append(VRAMPositions)

interval_to_VRAM_solver = ConstraintSolver(sources=intervals, destinations=bitsets, evaluator_class=IntervalsToBitSetsEvaluator, debugging=True)
while (len(interval_to_VRAM_solver.solutions) == 0) and (interval_to_VRAM_solver.is_exhausted() == False):
    interval_to_VRAM_solver.update()

# How'd the solution go?
solution = interval_to_VRAM_solver.solutions[0]
for move in solution:
    # The "source" will be one of our intervals, and since we're only doing one BitSet, our "destination" will always be the VRAMPositions array.
    # Dig into the change list to figure out which slot was actually chosen.
    source_interval = intervals[move.source_index]
    dest_interval = move.change_list.chosen_interval
    if dest_interval.begin == dest_interval.end:
        print(f"Interval {move.source_index}: ({source_interval.begin}, {source_interval.end}) with length {source_interval.length} will occupy location {dest_interval.begin}.")
    else:
        print(f"Interval {move.source_index}: ({source_interval.begin}, {source_interval.end}) with length {source_interval.length} will occupy locations {dest_interval.begin} thru {dest_interval.end}")
##############################################################################
# EXECUTE SOLVER

# THIS SOLUTION MAPS PIXELS INTO PIXELS VIA SPRITES
sources = []
for pixel_idx in range(len(pixel_list)):
    pixel_to_sprite_bitset = pixel_to_sprite_bitsets[pixel_idx]
    source = RasterPixelsToSpritesEvaluator.Source(
        pixel_to_potential_sprites_bitset=pixel_to_sprite_bitset,
        sprite_pixel_coverages=potential_sprite_pixel_coverage_bitsets)
    sources.append(source)

dest_pixel_bitset = BitSet(len(pixel_list))
solver = ConstraintSolver(sources=sources,
                          destinations=[dest_pixel_bitset],
                          evaluator_class=RasterPixelsToSpritesEvaluator,
                          debugging=None)

solution_count = 0
best_solutions = []
best_pixels_list = None
best_sprites_list = None
best_sprites_on_a_line = math.inf

# Solver will stop when it is either exhausted or finds this many solutions.
max_solutions = 250

while (len(solver.solutions) < max_solutions) and (solver.is_exhausted()
                                                   == False):
    solver.update()
# Treat the image as one large color remapping problem.  We'll divvy up into tiles later.
px_array = PixelArray(parent_image, 0, 0, parent_image.width,
                      parent_image.height)
px_array.quantize((8, 8, 8), (2, 2, 2))

# Extract all unique colors
unique_pixel_values_list = px_array.generate_deterministic_unique_pixel_list()

color_remap_font = ColorRemap({}, unique_pixel_values_list,
                              special_color_remap)
color_remaps.append(color_remap_font)

##############################################################################
# SOLUTION FOR COLOR REMAPS -> STAGING PALETTES
remap_to_staging_solver = ConstraintSolver(
    color_remaps, staging_palettes, ColorRemapsIntoStagingPalettesEvaluator,
    True)
while remap_to_staging_solver.is_exhausted() == False:
    remap_to_staging_solver.update()

# TODO find the best one.
remap_to_staging_solution = remap_to_staging_solver.solutions[0]

for move in remap_to_staging_solution:
    # Let the corresponding color remap process these moves.
    source_remap = color_remaps[move.source_index]
    source_remap.remap_to_staging_palette(move, staging_palettes)

# Now apply the solution to the staging palettes.
remap_to_staging_solver.apply_solution(remap_to_staging_solution)
                                             (0, 0, 255))
dest_blue_0.intentions.attempt_set_intention(ColorEntry.INTENTION_SLOT, 0)
dest_node_list.append(dest_blue_0)

dest_green = ColorEntry()
dest_green.intentions.attempt_set_intention(ColorEntry.INTENTION_COLOR,
                                            (0, 255, 0))
dest_node_list.append(dest_green)

dest_red = ColorEntry()
dest_red.intentions.attempt_set_intention(ColorEntry.INTENTION_COLOR,
                                          (255, 0, 0))
dest_node_list.append(dest_red)

dest_clear_1 = ColorEntry()
dest_node_list.append(dest_clear_1)

dest_clear_2 = ColorEntry()
dest_node_list.append(dest_clear_2)

# Start the solver.
solver = ConstraintSolver(source_node_list, dest_node_list,
                          ColorsIntoColorsEvaluator, True)

while False == solver.is_exhausted():
    solver.update()

solutions = solver.solutions

print(f"Found {len(solutions)} colors-into-colors solutions.")
Пример #7
0
pattern_intention_map_flips = {
    Pattern.INTENTION_FLIPS_ALLOWED: Pattern.Flip.HORIZ
}
for pixel_array in pixel_arrays:
    index_array = pixel_array.generate_indexed_color_array()
    pattern = Pattern(index_array=index_array,
                      initial_intentions_map=pattern_intention_map_flips)
    patterns.append(pattern)

##############################################################################
# PATTERN SOLVING
dest_map = {}
dest_maps = [dest_map]

solver = ConstraintSolver(sources=patterns,
                          destinations=dest_maps,
                          evaluator_class=PatternsIntoPatternHashMapsEvaluator,
                          debugging=None)
while ((len(solver.solutions) == 0) and (solver.is_exhausted() == False)):
    solver.update()

# How'd we do?
solution = solver.solutions[0]
solver.apply_solution(solution)

# Count uniques.
unique_patterns = []
for move in solution:
    matched = move.change_list.matching_pattern_object_ref
    if matched is None:
        # We didn't match anybody else, so we're unique.
        src_pattern_idx = move.source_index