import json import random import project_constants as const class JsonGenerator: grid = dict() def __init__(self, agent_starting_position): self.agent_starting_position = agent_starting_position starting_row, starting_column = agent_starting_position self.grid["agent_starting_position"] = str(starting_row) + ',' + str(starting_column) # sets agent's starting position def set_agent_starting_position(self, position): # getting position coordinates starting_row, starting_column = position # setting new agent's starting position self.grid["agent_starting_position"] = str(starting_row) + ',' + str(starting_column) # overwrites grid field with a new grid with randomized colors and mines def generate_randomized_grid(self, dimensions): # clearing grid field self.clear_tile_dictionary() # getting grid dimensions num_of_rows, num_of_columns = dimensions for i in range(num_of_rows): for j in range(num_of_columns): # picking random values for tiles random_tile_color = random.choice(const.STRUCT_TILE_COLORS) random_mine_type = random.choice(const.STRUCT_MINE_TYPES) # randomly checking if a mine should appear if random.random() < 0.75: # creating a tile without a mine self.add_tile((i, j), random_tile_color) else: # picking random mine attribute values random_attribute_values = [] for attr_type in const.STRUCT_MINE_ATTRIBUTE_TYPES[random_mine_type]: if attr_type == int: min_value, max_value = (num_of_columns + num_of_rows) / 2, 2 *(num_of_columns + num_of_rows) random_value = random.randint(min_value, max_value) random_attribute_values.append(random_value) elif attr_type == (int, int): if i > 0: rand_i = random.randint(0, (i - 1)) rand_j = random.randint(0, (num_of_columns - 1)) random_attribute_values.append(str(rand_i) + ',' + str(rand_j)) self.set_a_mine((rand_i, rand_j), "chained", [None]) elif j > 0: rand_i = 0 rand_j = random.randint(0, (j - 1)) random_attribute_values.append(str(rand_i) + ',' + str(rand_j)) self.set_a_mine((rand_i, rand_j), "chained", [None]) else: random_attribute_values.append(None) # creating a tile with a mine self.add_tile_with_a_mine( (i, j), random_tile_color, random_mine_type, random_attribute_values) # adds a new tile or edits an existing one in the grid field def add_tile(self, position, color): # getting added/edited tile's index values row, column = position # creating new tile without a mine self.grid[str(row) + ',' + str(column)] = { "color": color, "mine": None } # adds a new tile with a mine or edits an existing one in the grid field def add_tile_with_a_mine(self, position, color, mine_type, attribute_values): # getting added/edited tile's index values row, column = position # setting mine data using attribute_values mine_values = const.STRUCT_MINE_ATTRIBUTES[mine_type] for key in mine_values.keys(): if key not in const.HARDCODED_VALUES and len(attribute_values) > 0: mine_values[key] = attribute_values.pop(0) # creating a new tile self.grid[str(row) + ',' + str(column)] = { "color": color } # updating the tile with a mine field self.grid[str(row) + ',' + str(column)]["mine"] = {} for key in mine_values.keys(): self.grid[str(row) + ',' + str(column)]["mine"][key] = mine_values[key] # deletes a mine with a given position from the grid field def delete_a_tile(self, position): # getting tile's index values row, column = position # deleting a tile with given key self.grid.pop(str(row) + ',' + str(column)) # adds a mine to a tile stored in the grid field def set_a_mine(self, position, mine_type, attribute_values): # getting edited tile's index values row, column = position # setting mine data using attribute_values mine_values = const.STRUCT_MINE_ATTRIBUTES[mine_type] for key in mine_values.keys(): if key not in const.HARDCODED_VALUES and len(attribute_values) > 0: mine_values[key] = attribute_values.pop(0) # adding a mine to the edited tile self.grid[str(row) + ',' + str(column)]["mine"] = {} for key in mine_values.keys(): self.grid[str(row) + ',' + str(column)]["mine"][key] = mine_values[key] # deletes a mine from a tile stored in the grid field def delete_a_mine(self, position): # getting edited tile's index values row, column = position # removing mine from the edited tile self.grid[str(row) + ',' + str(column)]["mine"] = None # returns the grid field def get_tile_dictionary(self): return self.grid # clears the grid field def clear_tile_dictionary(self): # clearing grid dict self.grid.clear() # resetting agents starting position starting_row, starting_column = self.agent_starting_position self.grid["agent_starting_position"] = str(starting_row) + ',' + str(starting_column) # loads a grid from a file and overwrites the grid field def load_from_a_file(self, file_path): # opening a file for reading with open(file_path, 'r') as input_file: # overwriting the grid field with the grid stored in a file self.grid = json.load(input_file) # saves the current grid field to a file def save_to_a_file(self, file_path, access_mode): # opening a file with a given access mode (w - write / a - append) with open(file_path, access_mode) as output_file: # saving the grid to the file json.dump(self.grid, output_file, indent=2, sort_keys=True) # edits a grid in a file. doesn't delete data, only overwrites and adds new entries def edit_a_file(self, file_path): # opening a file for reading with open(file_path, "r") as input_file: # loading data that was stored in the file previously previous_data = json.load(input_file) # creating and updating a new grid using it's own grid field new_grid = previous_data new_grid.update(self.grid) # opening the file for writing with open(file_path, "w") as output_file: # saving the newly created grid json.dump(new_grid, output_file, indent=2, sort_keys=True)