If you're seeing this message, it means we're having trouble loading external resources on our website.

Se você está atrás de um filtro da Web, certifique-se que os domínios *.kastatic.org e *.kasandbox.org estão desbloqueados.

Conteúdo principal

Passeios aleatórios

Antes de estudarmos as complexidades de vetores e movimentos baseados na física, vamos pensar sobre o significado de algo apenas se movendo pela tela. Vamos começar com uma das simulações de movimento mais conhecidas e mais simples: o passeio aleatório.
Imagine que você está se equilibrando no meio de uma trave olímpica. A cada dez segundos, você lança uma moeda. Cara, você dá um passo para frente. Coroa, dá um passo para trás. Isso é um passeio aleatório - um caminho definido por uma série de passos aleatórios. Pulando dessa trave para o chão, você poderia realizar um passeio aleatório em duas dimensões lançando a mesma moeda duas vezes com os seguintes resultados:
Lançamento 1Lançamento 2Resultado
CaraCaraAnda para a frente.
CaraCoroaAnda para a direita.
CoroaCaraAnda para a esquerda.
CoroaCoroaAnda para trás.
Sim, esse pode parecer um algoritmo particularmente pouco sofisticado. No entanto, passeios aleatórios podem ser usados para modelar fenômenos que ocorrem no mundo real, do movimento de moléculas em um gás até o comportamento de um apostador em um cassino. No nosso caso, vamos começar esse tópico estudando um passeio aleatório com três objetivos em mente.

O Objeto do Caminhante Aleatório (Walker)

Vamos rever alguns conceitos de Programação Orientada a Objectos (POO) criando um objecto Walker. Apenas vamos rever conceitos. Se você nunca trabalhou com POO antes, deveria dar uma olhada na seção sobre JavaScript Orientado a Objetos.
Um objeto em JavaScript é um tipo de dado que possui tanto propriedades como funcionalidades aderidas à ele através do seu protótipo. Esperamos projetar um objeto Walker que possa monitorar os próprios dados (onde ele existe na tela) e tem a capacidade de executar certas ações (como desenhar a si próprio ou dar um passo).
Para criar instâncias do Walker, precisamos definir um objeto Walker. Usaremos esse objeto como um cortador de biscoito, e cada nova instância Walker será um biscoito.
Vamos começar definindo o tipo de objeto Walker. O Walker só precisa de duas informações - um número com a sua coordenada X e outro número com a sua coordenada Y. Vamos definir os valores das coordenadas no construtor da função e vamos colocá-las no centro da tela.
var Walker = function() {
    this.x = width/2;
    this.y = height/2;
};
Além de monitorar os próprios eixos X e Y, nosso objeto Walker também terá métodos que podemos utilizar para executar ações. O primeiro método permite que o objeto se mostre como um ponto preto na tela. Lembre-se que adicionamos métodos à um objeto em JavaScript anexando-os ao prototype do objeto.
Walker.prototype.display = function() {
    stroke(0, 0, 0);
    point(this.x, this.y);
};
O segundo método faz com que o objeto Walker dê um passo. Nesse momento as coisas ficam mais interessantes. Lembra do chão onde damos os nossos passos aleatórios? Bem, agora podemos usar a tela com essa mesma capacidade. Existem quatro passos possíveis. Um passo para a direita pode ser simulado ao adicionarmos x (x++); para a esquerda ao reduzirmos x (x--); em frente ao descermos um pixel (y++); e para trás ao subirmos um pixel (y--). Como escolhemos entre essas quatro opções? Há pouco falamos que poderíamos jogar duas moedas. Ao processar JavaScript, entretanto, quando desejamos escolher aleatoriamente dentro de uma lista de opções, podemos escolher um número aleatório utilizando random().
Walker.prototype.walk = function() {
    var choice = floor(random(4));
};
A linha de código acima seleciona um ponto e um número aleatório entre 0 e 4 e o converte em um novo número utilizando floor(), com um resultado de 0, 1, 2 ou 3. Tecnicamente, o maior número nunca será 4.0, mas preferivelmente 3.999999999 (com tantos noves quanto casas decimais existirem); já que floor() retorna o número inteiro mais próximo que é menor ou igual, o maior resultado que podemos obter é 3. Depois, podemos dar o passo apropriado (esquerda, direita, para cima ou para baixo) dependendo de qual número aleatório foi selecionado.
Walker.prototype.walk = function() {
    var choice = floor(random(4));
    if (choice === 0) {
        this.x++;
    } else if (choice === 1) {
        this.x--;
    } else if (choice === 2) {
        this.y++;
    } else {
        this.y--;
    } 
};
Agora que nós escrevemos a classe, é hora de criar um verdadeiro objeto Walker em nosso programa. Supondo que estamos querendo modelar um único passeio aleatório, nós definimos e inicializamos uma variável global do tipo Walker chamando a função construtora com o novo operador.
var w = new Walker();
Agora, para fazer o caminhador realmente fazer alguma coisa, nós definimos a função draw() que diz a ele para dar um passo e se desenhar a cada vez que é chamada:
draw = function() {
    w.walk();
    w.display();
};
Como nós não chamamos o método background() na função draw, nós podemos ver o rastro do passeio aleatório em nossa tela:

Aprimorando o Caminhante Aleatório (Walker)

Existem alguns aprimoramentos que podemos fazer ao caminhante aleatório. Primeiro, as escolhas de passo do walker são limitadas a quatro opções - para cima, para baixo, para a esquerda e para a direita. Entretanto, qualquer pixel na janela tem oito vizinhos possíveis e uma nona possibilidade é manter-se no mesmo lugar.
Imagem da Natureza do Código
Figura I.1
Para implementar um objeto Walker que possa andar em direção a qualquer pixel vizinho (ou permanecer no lugar), podemos escolher um número entre 0 e 8 (nove possibilidades). Entretanto, uma maneira mais eficiente de escrever o código seria simplesmente pegar três passos possíveis ao longo do eixo X (-1, 0 ou 1) e três possibilidades de passo ao longo do eixo Y.
Walker.prototype.walk = function() {
  var stepx = floor(random(3))-1;
  var stepy = floor(random(3))-1;
  this.x += stepx;
  this.y += stepy;
};
Aprofundando um pouco mais, poderíamos usar um valor decimal para x e y ao invés e mover-se de acordo com um valor aleatório arbitrário entre -1 e 1, se nosso ambiente pudesse mostrar a diferença entre "2.2" e "2.4":
Walker.prototype.walk = function() {
  var stepx = random(-1, 1);
  var stepy = random(-1, 1);
  this.x += stepx;
  this.y += stepy;
};
Todas essa variações do caminhante aleatório "tradicional" têm uma coisa em comum: em qualquer momento, a probabilidade do Walker dar um passo em uma direção específica é igual à probabilidade do Walker dar um passo em qualquer outra direção. Em outras palavras, se existem quatro passos possíveis, existe 1 chance em 4 (25%) de que ele irá dar esse passo. Com nove passos possíveis, a chance muda para 1 em 9 (ou 11,1%).
Convenientemente, é dessa forma que a função random() funciona. Seu gerador de número aleatório produz o que é conhecido como uma distribuição "uniforme" dos números. Podemos testar essa distribuição com um programa que conta cada vez que um número aleatório é selecionado e o coloca no gráfico como a altura de uma barra:
Todas as barras têm a mesma altura após alguns minutos de teste? Provavelmente não. Nossa amostra (a quantidade de números aleatórios que escolhemos) é bem pequena e existem algumas discrepâncias ocasionais onde determinados números são selecionados com mais frequência. Ao longo do tempo, com um bom gerador de números aleatórios, eles iriam se nivelar.
Os números aleatórios que obtemos da função random() não são verdadeiramente aleatórios; portanto, eles são conhecidos como “pseudoaleatórios.” Tais números são o resultado de uma função matemática que simula a aleatoriedade. Essa função produziria um padrão ao longo do tempo, mas esse período é tão longo que para nós ela funciona tão bem quanto uma aleatoriedade pura!
Na próxima seção, falaremos sobre as diferentes formas que podemos criar caminhantes com "tendências" a se locomover em determinadas direções. Antes disso, há um desafio esperando por você!

Este curso "Natural Simulations" é um derivado do "The Nature of Code" por Daniel Shiffman, usado sob a Creative Commons Attribution-NonCommercial 3.0 Unported License.

Quer participar da conversa?

Você entende inglês? Clique aqui para ver mais debates na versão em inglês do site da Khan Academy.