Skip to content

Guidance on creating multiple similar outputs with variations in return value #87

@cwaldbieser

Description

@cwaldbieser

I was experimenting with automat to simulate a game. The game has a number of different phases, and different players may only be active in particular phases.

I modelled the phases as different states, and an input, advance_phase allows transitioning from one phase to the next in a linear fashion. I.e. in state "A", calling advance_phase() causes the machine to enter state "B". Calling it again causes the machine to enter state "C", etc.

I'd like to be able to query which players are active during a particular phase, but since there doesn't seem to be any way to map the machine state to other meaningful information in the game, I find I need to track the phases independently. So I end up with something like the following:

class Game(object):
    _machine = MethodicalMachine()

    # States
    @_machine.state()
    def have_players(self):
        """
        The game has players configured.
        """

    @_machine.state(initial=True)
    def dont_have_players(self):
        """
        The game doesn't have any players set.
        """

    @_machine.state()
    def phase_a(self):
        """
        Game phase "A"
        """

    @_machine.state()
    def phase_b(self):
        """
        Game phase "B"
        """

    @_machine.state()
    def phase_c(self):
        """
        Game phase "C"
        """

    # ...

    @_machine.state()
    def phase_z(self):
        """
        Game phase "Z"
        """

    # Inputs

    @_machine.input()
    def start_game(self):
        """
        Start the game.
        """

    @_machine.input()
    def advance_phase(self):
        """
        Advance to the next phase.
        """

    # Outputs

    @_machine.output()
    def _set_phase_a(self):
        self._game_phase = "a"

    @_machine.output()
    def _set_phase_b(self):
        self._game_phase = "b"

    # ...

    @_machine.output()
    def _set_phase_z(self):
        self._game_phase = "z"

    # Transitions

    dont_have_players.upon(add_players, enter=have_players, outputs=[_set_players])

    have_players.upon(start_game, enter=phase_a, outputs=[_set_phase_a])
    phase_a.upon(advance_phase, enter=phase_b, outputs=[_set_phase_b])
    phase_b.upon(advance_phase, enter=phase_c, outputs=[_set_phase_c])
    # ...
    phase_y.upon(advance_phase, enter=phase_d, outputs=[_set_phase_z])

I end up with lots of repetitive-looking states and outputs, and I was wondering if there is some guidance on the best way for implementing these multiple states or outputs, using some kind of looping perhaps.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions