#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 ...