Nesse problema, você recriará uma das mais belas histórias folclóricas, a saber, a clássica competição entre a lebre e a tartaruga. Você utilizará geração de números aleatórios para desenvolver uma simulação desse memorável evento.
Nossos competidores começam a corrida no quadrado 01 de 70 quadrados. Cada quadrado representa uma posição possível ao longo do percurso da competição. A linha de chegada está no quadrado 70. O primeiro competidor a alcançar ou passar o quadrado 70 é recompensado com um cesto de cenouras frescas e alface. O percurso envolve subir uma montanha escorregadia, de modo que, ocasionalmente, os competidores perdem terreno.
Utilize variáveis para monitorar a posição dos animais (isto é, os números de posição são 01 a 70). Inicie com cada animal na posição 01 (isto é, a partida). Se um animal escorrega para a esquerda antes do quadrado 01, mova o animal de volta para o quadrado 01.
Gere as porcentagens na tabela precedente produzindo um inteiro aleatório, i, no intervalo 1 <= i <= 10. Para a tartaruga, realize uma "caminhada rápida" quando 1 <= i <= 5, um "escorregão" quando 6 <= i <= 7 ou uma "caminhada lenta" quando 8 <= i <= 10. Utilize uma técnica semelhante para mover a lebre.
Inicie a corrida imprimindo
Para cada movimentação dos competidores imprima uma linha de 70 posições mostrando a letra T na posição da tartaruga e a letra L na posição da lebre. De vez em quando, os competidores aterrissarão no mesmo quadrado. Nesse caso, a tartaruga morde a lebre e o programa deve imprimir AI!!! começando nessa posição. Todas as outras posições diferentes de T, L ou AI!!! (no caso de um empate na mesma posição) devem estar em branco.
Depois que cada linha é impressa, teste se o animal alcançou ou passou o quadrado 70. Se isso ocorreu, imprima o vencedor e encerre a simulação. Se a tartaruga ganhar, imprima A TARTARUGA VENCE!!! ÊH!!! Se a lebre ganhar, imprima A LEBRE GANHA. OH. Se ambos os animais ganharem, você pode querer favorecer a tartaruga ou imprimir TEMOS UM EMPATE.
A coordenação dos competidores poderá ser feita através de um controle que faz uso de Semáforos (java.util.concurrent.Semaphore
). Assim, a cada avanço do personagem do decorrer da corrida, há a garantia que cada participante irá percorrer a pista de forma coerente, ou seja, há um mecanismo de cooperação entre as Threads implementado no controle. O primeiro que chegar na posição 70 será o vencedor.
Animal | Tipo de Movimento | Porcentagem do Tempo | Movimento Real |
---|---|---|---|
Tartaruga | Caminhada rápida | 50% | 3 quadrados à direita |
Escorregão | 20% | 6 quadrados à esquerda | |
Caminhada lenta | 30% | 1 quadrados à direita | |
Lebre | Dormindo | 20% | Sem nenhum movimento |
Salto grande | 20% | 9 quadrados à direita | |
Escorregão grande | 10% | 12 quadrados à esquerda | |
Salto pequeno | 30% | 1 quadrados à direita | |
Escorregão pequeno | 20% | 2 quadrados à esquerda |
Deitel, H. M. (2003). Java, como programar. 4ª edição. Porto Alegre: Bookman. 1.386 páginas.
/**
* Copyright (C) 2009/2025 - Cristiano Lehrer (cristiano@ybadoo.com.br)
* Ybadoo - Solucoes em Software Livre (www.ybadoo.com.br)
*
* Permission is granted to copy, distribute and/or modify this document
* under the terms of the GNU Free Documentation License, Version 1.3
* or any later version published by the Free Software Foundation; with
* no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.
* A copy of the license is included in the section entitled "GNU
* Free Documentation License".
*/
package com.ybadoo.tutoriais.poo;
import java.util.concurrent.Semaphore;
/**
* Encapsula dados e comportamento em relacao aos competidores num autodromo
* garantindo exclusao mutua
*/
public class Autodromo
{
/**
* Flag para indicar o fim da corrida
*/
private boolean fimCorrida;
/**
* Posicao da lebre na corrida
*/
private int posicaoLebre;
/**
* Posicao da tartaruga na corrida
*/
private int posicaoTartaruga;
/**
* Semaforo para os movimentos da lebre
*/
Semaphore semaphoreLebre;
/**
* Semaforo para os movimentos da tartaruga
*/
Semaphore semaphoreTartaruga;
/**
* Construtor padrao da classe Autodromo.
*/
public Autodromo()
{
this.posicaoLebre = 1;
this.posicaoTartaruga = 1;
this.fimCorrida = false;
this.semaphoreTartaruga = new Semaphore(0);
this.semaphoreLebre = new Semaphore(1);
System.out.println("BANG !!!!!\nE ELES PARTIRAM !!!!!");
}
/**
* Altera a posicao da Lebre em relacao a um numero aleatorio
*
* @param aleatorio parametro usado como criterio para gerar obstaculos
* ao compeditor Lebre
*/
private void alteraPosicaoLebre(int aleatorio)
{
if((aleatorio >= 0) && (aleatorio <= 1))
{
// Lebre dormindo - posicao nao muda
}
else if((aleatorio >= 2) && (aleatorio <= 3))
{
// salto grande
this.posicaoLebre += 9;
}
else if((aleatorio >= 4) && (aleatorio <= 4))
{
// escorregao grande
this.posicaoLebre -= 12;
if(this.posicaoLebre <= 0)
{
this.posicaoLebre = 1;
}
}
else if((aleatorio >= 5) && (aleatorio <= 7))
{
// salto pequeno
this.posicaoLebre += 1;
}
else if((aleatorio >= 8) && (aleatorio < 10))
{
// escorregao pequeno
this.posicaoLebre -= 2;
if(this.posicaoLebre <= 0)
{
this.posicaoLebre = 1;
}
}
}
/**
* Altera a posicao da Tartaruga em relacao a um dado numero aleatorio
*
* @param aleatorio parametro usado como criterio para gerar obstaculos
* ao compeditor Tartaruga
*/
private void alteraPosicaoTartaruga(int aleatorio)
{
if((aleatorio >= 0) && (aleatorio <= 4))
{
this.posicaoTartaruga += 3; // caminhada rapida
}
else if((aleatorio >= 5) && (aleatorio <= 6))
{
this.posicaoTartaruga -= 6; // escorregao
if(this.posicaoTartaruga <= 0)
{
this.posicaoTartaruga = 1;
}
}
else if((aleatorio >= 7) && (aleatorio < 10))
{
this.posicaoTartaruga += 1; // caminhada lenta
}
}
/**
* Apresentar a situacao da corrida para o publico
*/
private void escrever()
{
if(this.posicaoLebre == this.posicaoTartaruga)
{
for(int i = 1; i <= this.posicaoLebre; i++)
{
System.out.print("_");
}
System.out.println("AI !!!");
}
else
{
int limite = (this.posicaoLebre > this.posicaoTartaruga)
? this.posicaoLebre : this.posicaoTartaruga;
for(int i = 1; i <= limite; i++)
{
if(i == this.posicaoLebre)
{
System.out.print("L");
}
else if(i == this.posicaoTartaruga)
{
System.out.print("T");
}
else
{
System.out.print("_");
}
}
System.out.println();
}
}
/**
* Movimenta a Lebre fazendo com que avance na corrida. Uma alteracao de
* movimentacao da lebre ocorre a cada avanco, podendo ser de forma
* benefica ou entao de modo a retroceder o personagem na corrida. A
* escolha entre um modo ou outro eh feita de forma aleatoria.
*
* @param avanco refere-se o quanto o competidor avanca na competicao.
* @return retorna TRUE se a corrida acabou, ou seja se o competidor
* alcancou a posicao maior ou igual a 70.
*/
public boolean movimentaLebre(int avanco)
{
try
{
this.semaphoreTartaruga.acquire();
// o metodo abaixo pode mudar a posicao da lebre
alteraPosicaoLebre(avanco);
if(!this.fimCorrida)
{
escrever();
}
this.semaphoreLebre.release();
}
catch(InterruptedException exception)
{
exception.printStackTrace();
}
if(this.posicaoLebre >= 70)
{
this.fimCorrida = true;
}
return this.fimCorrida;
}
/**
* Movimenta a Tartaruga fazendo com que avance na corrida. Uma alteracao
* de movimentacao da Tartaruga ocorre a cada avanco, podendo ser de forma
* benefica ou entao de modo a retroceder o personagem na corrida. A
* escolha entre um modo ou outro eh feita de forma aleatoria.
*
* @param avanco refere-se o quanto o competidor avanca na competicao.
* @return retorna TRUE se a corrida acabou, ou sejam se o competidor
* alcancou a posicao maior ou igual a 70.
*/
public boolean movimentaTartaruga(int avanco)
{
try
{
this.semaphoreLebre.acquire();
// o metodo abaixo muda a posicao da tartaruga
alteraPosicaoTartaruga(avanco);
if(!this.fimCorrida)
{
escrever();
}
this.semaphoreTartaruga.release();
}
catch(InterruptedException exception)
{
exception.printStackTrace();
}
if(this.posicaoTartaruga >= 70)
{
this.fimCorrida = true;
}
return this.fimCorrida;
}
/**
* Anuncia o vencedor da competicao.
*/
public void vencedor()
{
if(this.posicaoTartaruga > this.posicaoLebre)
{
System.out.println("A TARTARUGA VENCE !!! ÊH !!!");
}
else if(this.posicaoTartaruga < this.posicaoLebre)
{
System.out.println("A LEBRE GANHA. OH");
}
else
{
System.out.println("TEMOS UM EMPATE");
}
}
}
/**
* Copyright (C) 2009/2025 - Cristiano Lehrer (cristiano@ybadoo.com.br)
* Ybadoo - Solucoes em Software Livre (www.ybadoo.com.br)
*
* Permission is granted to copy, distribute and/or modify this document
* under the terms of the GNU Free Documentation License, Version 1.3
* or any later version published by the Free Software Foundation; with
* no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.
* A copy of the license is included in the section entitled "GNU
* Free Documentation License".
*/
package com.ybadoo.tutoriais.poo;
/**
* Encapsula dados e comportamentos referentes a classe do compeditor
* Tartaruga. O avanco conforme a corrida se desenvolve eh garatinda por
* um controle sendo um objeto da classe Autodromo
*/
public class Tartaruga extends Thread
{
/**
* Instancia do autodromo
*/
private Autodromo autodromo;
/**
* Flag para indicar o fim da corrida
*/
private boolean fim;
/**
* Construtor padrao da classe Tartaruga
*
* @param autodromo parametro de controle do competidor Tartaruga numa
* corrida
*/
public Tartaruga(Autodromo autodromo)
{
this.fim = false;
this.autodromo = autodromo;
}
/**
* Metodo especializado da classe Java Thread que define o comportamento
* do competidor Tartaruga
*/
public void run()
{
int avanca = 0;
while(!this.fim)
{
avanca = (int)(Math.random() * 10);
this.fim = this.autodromo.movimentaTartaruga(avanca);
}
}
}
/**
* Copyright (C) 2009/2025 - Cristiano Lehrer (cristiano@ybadoo.com.br)
* Ybadoo - Solucoes em Software Livre (www.ybadoo.com.br)
*
* Permission is granted to copy, distribute and/or modify this document
* under the terms of the GNU Free Documentation License, Version 1.3
* or any later version published by the Free Software Foundation; with
* no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.
* A copy of the license is included in the section entitled "GNU
* Free Documentation License".
*/
package com.ybadoo.tutoriais.poo;
/**
* Encapsula dados e comportamento em relacao a classe Lebre. O controle do
* avanco do compeditor Lebre eh feita atraves de um objeto da classe
* Autodromo
*/
public class Lebre extends Thread
{
/**
* Instancia do autodromo
*/
private Autodromo autodromo;
/**
* Flag para indicar o fim da corrida
*/
private boolean fim;
/**
* Construtor padrao da classe Lebre
*
* @param autodromo parametro de controle do competidor Lebre numa corrida
*/
public Lebre(Autodromo autodromo)
{
this.fim = false;
this.autodromo = autodromo;
}
/**
* Metodo especializado da classe Java Thread que define o comportamento
* do competidor Lebre
*/
public void run()
{
int avanca = 0;
while(!this.fim)
{
avanca = (int)(Math.random() * 10);
this.fim = this.autodromo.movimentaLebre(avanca);
}
}
}
/**
* Copyright (C) 2009/2025 - Cristiano Lehrer (cristiano@ybadoo.com.br)
* Ybadoo - Solucoes em Software Livre (www.ybadoo.com.br)
*
* Permission is granted to copy, distribute and/or modify this document
* under the terms of the GNU Free Documentation License, Version 1.3
* or any later version published by the Free Software Foundation; with
* no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.
* A copy of the license is included in the section entitled "GNU
* Free Documentation License".
*/
package com.ybadoo.tutoriais.poo;
/**
* Encapsula dados e comportamente relacionado a uma corrida entre dois
* personagens
*/
public class Corrida
{
/**
* Metodo principal da linguagem de programacao Java
*
* @param args argumentos da linha de comando (nao utilizado)
*/
public static void main(String[] args)
{
Autodromo autodromo = new Autodromo();
Lebre lebre = new Lebre(autodromo);
Tartaruga tartaruga = new Tartaruga(autodromo);
tartaruga.start();
lebre.start();
try
{
tartaruga.join();
lebre.join();
}
catch(InterruptedException exception)
{
exception.printStackTrace();
}
autodromo.vencedor();
}
}