Python: how to make a turtle never cross over a line

为君一笑 提交于 2019-12-13 07:23:48

问题


I'm trying to write a python program that will make a turtle either move forward, turn left and then move, or turn right and then move randomly without ever crossing over its own previously drawn lines. It must stay within the screen and clear and restart once it has done the most possible moves. This is as far as I got:

import turtle
positions=[]

while 'x':
    count=132
    for x in range (132):
        count-=1
        print(count)
        move = randint(1,3)

        if move == 1:
            turtle.fd(50)
        if move == 2:
            turtle.rt(90)
            turtle.fd(50)
        if move == 3:
            turtle.lt(90)
            turtle.fd(50)

        if turtle.xcor()>290:
            turtle.rt(180)
            turtle.fd(50)
        if turtle.xcor()<-290:
            turtle.rt(180)
            turtle.fd(50)
        if turtle.ycor()>240:
            turtle.rt(180)
            turtle.fd(50)
        if turtle.ycor()<-240:
            turtle.rt(180)
            turtle.fd(50)
    turtle.clear()

How can I make it remember its positions and not go over them? Many thanks!


回答1:


Below is my attempt to solve your autonomous turtle problem. I chose a set() to track visited positions but also coerced the turtle onto a grid to make sure that only a limited set of points could be visited. I didn't like your approach of doing a 180 when you hit a wall as that just makes you retrace your path and fail -- instead my turtle tries to avoid hitting the walls.

I use an invisible turtle clone to "test the waters" to see if a move is good or bad. If there are no good moves, it gives up, resets, and starts again. You have to close the window to kill the program:

import turtle
from random import shuffle

WIDTH, HEIGHT = 600, 500

INCREMENT = 50

TURTLE_WIDTH = 20

X, Y = 0, 1

def dot_round(x, base=INCREMENT):
    return int(base * round(float(x) / base))

turtle.setup(WIDTH, HEIGHT)

turtle.shape("turtle")

while True:
    positions = set()

    while True:

        position = (dot_round(turtle.xcor()), dot_round(turtle.ycor()))  # coerce position to grid

        if position in positions:
            break  # collision with line

        positions.add(position)

        turtle.setposition(position)  # coerce turtle back onto our grid

        moves = list(range(3))

        shuffle(moves)

        clone = None

        for move in moves:
            clone = turtle.clone()  # use an invisible clone to test the waters
            clone.hideturtle()
            clone.penup()

            if move == 1:
                clone.right(90)
            elif move == 2:
                clone.left(90)

            clone.forward(INCREMENT)

            position = (dot_round(clone.xcor()), dot_round(clone.ycor()))

            if position[X] <= TURTLE_WIDTH//2 - WIDTH//2 or position[X] > WIDTH//2 - TURTLE_WIDTH//2:
                continue  # avoid collision with wall

            if position[Y] <= TURTLE_WIDTH//2 - HEIGHT//2 or position[Y] > HEIGHT//2 - TURTLE_WIDTH//2:
                continue  # avoid collision with wall

            if position not in positions:
                break

        else:  # no break
            break  # accept the inevitable, there's no good move

        turtle.setheading(clone.heading())
        turtle.forward(INCREMENT)

    turtle.reset()

# close the turtle window to get out of this program

This turtle only looks one move ahead -- he easily gets himself into jams he can't get himself out of.

This hopefully gives you some ideas how to design your own turtle automaton.



来源:https://stackoverflow.com/questions/42121107/python-how-to-make-a-turtle-never-cross-over-a-line

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!