Package horizons :: Package ai :: Package aiplayer :: Module villagebuilder :: Class VillageBuilder
[hide private]
[frames] | no frames]

Class VillageBuilder

source code

util.changelistener.ChangeListener --+        
                                     |        
          util.worldobject.WorldObject --+    
                                         |    
                   areabuilder.AreaBuilder --+
                                             |
                                            VillageBuilder


An object of this class manages the village area of a settlement.

Important attributes:
* plan: a dictionary of the form {(x, y): (purpose, (section, seq_no)), ...} where
        purpose is one of the BUILDING_PURPOSE constants, section is the sequence number
        of the village section and seq_no is the sequence number of a residence or None
        if it is another type of building. The plan is created in the beginning and
        changed only when land is lost.
* special_building_assignments: {BUILDING_PURPOSE constant: {village producer coordinates: [residence coordinates, ...]}}
* tent_queue: deque([(x, y), ...]) of remaining residence spots in the right order
* num_sections: number of sections in the area
* current_section: 1-based number of the section that is being filled with residences
* roads_built: boolean showing whether all planned roads in the area have been built

Instance Methods [hide private]
 
__init__(self, settlement_manager) source code
 
__init(self, settlement_manager) source code
 
save(self, db) source code
 
_load(self, db, settlement_manager) source code
 
_get_village_section_coordinates(self, start_x, start_y, width, height)
Return set([(x, y), ...]) of usable coordinates in the rectangle defined by the parameters.
source code
 
_create_plan(self)
Create the area plan.
source code
 
_stitch_sections_together(self, section_plans, vertical_roads, horizontal_roads)
Complete creating the plan by stitching the sections together and creating the tent queue.
source code
 
_get_possible_building_positions(self, section_coords_set, size)
Return {(x, y): Rect, ...
source code
 
_create_section_plan(self, section_coords_set, vertical_roads, horizontal_roads)
Create the section plan that contains the main square, roads, and residence positions.
source code
 
_optimize_section_plan(self, section_plan)
Try to fit more residences into the grid.
source code
 
_return_unused_space(self)
Return the area that remains unused after creating the plan.
source code
 
_get_sorted_building_positions(self, building_purpose)
Return a list of sorted building positions in the form [Rect, ...].
source code
 
_replace_planned_residence(self, new_purpose, max_buildings, capacity)
Replace up to max_buildings residence spots with buildings of purpose new_purpose.
source code
 
_reserve_special_village_building_spots(self)
Replace residence spots with special village buildings such as pavilions, schools, taverns, doctors and fire stations.
source code
 
_create_special_village_building_assignments(self)
Create an assignment of residence spots to special village building spots.
source code
 
_create_tent_queue(self, section_plan)
Place the residences of a section in a visually appealing order; save the result in the tent queue.
source code
 
_recreate_tent_queue(self, removal_location=None)
Recreate the tent queue making sure that the possibly removed location is missing.
source code
 
build_roads(self)
Try to build all roads in the village area, record the result in the field roads_built.
source code
 
build_tent(self, coords=None)
Build the next tent (or the specified one if coords is not None).
source code
 
handle_lost_area(self, coords_list)
Handle losing the potential land in the given coordinates list.
source code
 
remove_building(self, building)
Called when a building is removed from the area (the building still exists during the call).
source code
 
display(self)
Show the plan on the map unless it is disabled in the settings.
source code
 
__str__(self) source code
    Inherited from areabuilder.AreaBuilder
 
_get_road_to_builder(self, builder)
Return a path from the builder to a building with general collectors (None if impossible).
source code
 
_init_cache(self)
Initialize the cache that knows the last time the buildability of a rectangle may have changed in this area.
source code
 
add_building(self, building)
Called when a new building is added in the area (the building already exists during the call).
source code
 
build_best_option(self, options, purpose)
Try to build the highest valued option.
source code
 
build_road(self, path)
Build the road given a valid path or None.
source code
 
build_road_connection(self, builder)
Build a road connecting the builder to a building with general collectors.
source code
 
extend_settlement(self, position)
Build a storage to extend the settlement towards the given position.
source code
 
get_path_nodes(self)
Return a dict {(x, y): penalty, ...
source code
 
get_road_connection_cost(self, builder)
Return the cost of building a road from the builder to a building with general collectors.
source code
 
get_road_cost(self, path)
Return the cost of building a road on the given path as {resource_id: amount, ...
source code
 
have_resources(self, building_id)
Return a boolean showing whether we currently have the resources to build a building of the given type.
source code
 
iter_neighbor_tiles(self, rect)
Iterate over the tiles that share a side with the given Rect.
source code
 
iter_possible_road_coords(self, rect, blocked_rect)
Iterate over the possible road tiles that share a side with the given Rect and are not in the blocked Rect.
source code
 
register_change(self, x, y, purpose, data)
Register the (potential) change of the purpose of land at the given coordinates.
source code
 
register_change_list(self, coords_list, purpose, data) source code
    Inherited from util.worldobject.WorldObject
 
__lt__(self, other) source code
 
remove(self) source code
    Inherited from util.changelistener.ChangeListener
 
_changed(self)
Calls every listener when an object changed
source code
 
add_change_listener(self, listener, call_listener_now=False, no_duplicates=False) source code
 
add_remove_listener(self, listener, no_duplicates=False)
A listener that listens for removal of the object
source code
 
clear_change_listeners(self)
Removes all change listeners
source code
 
discard_change_listener(self, listener)
Remove listener if it's there
source code
 
discard_remove_listener(self, listener) source code
 
end(self) source code
 
has_change_listener(self, listener) source code
 
has_remove_listener(self, listener) source code
 
remove_change_listener(self, listener) source code
 
remove_remove_listener(self, listener) source code
Class Methods [hide private]
 
_remove_unreachable_roads(cls, section_plan, main_square)
Remove the roads that can't be reached by starting from the main square.
source code
 
_get_position(cls, coords, building_id)
Return the position Rect of a building of the given type at the given position.
source code
    Inherited from areabuilder.AreaBuilder
 
load(cls, db, settlement_manager) source code
    Inherited from util.worldobject.WorldObject
 
get_object_by_id(cls, id)
Returns the worldobject with id id Throws WorldObjectNotFound with the worldid as arg.
source code
 
get_objs(cls) source code
 
reset(cls) source code
Class Variables [hide private]
  log = logging.getLogger("ai.aiplayer")
Method Details [hide private]

__init__(self, settlement_manager)
(Constructor)

source code 
Parameters:
  • worldid - worldid to assign. Use None to get an autogenerated one.
Overrides: util.changelistener.ChangeListener.__init__

save(self, db)

source code 
Overrides: util.worldobject.WorldObject.save

_load(self, db, settlement_manager)

source code 
Overrides: areabuilder.AreaBuilder._load

_create_plan(self)

source code 

Create the area plan.

The algorithm:
* find a way to cut the village area into rectangular section_plans
* each section gets a plan with a main square, roads, and residence locations
* the plan is stitched together and other village buildings are by replacing some
        of the residences

_stitch_sections_together(self, section_plans, vertical_roads, horizontal_roads)

source code 

Complete creating the plan by stitching the sections together and creating the tent queue.

Parameters:
  • section_plans - list of section plans in the format [{(x, y): BUILDING_PURPOSE constant, ...}, ...]
  • vertical_roads - vertical roads between the sections in the form set([x, ...])
  • horizontal_roads - horizontal roads between the sections in the form set([y, ...])

_remove_unreachable_roads(cls, section_plan, main_square)
Class Method

source code 

Remove the roads that can't be reached by starting from the main square.

Parameters:
  • section_plan - {(x, y): BUILDING_PURPOSE constant, ...}
  • main_square - Rect representing the position of the main square

_get_possible_building_positions(self, section_coords_set, size)

source code 

Return {(x, y): Rect, ...} that contains every size x size potential building location where only the provided coordinates are legal.

_create_section_plan(self, section_coords_set, vertical_roads, horizontal_roads)

source code 

Create the section plan that contains the main square, roads, and residence positions.

The algorithm is as follows:
* place the main square
* form a road grid to support the tents
* choose the best one by preferring the one with more residence locations and less
        unreachable / blocked / parallel side by side roads.

@param section_plans: list of section plans in the format [{(x, y): BUILDING_PURPOSE constant, ...}, ...]
@param vertical_roads: vertical roads between the sections in the form set([x, ...])
@param horizontal_roads: horizontal roads between the sections in the form set([y, ...])
@return: (number of residences in the plan, the plan in the form {(x, y): BUILDING_PURPOSE constant}

_replace_planned_residence(self, new_purpose, max_buildings, capacity)

source code 

Replace up to max_buildings residence spots with buildings of purpose new_purpose.

This function is used to amend the existing plan with village producers such as pavilions, schools, and taverns. The goal is to place as few of them as needed while still covering the maximum number of residences.

Parameters:
  • new_purpose - the BUILDING_PURPOSE constant of the new buildings
  • max_buildings - maximum number of residences to replace
  • capacity - maximum number of residences one of the new buildings can service

_create_special_village_building_assignments(self)

source code 

Create an assignment of residence spots to special village building spots.

This is useful for deciding which of the special village buildings would be most useful.

_create_tent_queue(self, section_plan)

source code 

Place the residences of a section in a visually appealing order; save the result in the tent queue.

The algorithm:
* split the residences of the section into blocks where a block is formed of all
        residence spots that share sides
* calculate the distance from the main square to the block
* form the final sequence by sorting the blocks by distance to the main square and
        by sorting the residences of a block by their coordinates

@return: {(x, y): residence sequence number}

handle_lost_area(self, coords_list)

source code 

Handle losing the potential land in the given coordinates list.

Take the following actions: * remove the lost area from the village and road areas * remove village sections with impossible main squares * remove all planned buildings that are now impossible * TODO: if the village area takes too much of the total area then remove / reduce the remaining sections

Overrides: areabuilder.AreaBuilder.handle_lost_area

remove_building(self, building)

source code 

Called when a building is removed from the area (the building still exists during the call).

Overrides: areabuilder.AreaBuilder.remove_building

display(self)

source code 

Show the plan on the map unless it is disabled in the settings.

Overrides: areabuilder.AreaBuilder.display