added useful functions to json_generator.py; code refactoring
This commit is contained in:
parent
7b87cb71ed
commit
a4bc74d5f2
@ -1,18 +1,15 @@
|
|||||||
import json
|
import json
|
||||||
import random
|
import random
|
||||||
|
|
||||||
import project_constants as const
|
import project_constants as const
|
||||||
|
|
||||||
|
# import tile class
|
||||||
|
import tile as tl
|
||||||
|
|
||||||
# auxiliary function that returns random attribute values based on their type
|
# import mine models
|
||||||
def _get_random_attribute_values(self, attr_type, grid_dimensions):
|
import mine_models.standard_mine as sm
|
||||||
num_of_rows, num_of_columns = grid_dimensions
|
import mine_models.time_mine as tm
|
||||||
|
import mine_models.chained_mine as cm
|
||||||
if attr_type == int:
|
|
||||||
# temporary solution
|
|
||||||
return random.randint(num_of_rows + num_of_columns, (2 * num_of_rows + num_of_columns))
|
|
||||||
|
|
||||||
else:
|
|
||||||
return None
|
|
||||||
|
|
||||||
|
|
||||||
class JsonGenerator:
|
class JsonGenerator:
|
||||||
@ -24,12 +21,9 @@ class JsonGenerator:
|
|||||||
self.agents_initial_position = agents_initial_position
|
self.agents_initial_position = agents_initial_position
|
||||||
self.agents_initial_direction = agents_initial_direction
|
self.agents_initial_direction = agents_initial_direction
|
||||||
|
|
||||||
# getting position coordinates
|
|
||||||
starting_row, starting_column = agents_initial_position
|
|
||||||
|
|
||||||
# saving data to the grid dictionary
|
# saving data to the grid dictionary
|
||||||
self.grid["agents_initial_state"] = {
|
self.grid["agents_initial_state"] = {
|
||||||
"position": str(starting_row) + ',' + str(starting_column),
|
"position": format_position_to_str(agents_initial_position),
|
||||||
"direction": agents_initial_direction
|
"direction": agents_initial_direction
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -39,19 +33,16 @@ class JsonGenerator:
|
|||||||
self.agents_initial_position = position
|
self.agents_initial_position = position
|
||||||
self.agents_initial_direction = direction
|
self.agents_initial_direction = direction
|
||||||
|
|
||||||
# getting position coordinates
|
|
||||||
starting_row, starting_column = position
|
|
||||||
|
|
||||||
# setting new agent's initial state
|
# setting new agent's initial state
|
||||||
self.grid["agents_initial_state"] = {
|
self.grid["agents_initial_state"] = {
|
||||||
"position": str(starting_row) + ',' + str(starting_column),
|
"position": format_position_to_str(position),
|
||||||
"direction": direction
|
"direction": direction
|
||||||
}
|
}
|
||||||
|
|
||||||
# overwrites grid field with a new grid with randomized colors and mines
|
# overwrites grid field with a new grid with randomized colors and mines
|
||||||
def generate_randomized_grid(self, dimensions, mine_appearance_chance=0.15, predecessor_chance_decrease=0.25):
|
def generate_randomized_grid(self, dimensions, mine_appearance_chance=0.15, predecessor_chance_decrease=0.25):
|
||||||
# clearing grid field
|
# clearing grid field
|
||||||
self.clear_tile_dictionary()
|
self.clear_grid()
|
||||||
|
|
||||||
# getting grid dimensions
|
# getting grid dimensions
|
||||||
num_of_rows, num_of_columns = dimensions
|
num_of_rows, num_of_columns = dimensions
|
||||||
@ -60,6 +51,7 @@ class JsonGenerator:
|
|||||||
|
|
||||||
for i in range(num_of_rows):
|
for i in range(num_of_rows):
|
||||||
for j in range(num_of_columns):
|
for j in range(num_of_columns):
|
||||||
|
|
||||||
# picking random values for tiles
|
# picking random values for tiles
|
||||||
random_tile_color = random.choice(const.STRUCT_TILE_COLORS)
|
random_tile_color = random.choice(const.STRUCT_TILE_COLORS)
|
||||||
|
|
||||||
@ -86,7 +78,7 @@ class JsonGenerator:
|
|||||||
random_attribute_values = []
|
random_attribute_values = []
|
||||||
|
|
||||||
for attr_type in const.STRUCT_MINE_ATTRIBUTE_TYPES[random_mine_type]:
|
for attr_type in const.STRUCT_MINE_ATTRIBUTE_TYPES[random_mine_type]:
|
||||||
random_attribute_values.append(_get_random_attribute_values(self, attr_type, dimensions))
|
random_attribute_values.append(_get_random_attribute_values(attr_type, dimensions))
|
||||||
|
|
||||||
# adding the mine
|
# adding the mine
|
||||||
self.set_a_mine((i, j), random_mine_type, random_attribute_values)
|
self.set_a_mine((i, j), random_mine_type, random_attribute_values)
|
||||||
@ -94,15 +86,14 @@ class JsonGenerator:
|
|||||||
# if is ChainedMine create predecessors
|
# if is ChainedMine create predecessors
|
||||||
if random_mine_type == "chained":
|
if random_mine_type == "chained":
|
||||||
predecessor_appearance_chance = 1.0
|
predecessor_appearance_chance = 1.0
|
||||||
current_tile = str(i) + ',' + str(j)
|
current_tile = format_position_to_str((i, j))
|
||||||
|
|
||||||
# create chained predecessors
|
# create chained predecessors
|
||||||
while random.random() < predecessor_appearance_chance and len(tile_pool) > 0:
|
while random.random() < predecessor_appearance_chance and len(tile_pool) > 0:
|
||||||
predecessor_appearance_chance -= predecessor_chance_decrease
|
predecessor_appearance_chance -= predecessor_chance_decrease
|
||||||
|
|
||||||
predecessor_position = random.choice(tile_pool)
|
predecessor_position = random.choice(tile_pool)
|
||||||
pre_row, pre_column = predecessor_position
|
predecessor = format_position_to_str(predecessor_position)
|
||||||
predecessor = str(pre_row) + ',' + str(pre_column)
|
|
||||||
tile_pool.remove(predecessor_position)
|
tile_pool.remove(predecessor_position)
|
||||||
|
|
||||||
self.set_a_mine(predecessor_position, "chained", [])
|
self.set_a_mine(predecessor_position, "chained", [])
|
||||||
@ -114,19 +105,14 @@ class JsonGenerator:
|
|||||||
|
|
||||||
# adds a new tile or edits an existing one in the grid field
|
# adds a new tile or edits an existing one in the grid field
|
||||||
def add_tile(self, position, color):
|
def add_tile(self, position, color):
|
||||||
# getting added/edited tile's index values
|
|
||||||
row, column = position
|
|
||||||
|
|
||||||
# creating new tile without a mine
|
# creating new tile without a mine
|
||||||
self.grid[str(row) + ',' + str(column)] = {
|
self.grid[format_position_to_str(position)] = {
|
||||||
"color": color,
|
"color": color,
|
||||||
"mine": None
|
"mine": None
|
||||||
}
|
}
|
||||||
|
|
||||||
# adds a new tile with a mine or edits an existing one in the grid field
|
# 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):
|
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
|
# setting mine data using attribute_values
|
||||||
mine_values = const.STRUCT_MINE_ATTRIBUTES[mine_type]
|
mine_values = const.STRUCT_MINE_ATTRIBUTES[mine_type]
|
||||||
|
|
||||||
@ -135,29 +121,23 @@ class JsonGenerator:
|
|||||||
mine_values[key] = attribute_values.pop(0)
|
mine_values[key] = attribute_values.pop(0)
|
||||||
|
|
||||||
# creating a new tile
|
# creating a new tile
|
||||||
self.grid[str(row) + ',' + str(column)] = {
|
self.grid[format_position_to_str(position)] = {
|
||||||
"color": color
|
"color": color
|
||||||
}
|
}
|
||||||
|
|
||||||
# updating the tile with a mine field
|
# updating the tile with a mine field
|
||||||
self.grid[str(row) + ',' + str(column)]["mine"] = {}
|
self.grid[format_position_to_str(position)]["mine"] = {}
|
||||||
|
|
||||||
for key in mine_values.keys():
|
for key in mine_values.keys():
|
||||||
self.grid[str(row) + ',' + str(column)]["mine"][key] = mine_values[key]
|
self.grid[format_position_to_str()]["mine"][key] = mine_values[key]
|
||||||
|
|
||||||
# deletes a mine with a given position from the grid field
|
# deletes a mine with a given position from the grid field
|
||||||
def delete_a_tile(self, position):
|
def delete_a_tile(self, position):
|
||||||
# getting tile's index values
|
|
||||||
row, column = position
|
|
||||||
|
|
||||||
# deleting a tile with given key
|
# deleting a tile with given key
|
||||||
self.grid.pop(str(row) + ',' + str(column))
|
self.grid.pop(format_position_to_str(position))
|
||||||
|
|
||||||
# adds a mine to a tile stored in the grid field
|
# adds a mine to a tile stored in the grid field
|
||||||
def set_a_mine(self, position, mine_type, attribute_values):
|
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
|
# setting mine data using attribute_values
|
||||||
mine_values = const.STRUCT_MINE_ATTRIBUTES[mine_type]
|
mine_values = const.STRUCT_MINE_ATTRIBUTES[mine_type]
|
||||||
|
|
||||||
@ -166,34 +146,36 @@ class JsonGenerator:
|
|||||||
mine_values[key] = attribute_values.pop(0)
|
mine_values[key] = attribute_values.pop(0)
|
||||||
|
|
||||||
# adding a mine to the edited tile
|
# adding a mine to the edited tile
|
||||||
self.grid[str(row) + ',' + str(column)]["mine"] = {}
|
self.grid[format_position_to_str(position)]["mine"] = {}
|
||||||
|
|
||||||
for key in mine_values.keys():
|
for key in mine_values.keys():
|
||||||
self.grid[str(row) + ',' + str(column)]["mine"][key] = mine_values[key]
|
self.grid[format_position_to_str(position)]["mine"][key] = mine_values[key]
|
||||||
|
|
||||||
# deletes a mine from a tile stored in the grid field
|
# deletes a mine from a tile stored in the grid field
|
||||||
def delete_a_mine(self, position):
|
def delete_a_mine(self, position):
|
||||||
# getting edited tile's index values
|
|
||||||
row, column = position
|
|
||||||
|
|
||||||
# removing mine from the edited tile
|
# removing mine from the edited tile
|
||||||
self.grid[str(row) + ',' + str(column)]["mine"] = None
|
self.grid[format_position_to_str(position)]["mine"] = None
|
||||||
|
|
||||||
|
# returns chosen tiles data
|
||||||
|
def get_tile(self, position):
|
||||||
|
return self.grid[format_position_to_str(position)]
|
||||||
|
|
||||||
|
# returns chosen mines data
|
||||||
|
def get_mine(self, position):
|
||||||
|
return self.grid[format_position_to_str(position)]["mine"]
|
||||||
|
|
||||||
# returns the grid field
|
# returns the grid field
|
||||||
def get_tile_dictionary(self):
|
def get_grid(self):
|
||||||
return self.grid
|
return self.grid
|
||||||
|
|
||||||
# clears the grid field
|
# clears the grid field
|
||||||
def clear_tile_dictionary(self):
|
def clear_grid(self):
|
||||||
# clearing grid dict
|
# clearing grid dict
|
||||||
self.grid.clear()
|
self.grid.clear()
|
||||||
|
|
||||||
# getting agent's starting position coordinates
|
|
||||||
starting_row, starting_column = self.agents_initial_position
|
|
||||||
|
|
||||||
# re-setting the agent's initial state
|
# re-setting the agent's initial state
|
||||||
self.grid["agents_initial_state"] = {
|
self.grid["agents_initial_state"] = {
|
||||||
"position": str(starting_row) + ',' + str(starting_column),
|
"position": format_position_to_str(self.agents_initial_position),
|
||||||
"direction": self.agents_initial_direction
|
"direction": self.agents_initial_direction
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -226,3 +208,118 @@ class JsonGenerator:
|
|||||||
with open(file_path, "w") as output_file:
|
with open(file_path, "w") as output_file:
|
||||||
# saving the newly created grid
|
# saving the newly created grid
|
||||||
json.dump(new_grid, output_file, indent=2, sort_keys=True)
|
json.dump(new_grid, output_file, indent=2, sort_keys=True)
|
||||||
|
|
||||||
|
|
||||||
|
# STATIC "PUBLIC" FUNCTIONS
|
||||||
|
|
||||||
|
# creates a Mine (Standard or Time or Chained) instance from mine dict data
|
||||||
|
# doesn't link chained mines, since it has no actual access to a grid
|
||||||
|
def create_a_mine(mine_dict, position):
|
||||||
|
# initializing a mine with no value
|
||||||
|
mine = None
|
||||||
|
|
||||||
|
# if mine doesn't exist - returning None
|
||||||
|
if mine_dict is None:
|
||||||
|
return mine
|
||||||
|
|
||||||
|
# formatting position to right format - in case it's not
|
||||||
|
position = format_position_to_tuple(position)
|
||||||
|
|
||||||
|
# if mine's type is "standard" - creating standard mine
|
||||||
|
if mine_dict["mine_type"] == "standard":
|
||||||
|
mine = sm.StandardMine(position)
|
||||||
|
|
||||||
|
# if mine's type is "time" - creating time mine
|
||||||
|
elif mine_dict["mine_type"] == "time":
|
||||||
|
timer_value = mine_dict["timer"]
|
||||||
|
mine = tm.TimeMine(position, timer_value)
|
||||||
|
|
||||||
|
# if mine's type is "chained" - creating chained mine (no successors assigned yet)
|
||||||
|
elif mine_dict["mine_type"] == "chained":
|
||||||
|
mine = cm.ChainedMine(position)
|
||||||
|
|
||||||
|
return mine
|
||||||
|
|
||||||
|
|
||||||
|
# creates a Tile instance with a mine (if a mine exists) from tile dict data
|
||||||
|
def create_a_tile(tile_dict, position):
|
||||||
|
# formatting position to right format - in case it's not
|
||||||
|
position = format_position_to_tuple(position)
|
||||||
|
|
||||||
|
# getting tile's parameters
|
||||||
|
color = tile_dict["color"]
|
||||||
|
mine = create_a_mine(position, tile_dict["mine"])
|
||||||
|
|
||||||
|
# creating and returning a tile with the parameters set above
|
||||||
|
return tl.Tile(position, color, mine)
|
||||||
|
|
||||||
|
|
||||||
|
# returns a list of tuples containing chained mine's position and it's predecessors position
|
||||||
|
# data is in format [(chained_mine_position, its_predecessors_position), ...]
|
||||||
|
def get_chained_mine_and_its_predecessor_pairs(minefield_dictionary):
|
||||||
|
predecessors = list()
|
||||||
|
|
||||||
|
# iterate for each key in the grid field
|
||||||
|
for key in minefield_dictionary.keys():
|
||||||
|
# if a chained mine with predecessor exists - adding it's and it's predecessors positions as a tuple to a list
|
||||||
|
if key != "agents_initial_state" and minefield_dictionary[key]["mine"] is not None\
|
||||||
|
and minefield_dictionary[key]["mine"]["mine_type"] == "chained"\
|
||||||
|
and minefield_dictionary[key]["mine"]["predecessor"] is not None:
|
||||||
|
|
||||||
|
# getting the chained mines and it's predecessors positions
|
||||||
|
this_mines_position = tuple(int(i) for i in key.split(','))
|
||||||
|
its_predecessors_position = tuple(int(i) for i in minefield_dictionary[key]["mine"]["predecessor"].split(','))
|
||||||
|
|
||||||
|
# adding the positions to the list as a tuple
|
||||||
|
predecessors.append((this_mines_position, its_predecessors_position))
|
||||||
|
|
||||||
|
return predecessors
|
||||||
|
|
||||||
|
|
||||||
|
# changes position from str or tuple format to str format
|
||||||
|
def format_position_to_str(position):
|
||||||
|
# if mine's position is in "row,column" format - that means position parameter is already in good format
|
||||||
|
if isinstance(position, str):
|
||||||
|
pass
|
||||||
|
|
||||||
|
# if mine's position is in (row:int, column:int) - creating string from tuple
|
||||||
|
elif isinstance(position, tuple) and list(map(type, position)) == [int, int]:
|
||||||
|
row, column = position
|
||||||
|
return str(row) + ',' + str(column)
|
||||||
|
|
||||||
|
# if mine's position is not in any of 2 formats above - returning None - unsupported format
|
||||||
|
else:
|
||||||
|
return None
|
||||||
|
|
||||||
|
return position
|
||||||
|
|
||||||
|
|
||||||
|
# changes position from str or tuple format to tuple format
|
||||||
|
def format_position_to_tuple(position):
|
||||||
|
# if mine's position is in "row,column" format - getting parameters from string
|
||||||
|
if isinstance(position, str):
|
||||||
|
position = tuple(int(i) for i in position.split(','))
|
||||||
|
|
||||||
|
# if mine's position is in (row:int, column:int) - that means position parameter is already in good format
|
||||||
|
elif isinstance(position, tuple) and list(map(type, position)) == [int, int]:
|
||||||
|
pass
|
||||||
|
|
||||||
|
# if mine's position is not in any of 2 formats above - returning None - unsupported format
|
||||||
|
else:
|
||||||
|
return None
|
||||||
|
|
||||||
|
return position
|
||||||
|
|
||||||
|
|
||||||
|
# AUXILIARY "PRIVATE" FUNCTIONS
|
||||||
|
|
||||||
|
# auxiliary function that returns random attribute values based on their type
|
||||||
|
def _get_random_attribute_values(attr_type, grid_dimensions):
|
||||||
|
num_of_rows, num_of_columns = grid_dimensions
|
||||||
|
|
||||||
|
if attr_type == int:
|
||||||
|
# temporary solution
|
||||||
|
return random.randint(num_of_rows + num_of_columns, (2 * num_of_rows + num_of_columns))
|
||||||
|
|
||||||
|
else:
|
||||||
|
return None
|
||||||
|
Loading…
Reference in New Issue
Block a user