quinta-feira, 15 de outubro de 2015

Uma tartaruga na prisão

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:
01.import turtle
02.import random
03. 
04.def random_walk_prison(raio,pos_x,pos_y,ang,step,num):
05.    turtle.penup()
06.    turtle.goto(pos_x,pos_y)
07.    turtle.setheading(ang)
08.    turtle.pendown()
09.    for i in range(num):
10.        if turtle.distance(pos_x, pos_y) > raio:
11.            turtle.setheading(turtle.towards(pos_x,pos_y))
12.        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.
01.def random_walk_prison_1(raio,pos_x,pos_y,ang,step,num):
02.    turtle.setheading(ang)
03.    turtle.shape('turtle')
04.    turtle.color('blue')
05.    turtle.penup()
06.    turtle.goto(pos_x,pos_y)
07.    for i in range(num):
08.        if turtle.distance(pos_x, pos_y) > raio:
09.            turtle.setheading(turtle.towards(pos_x,pos_y))
10.        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.
01.def random_walk_prison_2(raio,pos_x,pos_y,ang,step,num):
02.    turtle.setheading(ang)
03.    turtle.shape('turtle')
04.    turtle.color('blue')   
05.    turtle.penup()
06.    turtle.goto(pos_x,pos_y)
07.    for i in range(num):
08.        if turtle.distance(pos_x, pos_y) > raio:
09.            offset = random.randint(-10,10)
10.            turtle.setheading(turtle.towards(pos_x,pos_y) + offset)
11.        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.
01.def random_walk_prison_3(raio,pos_x,pos_y,ang,step,num):
02.    # prisão
03.    turtle.penup()
04.    turtle.goto(pos_x,pos_y-raio-step)
05.    turtle.pendown()
06.    turtle.width(5)
07.    turtle.pencolor('red')
08.    turtle.circle(raio+step)
09.    # tartaruga
10.    turtle.setheading(ang)
11.    turtle.shape('turtle')
12.    turtle.color('blue')   
13.    turtle.penup()
14.    turtle.hideturtle()
15.    turtle.goto(pos_x,pos_y)
16.    turtle.showturtle()
17.    for i in range(num):
18.        if turtle.distance(pos_x, pos_y) > raio:
19.            offset = random.randint(-10,10)
20.            turtle.setheading(turtle.towards(pos_x,pos_y) + offset)
21.        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.
01.def random_walk_prison_4(raio,pos_x,pos_y,ang,step,num):
02.    # prisão
03.    turtle.penup()
04.    turtle.goto(pos_x,pos_y-raio-step)
05.    turtle.pendown()
06.    turtle.width(5)
07.    turtle.pencolor('red')
08.    turtle.circle(raio+step)
09.    # tartaruga
10.    turtle.setheading(ang)
11.    turtle.shape('turtle')
12.    turtle.color('blue')   
13.    turtle.penup()
14.    turtle.goto(pos_x,pos_y)
15.    for i in range(num):
16.        if turtle.distance(pos_x, pos_y) + step >= raio:
17.            offset = random.randint(-10,10)
18.            turtle.setheading(turtle.heading() + 180 + offset )
19.            print(turtle.heading())
20.        turtle.forward(step)
Note como mandamos para trás a tartaruga. A partir daqui … use a sua imaginação.

Sem comentários:

Enviar um comentário