def place_sure_bulbs(puzzle): not_changed = False count = 0 while not not_changed: removed = False for x in range(len(valid_wall)): value = puzzle[valid_wall[x][0]][valid_wall[x][1]] if count == 0: sure_variable = library.generate_valid_neighbours( valid_wall[x][0], valid_wall[x][1], len(puzzle), puzzle) else: sure_variable = library.generate_valid_neighbours( valid_wall[x][0], valid_wall[x][1], len(puzzle), puzzle, True) add = True counter = count_bulbs(puzzle, valid_wall[x]) if count > 0 and counter == int(value): add = False if int(value) >= len(sure_variable) + counter: for y in range(len(sure_variable)): if sure_variable[y] not in already_placed and add: already_placed.append(sure_variable[y]) for z in range(len(variables)): if variables[z][1] == sure_variable[y]: variables.remove(variables[z]) removed = True break count += 1 if not removed: not_changed = True place_bulbs(already_placed, [], "b", "_", "*") count = count
def find_most_constraining(puzzle, child_possible_variables): prioritize_by_wall_neighbours(puzzle) for cell in child_possible_variables: r = cell[1][0] c = cell[1][1] constraints = -1 num_lit = num_cells_lit(cell[1], "_") for var in variables: if var[1][0] == r and var[1][1] == c: constraints = var[0] break constraints += num_lit cell[0] = constraints for wall in valid_wall: possible_position = library.generate_valid_neighbours( wall[0], wall[1], len(puzzle), puzzle, True) if int(puzzle[wall[0]][wall[1]]) > count_bulbs(puzzle, wall): for poss in possible_position: for cell in child_possible_variables: if cell[1] == poss: cell[0] += 3 child_possible_variables.sort() max = child_possible_variables[-1][0] y = -1 for cell in child_possible_variables: if max == cell[0]: y += 1 chosen = random.randint(0, y) * -1 item_1 = child_possible_variables[-1] child_possible_variables[-1] = child_possible_variables[-1 + chosen] child_possible_variables[-1 + chosen] = item_1
def count_bulbs(puzzle, wall): counter = 0 sure_variable = library.generate_valid_neighbours(wall[0], wall[1], len(puzzle), puzzle) for x in sure_variable: if puzzle[x[0]][x[1]] == "b": counter += 1 return counter
def remove_zero_wall_neighbours(puzzle: List[List[str]], empty_cells: List[List[int]]): invalid_neighbours = [] # remove all neighbours of a zero wall for x in range(len(library.invalid_wall)): invalid_neighbours.extend(library.generate_valid_neighbours(library.invalid_wall[x][0], library.invalid_wall[x][1], len(puzzle), puzzle)) for x in range(len(invalid_neighbours)): if invalid_neighbours[x] in empty_cells: empty_cells.remove(invalid_neighbours[x])
def remove_zero_wall_neighbours(puzzle): invalid_neighbours = [] for x in range(len(invalid_wall)): invalid_neighbours.extend( library.generate_valid_neighbours(invalid_wall[x][0], invalid_wall[x][1], len(puzzle), puzzle)) for x in range(len(invalid_neighbours)): for y in range(len(variables)): if variables[y][1] == invalid_neighbours[x]: variables.remove(variables[y]) break
def valid_bulbs_next_to_wall(puzzle): for x in range(len(valid_wall)): num_of_bulbs = int(puzzle[valid_wall[x][0]][valid_wall[x][1]]) valid_neighbour = library.generate_valid_neighbours( valid_wall[x][0], valid_wall[x][1], len(puzzle), puzzle) seen_bulbs = 0 for z in range(len(valid_neighbour)): if puzzle[valid_neighbour[z][0]][valid_neighbour[z][1]] == "b": seen_bulbs += 1 if num_of_bulbs != seen_bulbs: return False return True
def remove_completed_wall(puzzle): completed_walls = [] for x in range(len(valid_wall)): if count_bulbs(puzzle, valid_wall[x]) == int( puzzle[valid_wall[x][0]][valid_wall[x][1]]): completed_walls.append(valid_wall[x]) valid_neighbours_a = library.generate_valid_neighbours( valid_wall[x][0], valid_wall[x][1], len(puzzle), puzzle) for var in valid_neighbours_a: for cells in variables: if cells[1] == var: variables.remove(cells) for wall in completed_walls: valid_wall.remove(wall)
def prioritize_by_wall_neighbours(puzzle): for x in variables: x[0] = 0 for x in range(len(valid_wall)): valid_neighbours = library.generate_valid_neighbours( valid_wall[x][0], valid_wall[x][1], len(puzzle), puzzle) # if the wall is not completed all the neighbour around it would be prioritized if int(puzzle[valid_wall[x][0]][valid_wall[x][1]]) != count_bulbs( puzzle, valid_wall[x]): for z in range(len(valid_neighbours)): for a in range(len(variables)): if variables[a][1] == valid_neighbours[z]: variables[a][0] += 1 break # if the wall has already been completed neidgbour else: if heuristic == 'most_constraining' or heuristic == 'hybrid': for z in range(len(valid_neighbours)): for a in range(len(variables)): if variables[a][1] == valid_neighbours[z]: variables[a][0] -= 2 break
def place_must_have_bulbs(puzzle: List[List[str]], empty_cells: List[List[int]]) -> List[List[int]]: stop = False while not stop: new_bulb_placed = False for wall in library.valid_wall: sure_variable = library.generate_valid_neighbours(wall[0], wall[1], len(puzzle), puzzle) count_bulbs = 0 count_empty_cells = 0 count_stars = 0 for var in sure_variable: if puzzle[var[0]][var[1]] == 'b': count_bulbs += 1 elif puzzle[var[0]][var[1]] == '_': count_empty_cells += 1 elif puzzle[var[0]][var[1]] == '*': count_stars += 1 # if the amount of empty neighbours of a wall is exactly the same as its number, place bulbs if count_empty_cells > 0 and count_empty_cells == int(puzzle[wall[0]][wall[1]]) - count_bulbs: for var in sure_variable: if puzzle[var[0]][var[1]] == '_': puzzle[var[0]][var[1]] = 'b' empty_cells.remove(var) new_bulb_placed = True light_map_up(puzzle) if not new_bulb_placed: stop = True # remove already lit up cells from the list of potential cells to place a bulb variables = copy.deepcopy(empty_cells) for cell in variables: if puzzle[cell[0]][cell[1]] == '*': empty_cells.remove(cell) return empty_cells