Каков наилучший способ структурировать этот конечный автомат в Python? - PullRequest
0 голосов
/ 31 января 2020

Я очень плохо знаком с python и пытаюсь начать заниматься кодированием. Я пытаюсь создать простого бота, чтобы играть в игру на фейсбуке, и после некоторых исследований я считаю, что конечный автомат - это верный путь к go. Это набросок того, что я пытаюсь сделать, но я уверен, что это неправильный способ его кодирования. Как только программа станет более сложной, этот код станет запутанным. Может ли кто-нибудь помочь мне перевести это в более надежный код конечного автомата? Кроме того, есть ли способ проверить между состояниями, нажал ли пользователь клавишу, чтобы я мог поставить машину на паузу? Спасибо.

state = 1

def runStateMachine():
    global state
    if state == 1:
        doSomething()
        state = 2
    elif state == 2:
        if checkSomething():
            state = 3
        else:
            state = 1
    elif state == 3:
        finishSomething()
        state = 1

while True:
    runStateMachine()
    sleep(5)
    #check if a key has been pressed and pause here until the key is pressed again

Ответы [ 3 ]

1 голос
/ 31 января 2020

Идея конечного автомата не плохая, в зависимости от типа игры, для которой вы пытаетесь написать бота. Ваше замечание о том, что код станет более сложным, чем вы хотите, является хорошим, и сейчас самое время отступить и рассмотреть ваши варианты.

Из вашего кода и ваших вопросов это Похоже, вы довольно плохо знакомы с программированием, так что вы можете изучить некоторые основы, чтобы решить, будут ли они вам полезны.

Например, если вам требуется более одного конечного автомата или вы хотите составить конечный автомат из нескольких меньших, вы можете рассмотреть возможность записи конечного автомата в виде класса, который затем можно использовать повторно. То же самое применимо, если вы хотите написать разные для разных игр или для разных стратегий, чтобы играть в одну и ту же игру.

Вы спрашиваете о вводе с клавиатуры, и это то, что вы можете решать отдельно, но с одним основным l oop, который прогрессирует в шагах, которые прерываются нажатиями клавиш, может быть не лучшим подходом, когда вы начинаете добавлять вещи. Подумайте, какие изменения ввода и состояния должны повлиять на то, что делает ваша программа, и сфокусируйтесь на правильном подборе важных частей, прежде чем слишком сильно беспокоиться о том, как все это собрать вместе.

Чтобы ответить на ваши вопросы: есть лучшие способы чтобы написать свой код, и поскольку конечные автоматы являются очень распространенной концепцией информатики, существует множество библиотек, одна из которых может удовлетворить ваши потребности и сэкономить много времени. Например, посмотрите на https://github.com/pytransitions/transitions

Что касается проверки нажатий клавиш: вы можете просто заставить пользователя ввести что-то с помощью input(), но если вы хотите увидеть, происходит ли нажатие клавиши чтобы быть нажатым, вы должны проверить библиотеку, такую ​​как keyboard и, в частности, is_pressed() https://github.com/boppreh/keyboard#keyboard .is_pressed

Обратите внимание, что я не рекомендую эти библиотеки, я просто хочу указать на то, что для распространенных проблем библиотеки часто являются лучшим способом go. Достаточно взглянуть на огромный объем работы, который уже проделан, и время, которое потребовалось авторам, чтобы сделать это правильно.

Не каждая библиотека идеальна, и некоторым программистам не нравится идея включения кода, который они делают не нужно, но это определенно способ go, если вы хотите работать над чем-то, что делает что-то, не тратя дней на переизобретение колеса. Если у вас есть что-то, что работает, вы всегда можете подумать о замене библиотеки на что-то более лаконичное, если вы уверены, что сможете добиться большего - и, возможно, вы захотите выпустить это как библиотеку самостоятельно!

0 голосов
/ 31 января 2020

Ваш код работает в тех случаях, когда у вас есть несколько состояний. По мере того, как число ваших штатов увеличивается, управлять им станет намного сложнее. У меня есть пара предложений о том, как вы можете превентивно подготовить свой код.

  • Учитывая то, как вы кодируете прямо сейчас (используя целое число в блоке if / elif), вам лучше использовать операторы switch / case, а не большой блок if / elif заявления.

  • В идеале, вместо произвольного изменения значения состояния, создайте функцию, которая определяет текущее состояние, запускаемое в начале каждого l oop.

Реализация обоих этих режимов позволит вам легче добавлять больше состояний по мере увеличения общего числа состояний, а также позволит вам получить приблизительный обзор того, как на самом деле работает ваша программа. (то есть, что на самом деле означает быть в состоянии x и если вы в состоянии x, что происходит в следующем цикле вашего конечного автомата)

0 голосов
/ 31 января 2020

Я тоже новичок, но ваш код мне подходит.

Одна вещь, которую вы можете сделать, чтобы улучшить код, это превратить состояние = X в:

state = state % 3 + 1
...