pytransitions / transitions

A lightweight, object-oriented finite state machine implementation in Python with many extensions
MIT License
5.67k stars 529 forks source link

Machine get into wrong state. #637

Closed nocturne123 closed 11 months ago

nocturne123 commented 11 months ago

Describe the bug This is my project using transitions https://github.com/nocturne123/board_game.git I am using python 3.11.4 and transitions 0.9.0 with conda.

In file test_code_4.py, Card will occasionally get into wrong state. It is not always happen, chance is about 50%.

Minimal working example

# your minimal working example
# In player_action.py I defined draw_from_card_pile, and trigger card's machine
def draw_card_from_pile(player: Player, drawpile: DrawPile, num: int = 1):
    """抽牌"""
    for _ in range(num):
        card: Card = drawpile.pop()
        card.get_draw()
        card.get_into_hand()
        player.hand_sequence.append(card)

#In card.py I defined Card class, and related transitions. Here is the core.
transtions = [
    {
        "trigger": "get_draw",
        "source": CardStateEnum.in_draw_pile,
        "dest": CardStateEnum.on_draw,
    },
    {
        "trigger": "get_into_hand",
        "source": CardStateEnum.on_draw,
        "dest": CardStateEnum.in_hand,
    },]

class Card(metaclass=abc.ABCMeta):
    def __init__(
        self,
        card_type: CardTypeEnum,
        states=CardStateEnum,
        transitions=transtions,
    ):
        self.distance_limited = True
        self.machine = Machine(
            model=self,
            states=states,
            transitions=transitions,
            initial=CardStateEnum.in_draw_pile,
        )
        self.card_type = card_type
        self.auto_discard = True
        self.target = None

Expected behavior It's all in test_code_4.py, when it work well.

Additional context console give me imformation like this: Traceback (most recent call last): File "e:\pyglet_game\board_games_is_magic\board_game\test_code_4.py", line 57, in PlayerAction.draw_card_from_pile( File "e:\pyglet_game\board_games_is_magic\board_game\player_action.py", line 25, in draw_card_from_pile card.get_draw() File "C:\Users\yujiaxin.conda\envs\gamedev\Lib\site-packages\transitions\core.py", line 402, in trigger return self.machine._process(func) ^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "C:\Users\yujiaxin.conda\envs\gamedev\Lib\site-packages\transitions\core.py", line 1211, in _process return trigger() ^^^^^^^^^ File "C:\Users\yujiaxin.conda\envs\gamedev\Lib\site-packages\transitions\core.py", line 415, in _trigger if self._is_valid_source(event_data.state): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "C:\Users\yujiaxin.conda\envs\gamedev\Lib\site-packages\transitions\core.py", line 452, in _is_valid_source raise MachineError(msg) transitions.core.MachineError: "Can't trigger event get_draw from state in_hand!"

If you fail to get the bug, try it more times, I can get it within ten. board_game_bug_report_mini.zip bug no_bug

nocturne123 commented 11 months ago

It turns out my problem, I am sorry.