Модуль черепахи для муравья лэнгтона в python дает мне поднять терминатора — черепаху.Ошибка Терминатора

#python #python-3.x #turtle-graphics #python-turtle

#питон #черепаха-графика #питон-черепаха

Вопрос:

 import turtle   def update_maps(graph, turtle, color):  graph[turtle_pos(turtle)] = color  return None   def turtle_pos(turtle):  return (round(turtle.xcor()), round(turtle.ycor()))   def langton_move(turtle, pos, maps, step):  if pos not in maps or maps[pos] == "white":  turtle.fillcolor("black")  turtle.stamp()  update_maps(maps, turtle, "black")  turtle.right(90)  turtle.forward(step)  pos = turtle_pos(turtle)  elif maps[pos] == "black":  turtle.fillcolor("white")  update_maps(maps, turtle, "white")  turtle.stamp()  turtle.left(90)  turtle.forward(step)  pos = turtle_pos(turtle)  return pos   def move(movements,trace):  # Screen  BACKGROUND_COLOR = "white"  WIDTH = 2000  HEIGHT = 2000  # Ant  SHAPE = "square"  SHAPE_SIZE = 0.5  SPEED = -1  STEP = 11   # Data structure ex. {(x, y): "black", ..., (x_n, y_n): "white"}  maps = {}   # Initialize Window  window = turtle.Screen()  window.bgcolor(BACKGROUND_COLOR)  window.screensize(WIDTH, HEIGHT)  window.tracer(trace)  # Initialize Ant  ant = turtle.Turtle()  ant.shape(SHAPE)  ant.shapesize(SHAPE_SIZE)  ant.penup()  ant.speed(SPEED)  ant.right(180)  pos = turtle_pos(ant)   moves = 0  while moveslt;movements:  pos = langton_move(ant, pos, maps, STEP)  moves  = 1  window.exitonclick()  while True:  option = int(input("hey"))  if option == 1:  move(11000, False)  if option == 2:  move(100, True)  

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

Ответ №1:

Проблема в том, что ваша программа неправильно структурирована. Вы используете черепаху для рисования, но игнорируете парадигму программирования черепахи. В мире, управляемом событиями, их не должно быть while True: . Вы должны вводить цифры на экране (без возврата), а не на консоли. Вы не должны создавать нового (глобального) муравья для каждого запуска, а скорее повторно использовать старого. Вам не нужно полностью заново инициализировать все, что связано с окном, при каждом запуске. Его exitonclick() следует вызывать только один раз, а не в цикле.

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

 from turtle import Screen, Turtle  # Screen WIDTH = 2000 HEIGHT = 2000 BACKGROUND_COLOR = 'white'  # Ant SHAPE = 'square' SHAPE_SIZE = 0.5 SPEED = 'fastest' STEP = 11  def update_maps(graph, turtle, color):  graph[turtle_pos(turtle)] = color  def turtle_pos(turtle):  x, y = turtle.position()   return round(x), round(y)  def langton_move(turtle, pos, maps, step):  if pos not in maps or maps[pos] == 'white':  turtle.fillcolor('black')  turtle.stamp()  update_maps(maps, turtle, 'black')  turtle.right(90)  elif maps[pos] == 'black':  turtle.fillcolor('white')  turtle.stamp()  update_maps(maps, turtle, 'white')  turtle.left(90)   turtle.forward(step)   return turtle_pos(turtle)  def move(movements, trace):  # Data structure ex. {(x, y): 'black', ..., (x_n, y_n): 'white'}  maps = {}   screen.tracer(trace)   ant.home()  ant.clear()  ant.setheading(180)   screen.update()   position = turtle_pos(ant)   for _ in range(movements):  position = langton_move(ant, position, maps, STEP)  def long_untraced():  screen.onkey(None, '1') # disable handlers inside handler  screen.onkey(None, '2')   move(11000, False)   screen.onkey(long_untraced, '1') # reenable handlers  screen.onkey(short_traced, '2')  def short_traced():  screen.onkey(None, '2') # disable handlers inside handler  screen.onkey(None, '1')   move(100, True)   screen.onkey(short_traced, '2') # reenable handlers  screen.onkey(long_untraced, '1')  # Initialize Window screen = Screen() screen.screensize(WIDTH, HEIGHT) screen.bgcolor(BACKGROUND_COLOR)  # Initialize Ant ant = Turtle() ant.shape(SHAPE) ant.shapesize(SHAPE_SIZE) ant.penup() ant.speed(SPEED)  screen.onkey(long_untraced, '1') screen.onkey(short_traced, '2') screen.listen() screen.exitonclick()  

Комментарии:

1. Большое вам спасибо, но нет ли другого способа решить эту проблему, сохраняя цикл while, в моем окончательном коде есть десятки вариантов для муравья Langtons, он создает пользовательские правила и сохраненные правила, а также несколько муравьев на экране, и все это при использовании цикла while и предоставляя пользователю выбор: вводить свои собственные правила или выбирать заранее установленные, я поделился этим кодом, поскольку он описывает проблему в моем длинном коде самым простым способом, если проблема лежит в основе использования turtle и в то время как истинные циклы, я просто приму это. Еще раз спасибо вам.

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

3. @jujudoju121, загляните в turtle textinput() и numinput() позвольте вам взаимодействовать с пользователем из turtle вместо консоли. Обработчики событий, которые я написал, предполагали два предоставленных вами варианта, если бы было больше вариантов, я бы написал их по-другому, например, используя глобальную running переменную семафора, чтобы блокировать все обработчики, пока один из них активен.

4. @jujudoju121, exitonclick() не возвращается напрямую. Помимо настройки onclick() для экрана, он передает управление обработчику событий. Только когда окружающая среда черепахи полностью разрушена, она возвращается. И автономная черепаха не любит, когда ее перезапускают после того, как она была снесена.

Ответ №2:

Добавление этой единственной строки перед

#InitializeAnt заявление с комментарием поможет вам заставить этот код работать должным образом.

 ... turtle.TurtleScreen._RUNNING=True # Initialize Ant ...