def _initialize_locations(current_gameboard, game_schema):
    location_objects = dict() # key is a location name, and value is a Location object
    railroad_positions = list() # list of integers, with each integer corresponding to a railroad location in
    # game_elements['location_sequence']
    utility_positions = list() # list of integers, with each integer corresponding to a utility location in
    # game_elements['location_sequence']
    location_sequence = list() # list of Location objects in sequence, as they would be ordered on a linear game board.
    color_assets = dict()  # key is a string color (of a real estate property) and value is the set of location objects
    # that have that color. Any asset that does not have a color or where the color is None in the schema will not be
    # included in any set, since we do not insert None in as a key

    for l in game_schema['locations']['location_objects']:
        if l['loc_class'] == 'action':
            action_args = l.copy()
            action_args['perform_action'] = getattr(sys.modules[__name__], l['perform_action'])
            location_objects[l['name']] = location.ActionLocation(**action_args)

        elif l['loc_class'] == 'do_nothing':
            location_objects[l['name']] = location.DoNothingLocation(**l)

        elif l['loc_class'] == 'real_estate':
            real_estate_args = l.copy()
            flag = 0
            if l['owned_by'] == 'bank':
                real_estate_args['owned_by'] = current_gameboard['bank']
            else:
                for item in current_gameboard['players']:
                    if item.player_name == l['owned_by']:
                        real_estate_args['owned_by'] = item
                        flag = 1
            is_mortgaged_flag = l['is_mortgaged']
            del real_estate_args['is_mortgaged']
            location_objects[l['name']] = location.RealEstateLocation(**real_estate_args)
            location_objects[l['name']].is_mortgaged = is_mortgaged_flag
            if flag == 1:
                for player in current_gameboard['players']:
                    if player.player_name == l['owned_by']:
                        player.assets.add(location_objects[l['name']])

        elif l['loc_class'] == 'tax':
            location_objects[l['name']] = location.TaxLocation(**l)

        elif l['loc_class'] == 'railroad':
            railroad_args = l.copy()
            flag = 0
            if l['owned_by'] == 'bank':
                railroad_args['owned_by'] = current_gameboard['bank']
            else:
                for item in current_gameboard['players']:
                    if item.player_name == l['owned_by']:
                        railroad_args['owned_by'] = item
                        flag = 1
            is_mortgaged_flag = l['is_mortgaged']
            del railroad_args['is_mortgaged']
            location_objects[l['name']] = location.RailroadLocation(**railroad_args)
            location_objects[l['name']].is_mortgaged = is_mortgaged_flag
            if flag == 1:
                for player in current_gameboard['players']:
                    if player.player_name == l['owned_by']:
                        player.assets.add(location_objects[l['name']])

        elif l['loc_class'] == 'utility':
            utility_args = l.copy()
            flag = 0
            if l['owned_by'] == 'bank':
                utility_args['owned_by'] = current_gameboard['bank']
            else:
                for item in current_gameboard['players']:
                    if item.player_name == l['owned_by']:
                        utility_args['owned_by'] = item
                        flag = 1
            is_mortgaged_flag = l['is_mortgaged']
            del utility_args['is_mortgaged']
            location_objects[l['name']] = location.UtilityLocation(**utility_args)
            location_objects[l['name']].is_mortgaged = is_mortgaged_flag
            if flag == 1:
                for player in current_gameboard['players']:
                    if player.player_name == l['owned_by']:
                        player.assets.add(location_objects[l['name']])

        else:
            logger.debug('encountered unexpected location class: '+ l['loc_class'])
            logger.error("Exception")

    for i in range(len(game_schema['locations']['location_sequence'])):
        loc = location_objects[game_schema['locations']['location_sequence'][i]]
        location_sequence.append(loc) # we first get the name of
        # the location at index i of the game schema, and then use it in location_objects to get the actual location
        # object (loc) corresponding to that location name. We then append it to location_sequence. The net result is
        # that we have gone from a sequence of location names to the corresponding sequence of objects.
        if loc.loc_class == 'railroad':
            railroad_positions.append(i)
        elif loc.loc_class == 'utility':
            utility_positions.append(i)
        elif loc.name == 'In Jail/Just Visiting':
            current_gameboard['jail_position'] = i

    current_gameboard['railroad_positions'] = railroad_positions
    current_gameboard['utility_positions'] = utility_positions

    if len(location_sequence) != game_schema['locations']['location_count']:
        logger.debug('location count: '+ str(game_schema['locations']['location_count'])+ ', length of location sequence: '+
        str(len(location_sequence))+ ' are unequal.')
        logger.error("Exception")

    if location_sequence[game_schema['go_position']].name != 'Go':
        logger.debug('go positions are not aligned')
        logger.error("Exception")
    else:
        current_gameboard['go_position'] = game_schema['go_position']
        current_gameboard['go_increment'] = game_schema['go_increment']

    current_gameboard['location_objects'] = location_objects
    current_gameboard['location_sequence'] = location_sequence

    for o in location_sequence:
        if o.color is None:
            continue
        elif o.color not in game_schema['full_color_sets_possessed']:
            logger.debug(o.color)
            logger.error("Exception")
        else:
            if o.color not in color_assets:
                color_assets[o.color] = set()
            color_assets[o.color].add(o)

    current_gameboard['color_assets'] = color_assets

    for item in game_schema['players']:
        for player in current_gameboard['players']:
            if item['player_name'] == player.player_name:
                player.mortgaged_assets = set()
                for loc in item['mortgaged_assets']:
                    player.mortgaged_assets.add(current_gameboard['location_objects'][loc])

                outstanding_property_offer = dict()
                outstanding_property_offer['from_player'] = item['outstanding_property_offer']['from_player']
                outstanding_property_offer['price'] = item['outstanding_property_offer']['price']
                outstanding_property_offer['asset'] = set()
                if item['outstanding_property_offer']['asset']:
                    for loc in item['outstanding_property_offer']['asset']:
                        outstanding_property_offer['asset'].add(current_gameboard['location_objects'][loc])

                player.outstanding_property_offer = outstanding_property_offer

                outstanding_trade_offer = dict()
                outstanding_trade_offer['from_player'] = item['outstanding_trade_offer']['from_player']
                outstanding_trade_offer['cash_offered'] = item['outstanding_trade_offer']['cash_offered']
                outstanding_trade_offer['cash_wanted'] = item['outstanding_trade_offer']['cash_wanted']
                outstanding_trade_offer['property_set_wanted'] = set()
                for loc in item['outstanding_trade_offer']['property_set_wanted']:
                    outstanding_trade_offer['property_set_wanted'].add(current_gameboard['location_objects'][loc])
                outstanding_trade_offer['property_set_offered'] = set()
                for loc in item['outstanding_trade_offer']['property_set_offered']:
                    outstanding_trade_offer['property_set_offered'].add(current_gameboard['location_objects'][loc])

                player.outstanding_trade_offer = outstanding_trade_offer
                break
def _initialize_locations(game_elements, game_schema):
    location_objects = dict(
    )  # key is a location name, and value is a Location object
    railroad_positions = list(
    )  # list of integers, with each integer corresponding to a railroad location in
    # game_elements['location_sequence']
    utility_positions = list(
    )  # list of integers, with each integer corresponding to a utility location in
    # game_elements['location_sequence']
    location_sequence = list(
    )  # list of Location objects in sequence, as they would be ordered on a linear game board.
    color_assets = dict(
    )  # key is a string color (of a real estate property) and value is the set of location objects
    # that have that color. Any asset that does not have a color or where the color is None in the schema will not be
    # included in any set, since we do not insert None in as a key

    for l in game_schema['locations']['location_states']:

        if l['loc_class'] == 'action':
            action_args = l.copy()
            action_args['perform_action'] = getattr(sys.modules[__name__],
                                                    l['perform_action'])
            location_objects[l['name']] = location.ActionLocation(
                **action_args)

        elif l['loc_class'] == 'do_nothing':
            location_objects[l['name']] = location.DoNothingLocation(**l)

        elif l['loc_class'] == 'real_estate':
            real_estate_args = l.copy()
            real_estate_args['owned_by'] = game_elements['bank']
            real_estate_args['num_houses'] = 0
            real_estate_args['num_hotels'] = 0
            location_objects[l['name']] = location.RealEstateLocation(
                **real_estate_args)

        elif l['loc_class'] == 'tax':
            location_objects[l['name']] = location.TaxLocation(**l)

        elif l['loc_class'] == 'railroad':
            railroad_args = l.copy()
            railroad_args['owned_by'] = game_elements['bank']
            location_objects[l['name']] = location.RailroadLocation(
                **railroad_args)

        elif l['loc_class'] == 'utility':
            utility_args = l.copy()
            utility_args['owned_by'] = game_elements['bank']
            location_objects[l['name']] = location.UtilityLocation(
                **utility_args)

        else:
            logger.debug('encountered unexpected location class: ' +
                         l['loc_class'])
            logger.error("Exception")
            raise Exception

    for i in range(0, len(game_schema['location_sequence'])):
        loc = location_objects[game_schema['location_sequence'][i]]
        location_sequence.append(loc)  # we first get the name of
        # the location at index i of the game schema, and then use it in location_objects to get the actual location
        # object (loc) corresponding to that location name. We then append it to location_sequence. The net result is
        # that we have gone from a sequence of location names to the corresponding sequence of objects.
        if loc.loc_class == 'railroad':
            railroad_positions.append(i)
        elif loc.loc_class == 'utility':
            utility_positions.append(i)
        elif loc.name == 'In Jail/Just Visiting':
            game_elements['jail_position'] = i

    game_elements['railroad_positions'] = railroad_positions
    game_elements['utility_positions'] = utility_positions

    if len(location_sequence) != game_schema['locations']['location_count']:
        logger.debug('location count: ' +
                     str(game_schema['locations']['location_count']) +
                     ', length of location sequence: ' +
                     str(len(location_sequence)) + ' are unequal.')
        logger.error("Exception")
        raise Exception

    if location_sequence[game_schema['go_position']].name != 'Go':
        logger.debug('go positions are not aligned')
        logger.error("Exception")
        raise Exception
    else:
        game_elements['go_position'] = game_schema['go_position']
        game_elements['go_increment'] = game_schema['go_increment']

    game_elements['location_objects'] = location_objects
    game_elements['location_sequence'] = location_sequence

    for o in location_sequence:
        if o.color is None:
            continue
        elif o.color not in game_schema['players']['player_states'][
                'full_color_sets_possessed'][0]:
            logger.debug(o.color)
            logger.error("Exception")
            raise Exception
        else:
            if o.color not in color_assets:
                color_assets[o.color] = set()
            color_assets[o.color].add(o)

    game_elements['color_assets'] = color_assets