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

Sem comentários:

Enviar um comentário