(self, parent)
Creates the children nodes after an action node (a node where a player acted).
Creates the children nodes after an action node (a node where a player acted).
Creates the children nodes after an action node ( a node where a player acted ) .
def _get_children_of_action_node(self, parent):
        """
        Creates the children nodes after an action node (a node where a player acted).
        """
        self._env.load_state_dict(parent.env_state)
        if self._stop_at_street <= self._env.current_round:
            return []

        if parent.p_id_acting_next == self.CHANCE_ID:
            """
            When we get here, the parent node has a special attribute that carries the state after the new round is
            started. Here we adjust that state to not have the newly dealt cards dealt and cards drawn from the deck,
            but all other updates stay.
            """

            # ______________________________________ break if too far ______________________________________
            if not self._put_out_new_round_after_limit:
                if self._stop_at_street <= parent.env_state[EnvDictIdxs.current_round]:
                    return []

            # _____________________ prepare state to new round without new cards dealt _____________________
            _base_env_state = copy.deepcopy(parent.new_round_state)

            # ________________________________ generate all possible boards ________________________________

            def _make_boards(_new_boards, _board_1d, _idx_to_insert_in, _n_todo):
                if _n_todo > 0:
                    for _c in [_ for _ in range(self._env.N_CARDS_IN_DECK) if _ not in _board_1d]:
                        _b = np.copy(_board_1d)
                        _b[_idx_to_insert_in] = _c

                        for i in range(_n_todo):
                            _make_boards(_new_boards=_new_boards, _board_1d=_b, _idx_to_insert_in=_idx_to_insert_in + 1,
                                         _n_todo=_n_todo - 1)

                        _new_boards.append(self._env_bldr.lut_holder.get_2d_cards(cards_1d=_b))

            new_boards = []
            board_1d = self._env_bldr.lut_holder.get_1d_cards(cards_2d=_base_env_state[EnvDictIdxs.board_2d])
            _make_boards(_new_boards=new_boards,
                         _board_1d=board_1d,
                         _idx_to_insert_in=self._env_bldr.lut_holder.DICT_LUT_N_CARDS_OUT[
                             self._env_bldr.rules.ROUND_BEFORE[_base_env_state[EnvDictIdxs.current_round]]],
                         _n_todo=self._env_bldr.lut_holder.DICT_LUT_CARDS_DEALT_IN_TRANSITION_TO[
                             _base_env_state[EnvDictIdxs.current_round]])

            # ____________________________________ build children nodes ____________________________________
            children = []
            for board in new_boards:
                child_env_state = copy.deepcopy(_base_env_state)
                child_env_state[EnvDictIdxs.board_2d] = board
                _deck_remaining_before_deal = np.copy(child_env_state[EnvDictIdxs.deck]["deck_remaining"])
                for c in board:
                    child_env_state[EnvDictIdxs.deck]["deck_remaining"] = \
                        np.delete(_deck_remaining_before_deal, np.where(_deck_remaining_before_deal == c), axis=0)

                c = ChanceNode(env_state=child_env_state,
                               tree=self,
                               parent=parent,
                               is_terminal=False,
                               p_id_acted_last=self.CHANCE_ID,
                               depth=parent.depth + 1)

                self._env.load_state_dict(child_env_state)
                c.allowed_actions = self._env.get_legal_actions()
                children.append(c)

            return children

        else:
            children = []
            for action in parent.allowed_actions:
                self._env.load_state_dict(parent.env_state)
                _, __, is_terminal, info = self._env.step(action)

                # after action:  Terminal
                if is_terminal:
                    # state before payouts or rundown
                    env_state = info["state_dict_before_money_move"]
                    env_state[EnvDictIdxs.current_round] = parent.env_state[EnvDictIdxs.current_round]
                    env_state[EnvDictIdxs.board_2d] = parent.env_state[EnvDictIdxs.board_2d]
                    env_state[EnvDictIdxs.deck] = copy.deepcopy(parent.env_state[EnvDictIdxs.deck])
                    is_terminal = True
                    new_round_state = None

                # after action:  New round
                elif info["chance_acts"]:
                    # state before round transition
                    env_state = info["state_dict_before_money_move"]
                    env_state[EnvDictIdxs.current_round] = parent.env_state[EnvDictIdxs.current_round]
                    if self._is_debugging:
                        assert env_state[EnvDictIdxs.current_round] == parent.env_state[EnvDictIdxs.current_round]
                        assert np.array_equal(env_state[EnvDictIdxs.board_2d],
                                              np.copy(parent.env_state[EnvDictIdxs.board_2d]))
                        assert np.array_equal(env_state[EnvDictIdxs.deck]["deck_remaining"],
                                              np.copy(parent.env_state[EnvDictIdxs.deck]["deck_remaining"]))
                    is_terminal = False
                    new_round_state = self._env.state_dict()
                    new_round_state[EnvDictIdxs.board_2d] = np.copy(parent.env_state[EnvDictIdxs.board_2d])
                    new_round_state[EnvDictIdxs.deck] = copy.deepcopy(parent.env_state[EnvDictIdxs.deck])

                else:
                    env_state = self._env.state_dict()
                    is_terminal = False
                    new_round_state = None

                node = PlayerActionNode(env_state=env_state,
                                        action=action,
                                        is_terminal=is_terminal,
                                        parent=parent,
                                        p_id_acted_last=parent.p_id_acting_next,
                                        tree=self,
                                        depth=parent.depth + 1,
                                        new_round_state=new_round_state)

                if is_terminal:
                    node.p_id_acting_next = None
                    node.allowed_actions = []
                elif info["chance_acts"]:
                    node.p_id_acting_next = self.CHANCE_ID
                    node.allowed_actions = []
                else:
                    node.allowed_actions = self._env.get_legal_actions()
                children.append(node)

            return children
def _get_children_of_action_node ( self , parent ) : self . _env . load_state_dict ( parent . env_state ) if self . _stop_at_street <= self . _env . current_round : return [ ] if parent . p_id_acting_next == self . CHANCE_ID : """
            When we get here, the parent node has a special attribute that carries the state after the new round is
            started. Here we adjust that state to not have the newly dealt cards dealt and cards drawn from the deck,
            but all other updates stay.
            """ # ______________________________________ break if too far ______________________________________ if not self . _put_out_new_round_after_limit : if self . _stop_at_street <= parent . env_state [ EnvDictIdxs . current_round ] : return [ ] # _____________________ prepare state to new round without new cards dealt _____________________ _base_env_state = copy . deepcopy ( parent . new_round_state ) # ________________________________ generate all possible boards ________________________________ def _make_boards ( _new_boards , _board_1d , _idx_to_insert_in , _n_todo ) : if _n_todo > 0 : for _c in [ _ for _ in range ( self . _env . N_CARDS_IN_DECK ) if _ not in _board_1d ] : _b = np . copy ( _board_1d ) _b [ _idx_to_insert_in ] = _c for i in range ( _n_todo ) : _make_boards ( _new_boards = _new_boards , _board_1d = _b , _idx_to_insert_in = _idx_to_insert_in + 1 , _n_todo = _n_todo - 1 ) _new_boards . append ( self . _env_bldr . lut_holder . get_2d_cards ( cards_1d = _b ) ) new_boards = [ ] board_1d = self . _env_bldr . lut_holder . get_1d_cards ( cards_2d = _base_env_state [ EnvDictIdxs . board_2d ] ) _make_boards ( _new_boards = new_boards , _board_1d = board_1d , _idx_to_insert_in = self . _env_bldr . lut_holder . DICT_LUT_N_CARDS_OUT [ self . _env_bldr . rules . ROUND_BEFORE [ _base_env_state [ EnvDictIdxs . current_round ] ] ] , _n_todo = self . _env_bldr . lut_holder . DICT_LUT_CARDS_DEALT_IN_TRANSITION_TO [ _base_env_state [ EnvDictIdxs . current_round ] ] ) # ____________________________________ build children nodes ____________________________________ children = [ ] for board in new_boards : child_env_state = copy . deepcopy ( _base_env_state ) child_env_state [ EnvDictIdxs . board_2d ] = board _deck_remaining_before_deal = np . copy ( child_env_state [ EnvDictIdxs . deck ] [ "deck_remaining" ] ) for c in board : child_env_state [ EnvDictIdxs . deck ] [ "deck_remaining" ] = np . delete ( _deck_remaining_before_deal , np . where ( _deck_remaining_before_deal == c ) , axis = 0 ) c = ChanceNode ( env_state = child_env_state , tree = self , parent = parent , is_terminal = False , p_id_acted_last = self . CHANCE_ID , depth = parent . depth + 1 ) self . _env . load_state_dict ( child_env_state ) c . allowed_actions = self . _env . get_legal_actions ( ) children . append ( c ) return children else : children = [ ] for action in parent . allowed_actions : self . _env . load_state_dict ( parent . env_state ) _ , __ , is_terminal , info = self . _env . step ( action ) # after action:  Terminal if is_terminal : # state before payouts or rundown env_state = info [ "state_dict_before_money_move" ] env_state [ EnvDictIdxs . current_round ] = parent . env_state [ EnvDictIdxs . current_round ] env_state [ EnvDictIdxs . board_2d ] = parent . env_state [ EnvDictIdxs . board_2d ] env_state [ EnvDictIdxs . deck ] = copy . deepcopy ( parent . env_state [ EnvDictIdxs . deck ] ) is_terminal = True new_round_state = None # after action:  New round elif info [ "chance_acts" ] : # state before round transition env_state = info [ "state_dict_before_money_move" ] env_state [ EnvDictIdxs . current_round ] = parent . env_state [ EnvDictIdxs . current_round ] if self . _is_debugging : assert env_state [ EnvDictIdxs . current_round ] == parent . env_state [ EnvDictIdxs . current_round ] assert np . array_equal ( env_state [ EnvDictIdxs . board_2d ] , np . copy ( parent . env_state [ EnvDictIdxs . board_2d ] ) ) assert np . array_equal ( env_state [ EnvDictIdxs . deck ] [ "deck_remaining" ] , np . copy ( parent . env_state [ EnvDictIdxs . deck ] [ "deck_remaining" ] ) ) is_terminal = False new_round_state = self . _env . state_dict ( ) new_round_state [ EnvDictIdxs . board_2d ] = np . copy ( parent . env_state [ EnvDictIdxs . board_2d ] ) new_round_state [ EnvDictIdxs . deck ] = copy . deepcopy ( parent . env_state [ EnvDictIdxs . deck ] ) else : env_state = self . _env . state_dict ( ) is_terminal = False new_round_state = None node = PlayerActionNode ( env_state = env_state , action = action , is_terminal = is_terminal , parent = parent , p_id_acted_last = parent . p_id_acting_next , tree = self , depth = parent . depth + 1 , new_round_state = new_round_state ) if is_terminal : node . p_id_acting_next = None node . allowed_actions = [ ] elif info [ "chance_acts" ] : node . p_id_acting_next = self . CHANCE_ID node . allowed_actions = [ ] else : node . allowed_actions = self . _env . get_legal_actions ( ) children . append ( node ) return children