Python - 2 вопроса: редактирование переменной в функции и изменение порядка операторов if else внутри / во время выполнения - PullRequest
0 голосов
/ 30 апреля 2010

Прежде всего, я должен объяснить, что я пытаюсь сделать в первую очередь.

Я создаю игру, похожую на подземелья, и пытаюсь запрограммировать движение компьютерных персонажей / монстров на карте. Карта в основном является декартовой координатной сеткой. Расположение символов представлено кортежами значений x и y (x, y). Игра работает по очереди, и в свою очередь персонаж может двигаться только вверх, вниз, влево или вправо на 1 пробел. Я создаю очень простую систему движений, в которой персонаж будет просто принимать решения, чтобы двигаться по очереди. По сути, «забывчивая» система движений.

Основная блок-схема того, что я собираюсь сделать:

  1. Найти направление к месту назначения
  2. Составьте список приоритетов движений, которые должны быть выполнены, используя направление, например, («r», «u», «d», «l») означает, что он будет пытаться сначала двигаться вправо, затем вверх, затем вниз, затем влево.
  3. Попробуйте каждую из возможностей, следующих за порядком приоритетов. Если первое движение не удается (заблокировано препятствием и т. Д.), Оно будет последовательно пробовать движения до первого успешного движения, затем оно остановится.

На шаге 3 я пытаюсь это сделать так:

def move(direction,location):
    try:
        -snip- # Tries to move, raises the exception Movementerror if cannot move in the direction
        return 1 # Indicates movement successful
    except Movementerror:
        return 0 # Indicates movement unsuccessful (thus character has not moved yet)

prioritylist = ('r','u','d','l')
if move('r',location): pass
elif move('u',location): pass
elif move('d',location): pass
elif move('l',location): pass
else: pass

В блоке if / else программа попытается выполнить первое перемещение по приоритету в списке приоритетов. В функции перемещения персонаж будет пытаться двигаться. Если персонаж не заблокирован и движется, он возвращает 1, что приводит к проходу, на котором он остановится. Если персонаж заблокирован, он возвращает 0, затем он пытается следующее движение.

Однако это приводит к двум проблемам:

1.Как мне отредактировать переменную, переданную в функцию внутри самой функции, при возврате, если редактирование прошло успешно?

Мне сказали, что вы не можете редактировать переменную внутри функции, так как она не изменит значения переменной, она просто заставляет переменную внутри функции ссылаться на что-то другое, в то время как исходная переменная остается неизменной. Таким образом, решение состоит в том, чтобы вернуть значение и затем присвоить переменную возвращаемому значению. Однако я хочу, чтобы он возвращал другое значение, указывающее, успешно ли выполнено это редактирование, поэтому я хочу отредактировать эту переменную внутри самой функции. Как мне это сделать?

2.Как изменить порядок операторов if / else, чтобы они соответствовали порядку списка приоритетов? Он должен быть в состоянии изменить во время выполнения, так как список приоритетов может измениться, что приведет к изменению порядка перемещения.

Ответы [ 2 ]

3 голосов
/ 30 апреля 2010

Re 2. Я бы изменил ваше относительно большое дерево if / elif на простой цикл:

prioritylist = ('r','u','d','l')
for direction in prioritylist:
  if move(direction, location): break

менее повторяющийся, его легче расширять в будущем, если вы хотите разрешить диагональные шаги или что-то еще - и автоматически «следует за списком приоритетов» в любом порядке, в котором он находится, без необходимости изменять сам код

Re 1. Вы можете вернуть несколько значений из функции:

def move(direction,location):
    try:
        -snip-
        return True, newlocation
    except Movementerror:
        return False, location

и затем вы измените вышеприведенный цикл на, например ::

prioritylist = ('r','u','d','l')
for direction in prioritylist:
  success, newlocation = move(direction, location)
  if success: break

еще: newlocation = location

с использованием ветви else for, которая выполняется, если в for не происходит break, для рассмотрения случая, когда ни одна попытка не привела к успеху.

0 голосов
/ 30 апреля 2010

Вы можете использовать цикл for и выйти из цикла при первом удачном выборе:

for option in prioritylist:
    if move(option,location): # succeeded
        break

Вы также должны вернуть True или False вместо 1 или 0, поскольку это проясняет намерение.

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

positions = ['N','S','E','W']

def mutate_list(p):
     p.reverse()

print positions # prints ['N', 'S', 'E', 'W']
mutate_list(positions)
print positions # prints ['w', 'E', 'S', 'N']
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...