Nas aulas vimos como podíamos resolver o problema de ter uma tartaruga num passeio aleatório mas sem poder sair de uma prisão circular. A nossa solução, muito simples, baseou-se no uso das primitivas
distance(x,y) e
towards(x,y). A primeira, permite determinar a distância entre a posição actual da tartaruga e a posição (x,y). A segunda, calcula o ângulo entre a linha que une a posição corrente da tartaruga e (x,y) com o eixo dos X. Eis o código básico:
import turtle
import random
def random_walk_prison(raio,pos_x,pos_y,ang,step,num):
turtle.penup()
turtle.goto(pos_x,pos_y)
turtle.setheading(ang)
turtle.pendown()
for i in range(num):
if turtle.distance(pos_x, pos_y) > raio:
turtle.setheading(turtle.towards(pos_x,pos_y))
turtle.forward(step)
Esta solução permite controlar a dimensão da prisão (raio), a posição inicial da tartaruga (pos_x e pos_y), o ângulo inicial (ang), a dimensão de cada passo (step) e o número de passos da tartaruga (num). O código é fácil de entender: enquanto não tivermos esgotado o número de passos concedido, avançamos. Se ultrapassarmos o limite autorizado voltamos para trás na direção de onde partimos. Notar que a primitiva towards não altera a orientação, pelo que é necessário usar o setheading.
Se executarmos este programa o resultado não é muito entusiasmante: a tartaruga anda para trás e para a frente ao longo de uma linha. Tudo menos um caminhar aleatório. Vamos por isso pensar em melhorar o código. Começamos por coisas simples: mudar a forma e a cor da tartaruga e retirar o rasto.
def random_walk_prison_1(raio,pos_x,pos_y,ang,step,num):
turtle.setheading(ang)
turtle.shape('turtle')
turtle.color('blue')
turtle.penup()
turtle.goto(pos_x,pos_y)
for i in range(num):
if turtle.distance(pos_x, pos_y) > raio:
turtle.setheading(turtle.towards(pos_x,pos_y))
turtle.forward(step)
Não se pode dizer que esteja muito melhor. Vamos então introduzir alguma
variabilidade no caminhar da tartaruga, fazendo com que se movimente sem ser apenas para a frente e para trás.
def random_walk_prison_2(raio,pos_x,pos_y,ang,step,num):
turtle.setheading(ang)
turtle.shape('turtle')
turtle.color('blue')
turtle.penup()
turtle.goto(pos_x,pos_y)
for i in range(num):
if turtle.distance(pos_x, pos_y) > raio:
offset = random.randint(-10,10)
turtle.setheading(turtle.towards(pos_x,pos_y) + offset)
turtle.forward(step)
Como se pode ver recorremos ao método
randint do módulo
random.
Já nos parece mais razoável, mas podemos melhorar ainda o programa, desenhando a prisão. No nosso caso desenhamos uma circunferência de raio definido pelo utilizador. Também alteramos a espessura do traço.
def random_walk_prison_3(raio,pos_x,pos_y,ang,step,num):
# prisão
turtle.penup()
turtle.goto(pos_x,pos_y-raio-step)
turtle.pendown()
turtle.width(5)
turtle.pencolor('red')
turtle.circle(raio+step)
# tartaruga
turtle.setheading(ang)
turtle.shape('turtle')
turtle.color('blue')
turtle.penup()
turtle.hideturtle()
turtle.goto(pos_x,pos_y)
turtle.showturtle()
for i in range(num):
if turtle.distance(pos_x, pos_y) > raio:
offset = random.randint(-10,10)
turtle.setheading(turtle.towards(pos_x,pos_y) + offset)
turtle.forward(step)
E pronto… ou talvez não. Porque é que a tartaruga tem que ter o
centro da prisão sempre como referência?? Não tem, pois claro! Então vamos alterar isso.
def random_walk_prison_4(raio,pos_x,pos_y,ang,step,num):
# prisão
turtle.penup()
turtle.goto(pos_x,pos_y-raio-step)
turtle.pendown()
turtle.width(5)
turtle.pencolor('red')
turtle.circle(raio+step)
# tartaruga
turtle.setheading(ang)
turtle.shape('turtle')
turtle.color('blue')
turtle.penup()
turtle.goto(pos_x,pos_y)
for i in range(num):
if turtle.distance(pos_x, pos_y) + step >= raio:
offset = random.randint(-10,10)
turtle.setheading(turtle.heading() + 180 + offset )
print(turtle.heading())
turtle.forward(step)
Note como mandamos para trás a tartaruga.
A partir daqui … use a sua imaginação.