Ybadoo - Soluções em Software Livre
Tutoriais
Programação Orientada a Objetos

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

BANG !!!!!
E ELES PARTIRAM !!!!!

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.

 
Tabela 1: Regras para ajustar as posições da tartaruga e da lebre
AnimalTipo de MovimentoPorcentagem do TempoMovimento Real
TartarugaCaminhada rápida50%3 quadrados à direita
 Escorregão20%6 quadrados à esquerda
 Caminhada lenta30%1 quadrados à direita
LebreDormindo20%Sem nenhum movimento
 Salto grande20%9 quadrados à direita
 Escorregão grande10%12 quadrados à esquerda
 Salto pequeno30%1 quadrados à direita
 Escorregão pequeno20%2 quadrados à esquerda
 

Deitel, H. M. (2003). Java, como programar. 4ª edição. Porto Alegre: Bookman. 1.386 páginas.

 

Arquivo Autodromo.java

/**
 * Copyright (C) 2009/2024 - 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");
    }
  }
}

Arquivo Tartaruga.java

/**
 * Copyright (C) 2009/2024 - 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);
    }
  }
}

Arquivo Lebre.java

/**
 * Copyright (C) 2009/2024 - 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);
    }
  }
}

Arquivo Corrida.java

/**
 * Copyright (C) 2009/2024 - 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();
  }
}

Saída

BANG !!!!!
E ELES PARTIRAM !!!!!
_AI !!!
TL
__AI !!!
_TL
___AI !!!
L_T
L____T
L____T
L_______T
_L______T
_LT
___AI !!!
T_L
_AI !!!
L__T
_L_T
_L__T
____T_____L
_____T____L
_____T_____L
________T__L
________T__L
____________AI !!!
_________L_T
_________L__T
_________L__T
_________L_____T
L______________T
L________T
L________T
L___________T
L___________T
L______________T
L______________T
L_______________T
_________L______T
_________LT
___________AI !!!
__________L__T
___________L_T
_______T___L
_______T____L
__________T_L
__________T__L
___________T_L
___________T__________L
______________T_______L
______________T_____L
_______________T____L
_______________T____L
__________________T_L
__________________T__________L
_____________________T_______L
_____________________T________________L
_______________T______________________L
_______________T____________________L
__________________T_________________L
__________________T_____L
___________________T____L
___________________T_____________L
_____________T___________________L
_____________T_________________L
________________T______________L
________________T______________L
___________________T___________L
___________________T_________L
______________________T______L
______________________T______L
________________T____________L
________________T_____________L
___________________T__________L
___________________T__________L
_____________T________________L
_____________T_________________________L
_______T_______________________________L
_______T_______________________________L
__________T____________________________L
__________T____________________________L
___________T___________________________L
___________T___________________________L
______________T________________________L
______________T________________________L
________T______________________________L
________T_______________________________L
___________T____________________________L
___________T____________________________L
______________T_________________________L
______________T__________________________L
_______________T_________________________L
_______________T_________________________L
__________________T______________________L
__________________T_______________________L
___________________T______________________L
___________________T____________________L
____________________T___________________L
____________________T_______L
_____________________T______L
_____________________T____L
_______________T__________L
_______________T___________L
_________T_________________L
_________T_________________L
__________T________________L
__________T_________________L
_____________T______________L
_____________T______________L
________________T___________L
________________T____________________L
___________________T_________________L
___________________T_______________L
______________________T____________L
______________________TL
________________T______L
________________T______L
_________________T_____L
_________________T___L
____________________TL
____________________T_L
______________________LT
________________________AI !!!
_______________________L__T
________________________L_T
________________________L____T
_____________________________T___L
______________________________T__L
_____________________L________T
_____________________L___________T
_____________________L___________T
_____________________L______________T
_________L__________________________T
_________L____________________T
__________L___________________T
__________L_____________T
___________________L____T
__________________TL
_________________LT
_________________L_T
_______________L___T
_______________L____T
________________L___T
______________T_L
______________T__L
__________________AI !!!
__________________AI !!!
_________________LT
___________________AI !!!
__________________L__T
___________________L_T
___________________L____T
_________________L______T
_________________L_______T
_________________L_______T
_________________L________T
___________________________AI !!!
__________________________LT
____________________________AI !!!
___________________________L__T
____________________________L_T
________________________T___L
________________________T____L
___________________________T_L
___________________________T__L
_______________________________AI !!!
____________________________L_T
____________________________L__T
_____________________________L_T
_____________________________L____T
_____________________________L____T
_____________________________L_______T
_____________________________L_______T
_____________________________L__________T
___________________________L____________T
___________________________L_______________T
_________________________L_________________T
_________________________L____________________T
__________________________________L___________T
__________________________________L____________T
___________________________________________L___T
___________________________________________L____T
_________________________________________L______T
_________________________________________L_________T
__________________________________________L________T
__________________________________________L__T
______________________________L______________T
______________________________L_________________T
____________________________L___________________T
____________________________L____________________T
__________________________L______________________T
__________________________L_________________________T
___________________________L________________________T
___________________________L___________________________T
____________________________L__________________________T
____________________________L_____________________________T
____________________________L_____________________________T
____________________________L______________________________T
_____________________________L_____________________________T
_____________________________L________________________________T
___________________________L__________________________________T
___________________________L_____________________________________T
____________________________L____________________________________T
____________________________L______________________________T
____________________________L______________________________T
____________________________L_______________________________T
__________________________L_________________________________T
__________________________L____________________________________T
__________________________L____________________________________T
__________________________L_____________________________________T
__________________________L_____________________________________T
__________________________L______________________________________T
___________________________________L_____________________________T
___________________________________L________________________________T
_________________________________L__________________________________T
_________________________________L_____________________________________T
A TARTARUGA VENCE !!! ÊH !!!