def _initialize_cards(current_gameboard, game_schema):
    community_chest_cards = set() # community chest card objects
    chance_cards = set() # chance card objects

    community_chest_card_objects = dict() # key is a community chest card name and value is an object
    chance_card_objects = dict() # key is a chance card name and value is an object

    picked_community_chest_cards = []  #list of all picked community chest cards throughout the gameplay
    picked_chance_cards = []  #list of all picked chance cards throughout the gameplay

    for specific_card in game_schema['cards']['community_chest_cards']['card_states']:
        card_obj = None
        if specific_card['card_type'] == 'movement':
            for i in range(0, specific_card['num']):
                card_args = specific_card.copy()
                del card_args['num']
                card_args['action'] = getattr(sys.modules[__name__], specific_card['action'])
                card_args['destination'] = current_gameboard['location_objects'][specific_card['destination']]
                card_obj = card.MovementCard(**card_args)
                community_chest_cards.add(card_obj)

        elif specific_card['card_type'] == 'contingent_movement':
            for i in range(0, specific_card['num']):
                card_args = specific_card.copy()
                del card_args['num']
                card_args['action'] = getattr(sys.modules[__name__], specific_card['action'])
                card_obj = card.ContingentMovementCard(**card_args)
                community_chest_cards.add(card_obj)

        elif specific_card['card_type'] == 'positive_cash_from_bank' or specific_card[
            'card_type'] == 'negative_cash_from_bank':
            for i in range(0, specific_card['num']):
                card_args = specific_card.copy()
                del card_args['num']
                card_args['action'] = getattr(sys.modules[__name__], specific_card['action'])
                card_args['amount'] = specific_card['amount']
                card_obj = card.CashFromBankCard(**card_args)
                community_chest_cards.add(card_obj)

        elif specific_card['card_type'] == 'contingent_cash_from_bank':
            for i in range(0, specific_card['num']):
                card_args = specific_card.copy()
                del card_args['num']
                card_args['action'] = getattr(sys.modules[__name__], specific_card['action'])
                #######################
                if isinstance(specific_card['contingency'], str):
                    card_args['contingency'] = getattr(sys.modules[__name__], specific_card['contingency'])
                else:
                    card_args['contingency'] = getattr(sys.modules[__name__], specific_card['contingency'][0])
                ########################
                card_obj = card.ContingentCashFromBankCard(**card_args)
                community_chest_cards.add(card_obj)

        elif specific_card['card_type'] == 'positive_cash_from_players' or card[
            'card_type'] == 'negative_cash_from_players':
            for i in range(0, specific_card['num']):
                card_args = specific_card.copy()
                del card_args['num']
                card_args['action'] = getattr(sys.modules[__name__], specific_card['action'])
                card_args['amount_per_player'] = specific_card['amount_per_player']
                card_obj = card.CashFromPlayersCard(**card_args)
                community_chest_cards.add(card_obj)
        else:
            logger.debug('community chest card type is not recognized: '+ specific_card['card_type'])
            logger.error("Exception")

        community_chest_card_objects[card_obj.name] = copy.deepcopy(card_obj)

    if len(community_chest_cards) != game_schema['cards']['community_chest_cards']['card_count']:
        logger.debug('community chest card count and number of items in community chest card set are inconsistent')

    for specific_card in game_schema['cards']['chance_cards']['card_states']:
        card_obj = None
        if specific_card['card_type'] == 'movement':
            for i in range(0, specific_card['num']):
                card_args = specific_card.copy()
                del card_args['num']
                card_args['action'] = getattr(sys.modules[__name__], specific_card['action'])
                card_args['destination'] = current_gameboard['location_objects'][specific_card['destination']]
                card_obj = card.MovementCard(**card_args)
                chance_cards.add(card_obj)

        elif specific_card['card_type'] == 'movement_payment':
            for i in range(0, specific_card['num']):
                card_args = specific_card.copy()
                del card_args['num']
                card_args['action'] = getattr(sys.modules[__name__], specific_card['action'])
                card_obj = card.MovementPaymentCard(**card_args)
                chance_cards.add(card_obj)

        elif specific_card['card_type'] == 'contingent_movement':
            for i in range(0, specific_card['num']):
                card_args = specific_card.copy()
                del card_args['num']
                card_args['action'] = getattr(sys.modules[__name__], specific_card['action'])
                card_obj = card.ContingentMovementCard(**card_args)
                chance_cards.add(card_obj)

        elif specific_card['card_type'] == 'movement_relative':
            for i in range(0, specific_card['num']):
                card_args = specific_card.copy()
                del card_args['num']
                card_args['action'] = getattr(sys.modules[__name__], specific_card['action'])
                card_args['new_relative_position'] = specific_card['new_relative_position']
                card_obj = card.MovementRelativeCard(**card_args)
                chance_cards.add(card_obj)

        elif specific_card['card_type'] == 'positive_cash_from_bank' or specific_card[
            'card_type'] == 'negative_cash_from_bank':
            for i in range(0, specific_card['num']):
                card_args = specific_card.copy()
                del card_args['num']
                card_args['action'] = getattr(sys.modules[__name__], specific_card['action'])
                card_args['amount'] = specific_card['amount']
                card_obj = card.CashFromBankCard(**card_args)
                chance_cards.add(card_obj)

        elif specific_card['card_type'] == 'contingent_cash_from_bank':
            for i in range(0, specific_card['num']):
                card_args = specific_card.copy()
                del card_args['num']
                card_args['action'] = getattr(sys.modules[__name__], specific_card['action'])
                ##########
                if isinstance(specific_card['contingency'], str):
                    card_args['contingency'] = getattr(sys.modules[__name__], specific_card['contingency'])
                else:
                    card_args['contingency'] = getattr(sys.modules[__name__], specific_card['contingency'][0])
                ########
                card_obj = card.ContingentCashFromBankCard(**card_args)
                chance_cards.add(card_obj)

        elif specific_card['card_type'] == 'positive_cash_from_players' or specific_card[
            'card_type'] == 'negative_cash_from_players':
            for i in range(0, specific_card['num']):
                card_args = specific_card.copy()
                del card_args['num']
                card_args['action'] = getattr(sys.modules[__name__], specific_card['action'])
                card_args['amount_per_player'] = specific_card['amount_per_player']
                card_obj = card.CashFromPlayersCard(**card_args)
                chance_cards.add(card_obj)
        else:
            logger.debug('chance card type is not recognized: '+ specific_card['card_type'])
            logger.error("Exception")

        chance_card_objects[card_obj.name] = copy.deepcopy(card_obj)

    if len(chance_cards) != game_schema['cards']['chance_cards']['card_count']:
        logger.debug('chance card count and number of items in chance card set are inconsistent')

    for item in game_schema['cards']['picked_chance_cards']:
        picked_chance_cards.append(chance_card_objects[item])

    for item in game_schema['cards']['picked_community_chest_cards']:
        picked_community_chest_cards.append(community_chest_card_objects[item])

    current_gameboard['chance_cards'] = chance_cards
    current_gameboard['community_chest_cards'] = community_chest_cards
    current_gameboard['chance_card_objects'] = chance_card_objects
    current_gameboard['community_chest_card_objects'] = community_chest_card_objects
    current_gameboard['picked_chance_cards'] = picked_chance_cards
    current_gameboard['picked_community_chest_cards'] = picked_community_chest_cards
def _initialize_cards(game_elements, game_schema):
    community_chest_cards = set()  # community chest card objects
    chance_cards = set()  # chance card objects

    community_chest_card_objects = dict(
    )  # key is a community chest card name and value is an object
    chance_card_objects = dict(
    )  # key is a chance card name and value is an object

    picked_community_chest_cards = [
    ]  #list of all picked community chest cards throughout the gameplay
    picked_chance_cards = [
    ]  #list of all picked chance cards throughout the gameplay

    # note that the number of keys in community_chest_card_objects may be different from the number of items in
    # community_chest_cards (same for chance), since if there is more than one card with the same name, we will end up having
    # fewer keys in the _objects data structure. In the _cards data structure we directly add the objects, so even
    # if two cards share a name, they will be treated as distinct objects. We do an additional check after the for
    # loop to verify that we have the expected numbers of cards as specified in the game schema.

    for specific_card in game_schema['cards']['community_chest'][
            'card_states']:
        card_obj = None
        if specific_card['card_type'] == 'movement':
            for i in range(0, specific_card['num']):
                card_args = specific_card.copy()
                del card_args['num']
                card_args['action'] = getattr(sys.modules[__name__],
                                              specific_card['action'])
                card_args['destination'] = game_elements['location_objects'][
                    specific_card['destination']]
                card_obj = card.MovementCard(**card_args)
                community_chest_cards.add(card_obj)

        elif specific_card['card_type'] == 'contingent_movement':
            for i in range(0, specific_card['num']):
                card_args = specific_card.copy()
                del card_args['num']
                card_args['action'] = getattr(sys.modules[__name__],
                                              specific_card['action'])
                card_obj = card.ContingentMovementCard(**card_args)
                community_chest_cards.add(card_obj)

        elif specific_card[
                'card_type'] == 'positive_cash_from_bank' or specific_card[
                    'card_type'] == 'negative_cash_from_bank':
            for i in range(0, specific_card['num']):
                card_args = specific_card.copy()
                del card_args['num']
                card_args['action'] = getattr(sys.modules[__name__],
                                              specific_card['action'])
                card_obj = card.CashFromBankCard(**card_args)
                community_chest_cards.add(card_obj)

        elif specific_card['card_type'] == 'contingent_cash_from_bank':
            for i in range(0, specific_card['num']):
                card_args = specific_card.copy()
                del card_args['num']
                card_args['action'] = getattr(sys.modules[__name__],
                                              specific_card['action'])
                card_args['contingency'] = getattr(
                    sys.modules[__name__], specific_card['contingency'])
                card_obj = card.ContingentCashFromBankCard(**card_args)
                community_chest_cards.add(card_obj)

        elif specific_card['card_type'] == 'positive_cash_from_players' or card[
                'card_type'] == 'negative_cash_from_players':
            for i in range(0, specific_card['num']):
                card_args = specific_card.copy()
                del card_args['num']
                card_args['action'] = getattr(sys.modules[__name__],
                                              specific_card['action'])
                card_obj = card.CashFromPlayersCard(**card_args)
                community_chest_cards.add(card_obj)
        else:

            logger.debug('community chest card type is not recognized: ' +
                         specific_card['card_type'])
            logger.error("Exception")
            raise Exception

        community_chest_card_objects[card_obj.name] = copy.deepcopy(card_obj)

    if len(community_chest_cards
           ) != game_schema['cards']['community_chest']['card_count']:
        logger.debug(
            'community chest card count and number of items in community chest card set are inconsistent'
        )

    for specific_card in game_schema['cards']['chance']['card_states']:
        card_obj = None
        if specific_card['card_type'] == 'movement':
            for i in range(0, specific_card['num']):
                card_args = specific_card.copy()
                del card_args['num']
                card_args['action'] = getattr(sys.modules[__name__],
                                              specific_card['action'])
                card_args['destination'] = game_elements['location_objects'][
                    specific_card['destination']]
                card_obj = card.MovementCard(**card_args)
                chance_cards.add(card_obj)

        elif specific_card['card_type'] == 'movement_payment':
            for i in range(0, specific_card['num']):
                card_args = specific_card.copy()
                del card_args['num']
                card_args['action'] = getattr(sys.modules[__name__],
                                              specific_card['action'])
                card_obj = card.MovementPaymentCard(**card_args)
                chance_cards.add(card_obj)

        elif specific_card['card_type'] == 'contingent_movement':
            for i in range(0, specific_card['num']):
                card_args = specific_card.copy()
                del card_args['num']
                card_args['action'] = getattr(sys.modules[__name__],
                                              specific_card['action'])
                card_obj = card.ContingentMovementCard(**card_args)
                chance_cards.add(card_obj)

        elif specific_card['card_type'] == 'movement_relative':
            for i in range(0, specific_card['num']):
                card_args = specific_card.copy()
                del card_args['num']
                card_args['action'] = getattr(sys.modules[__name__],
                                              specific_card['action'])
                card_obj = card.MovementRelativeCard(**card_args)
                chance_cards.add(card_obj)

        elif specific_card[
                'card_type'] == 'positive_cash_from_bank' or specific_card[
                    'card_type'] == 'negative_cash_from_bank':
            for i in range(0, specific_card['num']):
                card_args = specific_card.copy()
                del card_args['num']
                card_args['action'] = getattr(sys.modules[__name__],
                                              specific_card['action'])
                card_obj = card.CashFromBankCard(**card_args)
                chance_cards.add(card_obj)

        elif specific_card['card_type'] == 'contingent_cash_from_bank':
            for i in range(0, specific_card['num']):
                card_args = specific_card.copy()
                del card_args['num']
                card_args['action'] = getattr(sys.modules[__name__],
                                              specific_card['action'])
                card_args['contingency'] = getattr(
                    sys.modules[__name__], specific_card['contingency'])
                card_obj = card.ContingentCashFromBankCard(**card_args)
                chance_cards.add(card_obj)

        elif specific_card[
                'card_type'] == 'positive_cash_from_players' or specific_card[
                    'card_type'] == 'negative_cash_from_players':
            for i in range(0, specific_card['num']):
                card_args = specific_card.copy()
                del card_args['num']
                card_args['action'] = getattr(sys.modules[__name__],
                                              specific_card['action'])
                card_obj = card.CashFromPlayersCard(**card_args)
                chance_cards.add(card_obj)
        else:
            logger.debug('chance card type is not recognized: ' +
                         specific_card['card_type'])
            logger.error("Exception")
            raise Exception

        chance_card_objects[card_obj.name] = copy.deepcopy(card_obj)

    if len(chance_cards) != game_schema['cards']['chance']['card_count']:
        logger.debug(
            'chance card count and number of items in chance card set are inconsistent'
        )

    game_elements['chance_cards'] = chance_cards
    game_elements['community_chest_cards'] = community_chest_cards
    game_elements['chance_card_objects'] = chance_card_objects
    game_elements[
        'community_chest_card_objects'] = community_chest_card_objects
    game_elements['picked_chance_cards'] = picked_chance_cards
    game_elements[
        'picked_community_chest_cards'] = picked_community_chest_cards