Pontifícia Universidade Católica de São Paulo Departamento de Ciência da Computação Apontamento 20 Setembro de 2004 LP: Laboratório de Programação Prof. ISVega Milhao da Computação II: Níveis e Aluno CONTEÚDO 20.1 Estrutura Básica do Jogo . . . . . . . . . 20.2 Base de Perguntas . . . . . . . . . . . . . 20.2.1Descrição da Base de Perguntas . 20.2.2Teste da Base de Perguntas . . . . 20.3 Modelo dos Níveis do Questionário . . . 20.4 Modelagem do Aluno . . . . . . . . . . . 20.5 Modelo do Jogo Milhão da Computação 20.5.1Estrutura Interna de um Jogo . . 20.5.2Geração de Perguntas . . . . . . . 20.5.3Teste da Estrutura do Jogo . . . . Exercícios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1 3 3 6 7 11 11 12 14 15 17 20.1 Estrutura Básica do Jogo A estrutura básica do jogo contém as classes Jogo, BaseDePergunta e Jogador (Figura 20.1). 1 Laboratório de Programação Setembro de 2004 { Vector } com size( ) >= 4 aluno que responde às perguntas { Vector } com size( ) >= 5 { Vector } com size( ) >= 4 cria cada pergunta de um nível { Vector } com size( ) >= 5 pergunta apresentada para o aluno Figura 20.1: Classes iniciais do jogo (diagrama de classes UML no BlueJ). Este diagrama revela as principais abstrações que compõem a estrutura do jogo. Mapa de Execução Inicial Em termos dinâmicos, o comportamento do jogo pode ser ilustrado pelo mapa de execução da Figura 20.2. aumentar(acumulado) [ ordem = correta ] mostrar(acumulado) perguntar [ ∃ pergunta ] gerar pergunta iniciarJogo mostrar(acumulado) responder(ordem) pergunta mostrada parar [ ordem ≠ correta ] ERROU dividir(acumulado) [¬ ∃ pergunta ] GANHOU PAROU mostrar(acumulado) Figura 20.2: Mapa de execução inicial. Após iniciar o jogo, gera-se uma pergunta a ser apresentada para o aluno. Diante da pergunta formulada pelo sistema, o jogador pode responder ou parar. Se optar c Copyright °1999-2004, Dr. Italo S. Vega 20-2 Laboratório de Programação Setembro de 2004 por responder, a ordem da alternativa pode ou não ser a correta. A rota de cor verde destaca os eventos no caso do aluno responder a todas as perguntas corretamente. Visualização de uma Pergunta A parte inicial do mapa carrega as bases de perguntas, configura os níveis do jogo (a partir destas bases), e gera e apresenta a primeira pergunta do nível Fácil. A Figura 20.3 faz a sobreposição destes eventos e o diagrama de classes UML. configurar pergunta mostrada gerar pergunta iniciarJogo [ ∃ pergunta ] carregar perguntar Figura 20.3: Mapa de execução do início do jogo até a apresentação de uma pergunta. Esta rota servirá de base para o primeiro refinamento do modelo da aplicação. 20.2 Base de Perguntas O jogo contém quatro bases de perguntas: uma para cada nível (Fácil, Médio e Difícil) e uma adicional para a pergunta final (nível Milhão). 20.2.1 Descrição da Base de Perguntas As perguntas de uma base são armazenadas, internamente, em um Vector conhecido por perguntas (Figura 20.1): c Copyright °1999-2004, Dr. Italo S. Vega 20-3 Laboratório de Programação Setembro de 2004 hBaseDePerguntas: estrutura de perguntas i≡ public Vector perguntas; É possível recuperar a i-ésima pergunta da base executando-se o método obter(i). Os níveis do jogo podem ser configurados executando-se este método: hBaseDePerguntas: obter pergunta i≡ public Pergunta obter( int i ) { // @pre: int n = perguntas.size(); assert( (0 <= i)&&(i < n) ); // @do: return (Pergunta)perguntas.get( i ); } Observa-se que a ordem i da pergunta deve estar no intervalo 0 . . n. Esta dimensão é estabelecida pela execução do método carregar() – definido a seguir. Carga da Base de Perguntas O mecanismo de carga preenche a estrutura perguntas (um Vector) com um universo de perguntas, dependendo do nome da base: h carregar i≡ public void carregar( String nivel ) { // @pre: assert( "FACIL".equals( nivel ) || "MEDIO".equals( nivel ) || "DIFICIL".equals( nivel ) || "MILHAO".equals( nivel ) ); // @do: if( "FACIL".equals( nivel ) ) { carregarBaseFacil(); } if( "MEDIO".equals( nivel ) ) { carregarBaseMedio(); } if( "DIFICIL".equals( nivel ) ) { carregarBaseDificil(); } if( "MILHAO".equals( nivel ) ) { carregarBaseMilhao(); } } Os métodos carregarBaseXXX criam perguntas e as inserem no Vector apontado pela variável perguntas. Exemplo 20.1 O método carregarBaseMilhao() pode ser codificado da seguinte forma: c Copyright °1999-2004, Dr. Italo S. Vega 20-4 Laboratório de Programação Setembro de 2004 h carregar milhão i≡ public void carregarBaseMilhao() { Pergunta nova = new Pergunta( "Um objeto..." ); nova.definirAlternativa( "É uma variável." ); nova.definirAlternativa( "É uma classe." ); nova.definirAlternativa( "Só tem atributos." ); nova.definirAlternativaCorreta( "Realiza computações." ); perguntas.add(nova); // @post: assert( perguntas.size() >= 1 ); } Após criar a nova pergunta, suas alternativas são definidas (inclusive a correta) e a referência para ela inserida no Vector apontado pela variável perguntas da base. ¨ Embaralhamento das Perguntas Uma vez carregadas as perguntas da base, pode-se embaralhá-las executando-se o método: hBaseDePerguntas: embaralhar perguntasi≡ public void embaralhar() { // @pre: assert( perguntas.size() > 0 ); // @do: Collections.shuffle( perguntas ); } A tecnologia Java oferece um mecanismo denominado Collections capaz de embaralhar um Vector passado como argumento na execução do método shuffle(). Este mecanismo provoca a importação da classe java.util.Collections, explicitada mais adiante. Construtor da Base de Perguntas O construtor se encarrega de criar o Vector utilizado para armazenar as perguntas da base: hBaseDePerguntas: construtori≡ public BaseDePerguntas() { // @do: perguntas = new Vector(); } O construtor garante que, após a sua execução, a estrutura Vector apontada pela variável perguntas terá sido criada. Dependências Externas da Base de Perguntas Devido à estrutura perguntas, devese importar a classe Vector. Além disso, o uso do mecanismo de embaralhamento c Copyright °1999-2004, Dr. Italo S. Vega 20-5 Laboratório de Programação Setembro de 2004 de perguntas estabelece a dependência em relação à classe Collections: hBaseDePerguntas: dependências externasi≡ import java.util.Vector; import java.util.Collections; 20.2.2 Teste da Base de Perguntas Para testar a classe BaseDePerguntas, deve-se instanciar um objeto de teste, carregar um nível, embaralhar e mostrar uma das perguntas. O construtor do teste instancia quatro bases de perguntas: h TesteBaseDePerguntas: construtor i≡ public TesteBaseDePerguntas() { // @do: criação das bases facil = new BaseDePerguntas(); medio = new BaseDePerguntas(); dificil = new BaseDePerguntas(); milhao = new BaseDePerguntas(); } Para visualizar os efeitos do teste, o seguinte método será utilizado para mostrar os enunciados das perguntas de uma base: h TesteBaseDePerguntas: visualização de enunciados i≡ public void mostrarEnunciados( BaseDePerguntas base ) { for( int i = 0; i < base.perguntas.size(); i++ ) { Pergunta p = base.obter( i ); System.out.println( p.enunciado ); } System.out.println( ".........." ); } O cenário1() carrega as perguntas de cada uma das bases. No final, o cenário mostra os enunciados das perguntas da base Milhão: h TesteBaseDePerguntas: cenário 1 i≡ public void cenario1() { // @do: carga das bases facil.carregar( "FACIL" ); medio.carregar( "MEDIO" ); dificil.carregar( "DIFICIL" ); milhao.carregar( "MILHAO" ); System.out.println("> ENUNCIADOS da base milhao:" ); mostrarEnunciados( milhao ); } c Copyright °1999-2004, Dr. Italo S. Vega 20-6 Laboratório de Programação Setembro de 2004 O cenário2() embaralha as perguntas da base Fácil, mostrando os enunciados antes e depois do embaralhamento: h TesteBaseDePerguntas: cenário 2 i≡ public void cenario2() { // @do: embaralhamento System.out.println("> ANTES de embaralhar o nivel Facil:" ); mostrarEnunciados( facil ); facil.embaralhar(); System.out.println("> DEPOIS de embaralhar o nivel Facil:" ); mostrarEnunciados( facil ); } O cenário3() recupera a pergunta 0 da base fácil, apresenta-a no terminal e a retorna para que uma ação possa ser tomada sobre ela (responder ou parar): h TesteBaseDePerguntas: cenário 3 i≡ public Pergunta cenario3() { Pergunta p = facil.obter( 0 ); p.mostrar(); return p; } 20.3 Modelo dos Níveis do Questionário Objetos da Classe Nível objeto da classe Nivel. Cada nível do questionário será representado por um Exemplo 20.2 O nível Fácil pode ser representado pelo objeto facil da classe Nivel (Figura 20.4). Fácil <<instância>> O que é computação? É um cálculo. <<detalhes>> É um procedimento. É uma rotina. É um método. RESPONDER PARAR 1.000 0 Figura 20.4: Representação do nível Fácil pelo objeto facil. c Copyright °1999-2004, Dr. Italo S. Vega 20-7 Laboratório de Programação Setembro de 2004 Internamente, observa-se que o objeto facil contém três variáveis: • nome, que armazena um String representando o nome do nível, • perguntas, um Vector que armazena as perguntas do nível, • aposta, indicando o valor da aposta das perguntas do nível. ¨ Variáveis da classe Nivel Para que seja construido um objeto da classe Nivel contendo as variáveis nome, perguntas e aposta, a descrição pode ser: h Classe Nivel i≡ import java.util.Vector; public class Nivel { public String nome; // do nível, ex: "Fácil", "Médio", "Difícil" public Vector perguntas; // do nível public int aposta; h Nivel: método construtor i h Nivel: método mostrar i } Construtor de objetos da classe Nivel Um dos métodos da classe Nivel é o construtor. Este método é executado sempre que se constrói um objeto da classe Nivel: h Nivel: método construtor i≡ public Nivel() { perguntas = new Vector(); aposta = 0; nome = "?"; } Inicialmente é criado um objeto da classe Vector, que passa a ser apontado pela variável perguntas. Em seguida, o valor da variável aposta é zerado. O método de construção deixa indefinido o nome do nível. Para alterar o nome de um nível, pode-se fazer uso do seguinte método: h Nível: mudar nome i≡ public void mudarNome( String novo ) { nome = novo; } c Copyright °1999-2004, Dr. Italo S. Vega 20-8 Laboratório de Programação Setembro de 2004 Carga de Perguntas do Nível Uma vez criado o nível, ele deve carregar suas perguntas a partir de uma base de perguntas pré-existente: h Nível: carregar peguntas i≡ public void carregar( int n, BaseDePerguntas base ) { // @pre: assert( base.perguntas.size() >= n ); // @do: for( int i = 0; i < n; i++ ) { Pergunta p = base.obter( i ); perguntas.add( p ); } } Este método também exige a quantidade n de perguntas a serem carregadas no nível. Obtenção de Perguntas solicitada: Cada nível deve retornar uma pergunta sempre que for h Nível: obter uma pergunta i≡ public Pergunta obter() { // @do: if( perguntas.isEmpty() ) { return null; } else { return (Pergunta)perguntas.remove( 0 ); } } A cada execução deste método, observa-se que a pergunta retornada é removida do nível. Assim, em algum momento, o nível estará sem perguntas. Se todas as perguntas do nível tiverem sido retornadas, este método retorna null. Teste da classe Nivel Um cenário de teste da classe Nivel envolve a criação de um objeto facil, seguida de uma solicitação para que ele mostre o seu nome e a sua quantidade de perguntas. A classe TesteNivel fica: h Classe TesteNivel i≡ public class TesteNivel { public BaseDePerguntas bpFacil; public Nivel facil; h TesteNivel: construtor i h TesteNivel: cenário 1 i h TesteNivel: cenário 2 i h TesteNivel: cenário 3 i } c Copyright °1999-2004, Dr. Italo S. Vega 20-9 Laboratório de Programação Setembro de 2004 O construtor do teste cria e carrega uma base de perguntas fáceis, e cria o nível fácil (inicialmente sem perguntas): h TesteNivel: construtor i≡ public TesteNivel() { bpFacil = new BaseDePerguntas(); bpFacil.carregar( "FACIL" ); facil = new Nivel(); } O cenário de teste 1 apenas mostra as perguntas do nível fácil, criado no construtor do teste: h TesteNivel: cenário 1 i≡ public void cenario1() { facil.mostrar(); } O cenário de teste 2 carrega o nível fácil com as perguntas da base criada no construtor do teste: h TesteNivel: cenário 2 i≡ public void cenario2() { facil.carregar( 5, bpFacil ); facil.mostrar(); } O cenário de teste 3 obtém, uma a uma, as perguntas do nível fácil: h TesteNivel: cenário 3 i≡ public Pergunta cenario3() { return facil.obter(); } Exemplo 20.3 A Figura 20.5 mostra o resultado da execução do método cenario1(). Figura 20.5: Visualização do teste da classe Nivel. O objeto t:TesteNivel, ao receber a mensagem ativando a operação cenario1(), mostra o seu nome e a quantidade de perguntas após a sua construção. ¨ c Copyright °1999-2004, Dr. Italo S. Vega 20-10 Laboratório de Programação Setembro de 2004 20.4 Modelagem do Aluno O aluno conhece o seu total de pontos. Na construção de uma instância de aluno, o total de pontos é zerado: h Classe Aluno i≡ public class Aluno { public int pontos; public Aluno() { // @do: pontos = 0; } h Aluno: ganhar a aposta i h Aluno: dividir seus pontos i } Cada pergunta corretamente respondida pelo aluno provoca um aumento na sua quantidade de pontos: h Aluno: ganhar a aposta i≡ public void ganhar( int aposta ) { // @pre: assert( pontos < aposta ); // @do: pontos = aposta; } Por outro lado, caso o aluno responda de forma errada a uma pergunta, o seu total de pontos se reduz pela metade: h Aluno: dividir seus pontos i≡ public void dividir() { // @do: if( pontos > 0 ) { pontos = pontos / 2; } } 20.5 Modelo do Jogo Milhão da Computação h Classe Jogo i≡ public class Jogo { h Jogo: bases de perguntas i h Jogo: estrutura de níveis i h Jogo: aluno, pergunta formulada e valor da aposta i h Jogo: tela de interação com o aluno i h Jogo: construtor i h Jogo: perguntar para o aluno i h Jogo: gerar a pergunta inicial i c Copyright °1999-2004, Dr. Italo S. Vega 20-11 Laboratório de Programação Setembro de 2004 h Jogo: gerar a pergunta seguinte i h Jogo: terminar i h Jogo: configurar bases de perguntas i h Jogo: configurar níveis de perguntas i h Jogo: analisar a ação do aluno diante da pergunta i } 20.5.1 Estrutura Interna de um Jogo Bases de Perguntas h Jogo: bases de perguntas i≡ public BaseDePerguntas[] bases; int facil = 0; int medio = 1; int dificil = 2; int milhao = 3; h Jogo: configurar bases de perguntas i≡ public void configurarBases() { bases = new BaseDePerguntas[ 4 ]; for( int i = facil; i <= milhao; i++ ) { bases[i] = new BaseDePerguntas(); } bases[facil].carregar( "FACIL" ); bases[medio].carregar( "MEDIO" ); bases[dificil].carregar( "DIFICIL" ); bases[milhao].carregar( "MILHAO" ); // @post: assert( bases.length == 4 ); assert( bases[facil].perguntas.size() >= 5 ); assert( bases[medio].perguntas.size() >= 5 ); assert( bases[dificil].perguntas.size() >= 5 ); assert( bases[milhao].perguntas.size() >= 1 ); } Níveis de Perguntas h Jogo: estrutura de níveis i≡ public Nivel[] niveis; int na; // nivel atual de perguntas h Jogo: configurar níveis de perguntas i≡ public void configurarNiveis() { // @pre: assert( bases != null ); assert( bases.length == 4 ); // @do: niveis = new Nivel[4]; niveis[facil] = new Nivel(); c Copyright °1999-2004, Dr. Italo S. Vega 20-12 Laboratório de Programação Setembro de 2004 niveis[facil].carregar( 5, bases[facil] ); niveis[facil].aposta = 1000; niveis[medio] = new Nivel(); niveis[medio].carregar( 5, bases[medio] ); niveis[medio].aposta = 10000; niveis[dificil] = new Nivel(); niveis[dificil].carregar( 5, bases[dificil] ); niveis[dificil].aposta = 100000; niveis[milhao] = new Nivel(); niveis[milhao].carregar( 1, bases[milhao] ); niveis[milhao].aposta = 1000000; // @post: assert( niveis != null ); assert( niveis.length == 4 ); } Aluno, Pergunta Formulada e Valor da Aposta h Jogo: aluno, pergunta formulada e valor da aposta i≡ public Aluno aluno; public Pergunta pergunta; int aposta; // da pergunta atual Tela de Interação h Jogo: tela de interação com o aluno i≡ public Tela tela; Método Construtor O método construtor provoca a configuração das bases de perguntas, dos níveis do jogo, armazena em na a ordem do nível fácil (nos Vectors de bases e níveis), geração da pergunta inicial, criação do aluno e da tela de interação: h Jogo: construtor i≡ public Jogo() { configurarBases(); configurarNiveis(); na = facil; gerarPerguntaInicial(); aluno = new Aluno(); tela = new Tela(); tela.mudar( this ); } Término do Jogo h Jogo: terminar a execução i≡ public void terminar() { c Copyright °1999-2004, Dr. Italo S. Vega 20-13 Laboratório de Programação Setembro de 2004 System.out.println( "Terminado." ); } 20.5.2 Geração de Perguntas Pergunta Inicial h Jogo: gerar a pergunta inicial i≡ public void gerarPerguntaInicial() { // @pre: assert( (facil <= na)&&(na <= milhao) ); // @do: pergunta = niveis[ na ].obter(); aposta = niveis[na].aposta; } Perguntas Seguintes h Jogo: gerar a pergunta seguinte i≡ public void gerarPerguntaSeguinte() { // @pre: assert( (facil <= na)&&(na <= milhao) ); assert( (niveis[na].aposta <= aposta)&&(aposta <= niveis[na].aposta*5) ); // @do: pergunta = niveis[ na ].obter(); if( pergunta == null ) { na++; if( na < 4 ) { gerarPerguntaInicial(); } else { na-; terminar(); } } else { aposta += niveis[na].aposta; } // @post: assert( (facil <= na)&&(na <= milhao) ); assert( (niveis[na].aposta <= aposta)&&(aposta <= niveis[na].aposta*5) ); } Formulação da Pergunta h Jogo: perguntar para o aluno i≡ public void perguntar() { System.out.println( "Valendo... " + aposta ); tela.mostrar( pergunta ); c Copyright °1999-2004, Dr. Italo S. Vega 20-14 Laboratório de Programação Setembro de 2004 } 20.5.3 Teste da Estrutura do Jogo Para testar a codificação do jogo, deve-se criar uma instância de Jogo e enviar a mensagens para geração de perguntas e análise de ações do aluno: h Classe TesteJogo i≡ public class TesteJogo { public Jogo jogo; h TesteJogo: cenário 1i h TesteJogo: cenário 2i h TesteJogo: cenário 3i h TesteJogo: cenário 4i } Cenário 1 O aluno responde corretamente a primeira pergunta: h TesteJogo: cenário 1i≡ public void cenario1() { jogo = new Jogo(); jogo.perguntar(); jogo.tela.selecionar(1); jogo.tela.responder(); } Cenário 2 O aluno responde a primeira, mas erra a segunda pergunta: h TesteJogo: cenário 2i≡ public void cenario2() { jogo = new Jogo(); jogo.perguntar(); jogo.tela.selecionar(1); jogo.tela.responder(); jogo.gerarPerguntaSeguinte(); jogo.perguntar(); jogo.tela.selecionar(1); jogo.tela.responder(); } Cenário 3 Aluno erra a primeira pergunta: h TesteJogo: cenário 3i≡ public void cenario3() { jogo = new Jogo(); jogo.perguntar(); jogo.tela.selecionar(2); jogo.tela.responder(); } c Copyright °1999-2004, Dr. Italo S. Vega 20-15 Laboratório de Programação Cenário 4 Setembro de 2004 Aluno pára o questionário: h TesteJogo: cenário 4i≡ public void cenario4() { jogo = new Jogo(); jogo.perguntar(); jogo.tela.parar(); } c Copyright °1999-2004, Dr. Italo S. Vega 20-16 Laboratório de Programação Setembro de 2004 E XERCÍCIOS 20.1 M ODELO DA B ASE DE P ERGUNTAS Tarefa 20.1.1 Crie um novo projeto denominado “ex20.1”. Tarefa 20.1.2 Codifique a classe BaseDePerguntas. Tarefa 20.1.3 Codifique a classe TesteBaseDePerguntas. Tarefa 20.1.4 Crie um objeto da classe TesteBaseDePerguntas: qual o resultado do cenário 1? Tarefa 20.1.5 Crie um objeto da classe TesteBaseDePerguntas: qual o resultado do cenário 2? Tarefa 20.1.6 Crie um objeto da classe TesteBaseDePerguntas: qual o resultado do cenário 3? 20.2 I MPLEMENTAÇÃO DOS N ÍVEIS Em relação ao modelo da classe Nivel: Tarefa 20.2.1 como “ex20.2”). Crie um novo projeto denominado “ex20.2” (salve o projeto anterior Tarefa 20.2.2 Codifique o modelo da classe Nivel conforme mostrado no texto. Tarefa 20.2.3 Codifique a classe TesteNivel. Tarefa 20.2.4 Crie o objeto t da classe TesteNivel. O que acontece quando ele recebe uma mensagem ativando a operação cenario1()? Tarefa 20.2.5 Altere a classe TesteNivel de modo que sejam criados dois outros nívels: medio e dificil. Tarefa 20.2.6 Crie o objeto t da classe TesteNivel. O que acontece quando ele recebe uma mensagem ativando a operação cenario1()? 20.3 I MPLEMENTAÇÃO DO A LUNO Em relação ao modelo da classe Aluno: Tarefa 20.3.1 como “ex20.3”). Crie um novo projeto denominado “ex20.3” (salve o projeto anterior Tarefa 20.3.2 Codifique o modelo da classe Aluno conforme mostrado no texto. Tarefa 20.3.3 Elabore e codifique a classe TesteAluno. Deve ser possível testar cada método da classe Aluno. Tarefa 20.3.4 Crie o objeto t da classe TesteAluno e envie mensagens de teste. 20.4 I MPLEMENTAÇÃO DO J OGO Em relação ao modelo da classe Jogo: Tarefa 20.4.1 como “ex20.4”). Crie um novo projeto denominado “ex20.4” (salve o projeto anterior Tarefa 20.4.2 Codifique o modelo da classe Jogo conforme mostrado no texto. c Copyright °1999-2004, Dr. Italo S. Vega 20-17 Laboratório de Programação Tarefa 20.4.3 Setembro de 2004 Codifique a classe TesteJogo. Tarefa 20.4.4 Crie o objeto t da classe TesteJogo. O que acontece quando ele recebe uma mensagem ativando a operação cenario1()? Tarefa 20.4.5 Crie o objeto t da classe TesteJogo. O que acontece quando ele recebe uma mensagem ativando a operação cenario2()? Tarefa 20.4.6 Crie o objeto t da classe TesteJogo. O que acontece quando ele recebe uma mensagem ativando a operação cenario3()? Tarefa 20.4.7 Crie o objeto t da classe TesteJogo. O que acontece quando ele recebe uma mensagem ativando a operação cenario4()? c Copyright °1999-2004, Dr. Italo S. Vega 20-18 Laboratório de Programação Setembro de 2004 Anexo: Listagem do Protótipo Pacote milhao Classe Alternativa.java public class Alternativa { public String texto; public Alternativa( String novoTexto ) { // @do: texto = novoTexto; } public void mostrar() { // @do: System.out.println( texto ); } } Classe Aluno.java public class Aluno { public int pontos; public Aluno() { // @do: pontos = 0; } public void ganhar( int aposta ) { // @pre: assert( pontos < aposta ); // @do: pontos = aposta; } public void dividir() { // @do: if( pontos > 0 ) { pontos = pontos / 2; } } } Classe BaseDePerguntas.java import java.util.Vector; import java.util.Collections; public class BaseDePerguntas { public Vector perguntas; public BaseDePerguntas() { // @do: perguntas = new Vector(); } public void carregar( String nivel ) { // @pre: assert( "FACIL".equals( nivel ) || "MEDIO".equals( nivel ) || "DIFICIL".equals( nivel ) || "MILHAO".equals( nivel ) ); // @do: if( "FACIL".equals( nivel ) ) { carregarBaseFacil(); } if( "MEDIO".equals( nivel ) ) { carregarBaseMedio(); } if( "DIFICIL".equals( nivel ) ) { carregarBaseDificil(); } if( "MILHAO".equals( nivel ) ) { c Copyright °1999-2004, Dr. Italo S. Vega 20-19 Laboratório de Programação Setembro de 2004 carregarBaseMilhao(); } } public void carregarBaseFacil() { Pergunta nova = new Pergunta( "O que é computação?" ); nova.definirAlternativaCorreta( "É um cálculo." ); nova.definirAlternativa( "É uma variável." ); nova.definirAlternativa( "É um metodo." ); nova.definirAlternativa( "É um array." ); perguntas.add(nova); nova = new Pergunta( "O que é um array?" ); nova.definirAlternativa( "É um valor." ); nova.definirAlternativaCorreta( "É uma estrutura de info." ); nova.definirAlternativa( "É uma ativação." ); nova.definirAlternativa( "É uma fila." ); perguntas.add(nova); nova = new Pergunta( "Uma variável ..." ); nova.definirAlternativa( "É um dado." ); nova.definirAlternativa( "Controla o programa." ); nova.definirAlternativa( "É um comando." ); nova.definirAlternativaCorreta( "Armazena um valor." ); perguntas.add(nova); nova = new Pergunta( "Pergunta facil..." ); nova.definirAlternativaCorreta( "A F1." ); nova.definirAlternativa( "A F2." ); nova.definirAlternativa( "A F3." ); nova.definirAlternativa( "A F4." ); perguntas.add(nova); nova = new Pergunta( "Algoritmos ..." ); nova.definirAlternativaCorreta( "Descrevem computações." ); nova.definirAlternativa( "São valores." ); nova.definirAlternativa( "São variáveis." ); nova.definirAlternativa( "São estruturas de info." ); perguntas.add(nova); // @post: assert( perguntas.size() >= 5 ); } public void carregarBaseMedio() { Pergunta nova = new Pergunta( "Um Vector..." ); nova.definirAlternativa( "É igual a um array." ); nova.definirAlternativaCorreta( "Permite acesso posicional." ); nova.definirAlternativa( "Não armazena char." ); nova.definirAlternativa( "É um algoritmo." ); perguntas.add(nova); nova = new Pergunta( "Uma atribuição..." ); nova.definirAlternativaCorreta( "Troca um valor." ); nova.definirAlternativa( "É um cálculo." ); nova.definirAlternativa( "É uma expressão." ); nova.definirAlternativa( "Não é um comando." ); perguntas.add(nova); nova = new Pergunta( "Pergunta media 1..." ); nova.definirAlternativaCorreta( "A M1." ); nova.definirAlternativa( "A M2." ); nova.definirAlternativa( "A M3." ); nova.definirAlternativa( "A M4." ); perguntas.add(nova); nova = new Pergunta( "Pergunta media 2..." ); nova.definirAlternativaCorreta( "A F1." ); nova.definirAlternativa( "A M2." ); nova.definirAlternativa( "A M3." ); nova.definirAlternativa( "A M4." ); perguntas.add(nova); nova = new Pergunta( "Pergunta media 3..." ); c Copyright °1999-2004, Dr. Italo S. Vega 20-20 Laboratório de Programação Setembro de 2004 nova.definirAlternativaCorreta( "A M1." ); nova.definirAlternativa( "A M2." ); nova.definirAlternativa( "A M3." ); nova.definirAlternativa( "A M4." ); perguntas.add(nova); // @post: assert( perguntas.size() >= 5 ); } public void carregarBaseDificil() { Pergunta nova = new Pergunta( "Um pacote..." ); nova.definirAlternativa( "Introduz acoplamentos." ); nova.definirAlternativa( "É um componente." ); nova.definirAlternativa( "É instanciável." ); nova.definirAlternativaCorreta( "Organiza classes." ); perguntas.add(nova); nova = new Pergunta( "Pergunta dificil 1..." ); nova.definirAlternativaCorreta( "A D1." ); nova.definirAlternativa( "A D2." ); nova.definirAlternativa( "A D3." ); nova.definirAlternativa( "A D4." ); perguntas.add(nova); nova = new Pergunta( "Pergunta dificil 2..." ); nova.definirAlternativaCorreta( "A D1." ); nova.definirAlternativa( "A D2." ); nova.definirAlternativa( "A D3." ); nova.definirAlternativa( "A D4." ); perguntas.add(nova); nova = new Pergunta( "Pergunta dificil 3..." ); nova.definirAlternativaCorreta( "A D1." ); nova.definirAlternativa( "A D2." ); nova.definirAlternativa( "A D3." ); nova.definirAlternativa( "A D4." ); perguntas.add(nova); nova = new Pergunta( "Pergunta dificil 4..." ); nova.definirAlternativaCorreta( "A D1." ); nova.definirAlternativa( "A D2." ); nova.definirAlternativa( "A D3." ); nova.definirAlternativa( "A D4." ); perguntas.add(nova); // @post: assert( perguntas.size() >= 5 ); } public void carregarBaseMilhao() { Pergunta nova = new Pergunta( "Um objeto..." ); nova.definirAlternativa( "É uma variável." ); nova.definirAlternativa( "É uma classe." ); nova.definirAlternativa( "Só tem atributos." ); nova.definirAlternativaCorreta( "Realiza computações." ); perguntas.add(nova); // @post: assert( perguntas.size() >= 1 ); } public void embaralhar() { // @pre: assert( perguntas.size() > 0 ); // @do: Collections.shuffle( perguntas ); } public Pergunta obter( int i ) { // @pre: int n = perguntas.size(); assert( (0 <= i)&&(i < n) ); // @do: return (Pergunta)perguntas.get( i ); } } c Copyright °1999-2004, Dr. Italo S. Vega 20-21 Laboratório de Programação Setembro de 2004 Classe Jogo.java public class Jogo { public BaseDePerguntas[] bases; int facil = 0; int medio = 1; int dificil = 2; int milhao = 3; public Nivel[] niveis; int na; // nivel atual de perguntas public Aluno aluno; public Pergunta pergunta; int aposta; // da pergunta atual public Tela tela; public Jogo() { configurarBases(); configurarNiveis(); na = facil; gerarPerguntaInicial(); aluno = new Aluno(); tela = new Tela(); tela.mudar( this ); } public void configurarNiveis() { // @pre: assert( bases != null ); assert( bases.length == 4 ); // @do: niveis = new Nivel[4]; niveis[facil] = new Nivel(); niveis[facil].carregar( 5, bases[facil] ); niveis[facil].aposta = 1000; niveis[medio] = new Nivel(); niveis[medio].carregar( 5, bases[medio] ); niveis[medio].aposta = 10000; niveis[dificil] = new Nivel(); niveis[dificil].carregar( 5, bases[dificil] ); niveis[dificil].aposta = 100000; niveis[milhao] = new Nivel(); niveis[milhao].carregar( 1, bases[milhao] ); niveis[milhao].aposta = 1000000; // @post: assert( niveis != null ); assert( niveis.length == 4 ); } public void configurarBases() { bases = new BaseDePerguntas[ 4 ]; for( int i = facil; i <= milhao; i++ ) { bases[i] = new BaseDePerguntas(); } bases[facil].carregar( "FACIL" ); bases[medio].carregar( "MEDIO" ); bases[dificil].carregar( "DIFICIL" ); bases[milhao].carregar( "MILHAO" ); // @post: assert( bases.length == 4 ); assert( bases[facil].perguntas.size() >= 5 ); assert( bases[medio].perguntas.size() >= 5 ); assert( bases[dificil].perguntas.size() >= 5 ); assert( bases[milhao].perguntas.size() >= 1 ); } public void gerarPerguntaInicial() { // @pre: assert( (facil <= na)&&(na <= milhao) ); // @do: pergunta = niveis[ na ].obter(); aposta = niveis[na].aposta; } public void gerarPerguntaSeguinte() { // @pre: assert( (facil <= na)&&(na <= milhao) ); c Copyright °1999-2004, Dr. Italo S. Vega 20-22 Laboratório de Programação Setembro de 2004 assert( (niveis[na].aposta <= aposta)&&(aposta <= niveis[na].aposta*5) ); // @do: pergunta = niveis[ na ].obter(); if( pergunta == null ) { na++; if( na < 4 ) { gerarPerguntaInicial(); } else { na--; terminar(); } } else { aposta += niveis[na].aposta; } // @post: assert( (facil <= na)&&(na <= milhao) ); assert( (niveis[na].aposta <= aposta)&&(aposta <= niveis[na].aposta*5) ); } public void perguntar() { System.out.println( "Valendo... " + aposta ); tela.mostrar( pergunta ); } public void terminar() { System.out.println( "Terminado." ); } } Classe Nivel.java import java.util.Vector; public class Nivel { public String nome; // do nível, ex: "Fácil", "Médio", "Difícil" public Vector perguntas; // do nível public int aposta; public Nivel() { perguntas = new Vector(); aposta = 0; nome = "?"; } public void carregar( int n, BaseDePerguntas base ) { // @pre: assert( base.perguntas.size() >= n ); // @do: for( int i = 0; i < n; i++ ) { Pergunta p = base.obter( i ); perguntas.add( p ); } } public Pergunta obter() { // @do: if( perguntas.isEmpty() ) { return null; } else { return (Pergunta)perguntas.remove( 0 ); } } public void mostrar() { System.out.println( nome ); System.out.println( "\tTotal de perguntas= " + perguntas.size() ); } } Classe Pergunta.java import java.util.Vector; public class Pergunta { public String enunciado; c Copyright °1999-2004, Dr. Italo S. Vega 20-23 Laboratório de Programação Setembro de 2004 public Vector alternativas; public int correta; public Pergunta( String novoEnunciado ) { // @do: enunciado = novoEnunciado; alternativas = new Vector(); correta = -1; } public void definirAlternativa( String texto ) { // @pre: menos do que 4 alternativas int n = alternativas.size(); assert( (0 <= n) && (n < 4) ); // @do: int ordem = n + 1; Alternativa nova = new Alternativa( "" + ordem + ") " + texto ); alternativas.add( nova ); // @post: até 4 alternativas assert( (0 < alternativas.size()) && (alternativas.size() <= 4) ); } public void definirAlternativaCorreta( String texto ) { // @pre: menos do que 4 alternativas int n = alternativas.size(); assert( (0 <= n) && (n < 4) ); // @do: int ordem = n + 1; Alternativa nova = new Alternativa( "" + ordem + ") " + texto ); alternativas.add( nova ); correta = ordem; // @post: até 4 alternativas, uma delas correta assert( (0 < alternativas.size()) && (alternativas.size() <= 4) ); assert( ( 1 <= correta )&&(correta <= 4) ); } public void mostrar() { // @pre: tem 4 alternativas, uma delas correta assert( alternativas.size() == 4 ); assert( ( 1 <= correta )&&(correta <= 4) ); // @do: System.out.println( enunciado ); for( int i = 0; i < alternativas.size(); i++ ) { Alternativa a = (Alternativa)alternativas.get(i); a.mostrar(); } } public void analisarAlternativa( int ordem ) { // @pre: ordem corresponde a alguma alternativa assert( ( 1 <= ordem )&&(ordem <= 4) ); // @do: if( ordem == correta ) { System.out.println( "Acertou" ); } else { System.out.println( "Errou" ); } } public void parar() { // @do: System.out.println( "Parou" ); } } Classe Tela.java public class Tela { public Pergunta pergunta; public int ordem; public Jogo jogo; // <- v2 public void mudar( Jogo dono ) { // <- v2 jogo = dono; } public void mostrar( Pergunta p ) { // @do: pergunta = p; c Copyright °1999-2004, Dr. Italo S. Vega 20-24 Laboratório de Programação Setembro de 2004 System.out.println( "=====" ); pergunta.mostrar(); } public void selecionar( int nova ) { // @do: ordem = nova; } public void responder() { // @do: pergunta.analisarAlternativa( ordem ); } public void parar() { // @do: pergunta.parar(); } } Pacote teste Classe TesteBaseDePerguntas.java package teste; public class TesteBaseDePerguntas { public BaseDePerguntas facil; public BaseDePerguntas medio; public BaseDePerguntas dificil; public BaseDePerguntas milhao; public TesteBaseDePerguntas() { // @do: criação das bases facil = new BaseDePerguntas(); medio = new BaseDePerguntas(); dificil = new BaseDePerguntas(); milhao = new BaseDePerguntas(); } public void mostrarEnunciados( BaseDePerguntas base ) { for( int i = 0; i < base.perguntas.size(); i++ ) { Pergunta p = base.obter( i ); System.out.println( p.enunciado ); } System.out.println( ".........." ); } public void cenario1() { // @do: carga das bases facil.carregar( "FACIL" ); medio.carregar( "MEDIO" ); dificil.carregar( "DIFICIL" ); milhao.carregar( "MILHAO" ); System.out.println("> ENUNCIADOS da base milhao:" ); mostrarEnunciados( milhao ); } public void cenario2() { // @do: embaralhamento System.out.println("> ANTES de embaralhar o nivel Facil:" ); mostrarEnunciados( facil ); facil.embaralhar(); System.out.println("> DEPOIS de embaralhar o nivel Facil:" ); mostrarEnunciados( facil ); } public Pergunta cenario3() { Pergunta p = facil.obter( 0 ); p.mostrar(); return p; } } Classe TesteJogo.java c Copyright °1999-2004, Dr. Italo S. Vega 20-25 Laboratório de Programação Setembro de 2004 public class TesteJogo { public Jogo jogo; public void cenario1() { jogo = new Jogo(); jogo.perguntar(); jogo.tela.selecionar(1); jogo.tela.responder(); } public void cenario2() { jogo = new Jogo(); jogo.perguntar(); jogo.tela.selecionar(1); jogo.tela.responder(); jogo.gerarPerguntaSeguinte(); jogo.perguntar(); jogo.tela.selecionar(1); jogo.tela.responder(); } public void cenario3() { jogo = new Jogo(); jogo.perguntar(); jogo.tela.selecionar(2); jogo.tela.responder(); } public void cenario4() { jogo = new Jogo(); jogo.perguntar(); jogo.tela.parar(); } } Classe TesteNivel.java package teste; public class TesteNivel { public BaseDePerguntas bpFacil; public Nivel facil; public TesteNivel() { bpFacil = new BaseDePerguntas(); bpFacil.carregar( "FACIL" ); facil = new Nivel(); } public void cenario1() { facil.mostrar(); } public void cenario2() { facil.carregar( 5, bpFacil ); facil.mostrar(); } public Pergunta cenario3() { return facil.obter(); } } Classe TestePergunta.java package teste; public class TestePergunta { public Pergunta p11; public void cenario() { // @do: p11 = new Pergunta( "O que é computação?" ); p11.definirAlternativaCorreta( "É um cálculo." ); p11.definirAlternativa( "É um procedimento." ); p11.definirAlternativa( "É uma rotina." ); p11.definirAlternativa( "É um método." ); p11.mostrar(); } public Alternativa obter( int i ) { // @do: return (Alternativa)p11.alternativas.get(i); } c Copyright °1999-2004, Dr. Italo S. Vega 20-26 Laboratório de Programação Setembro de 2004 } Classe TesteTela.java package teste; public class TesteTela { public Pergunta p11; public Tela tela; public void cenario() { // @do: p11 = new Pergunta( "O que é computação?" ); p11.definirAlternativaCorreta( "É um cálculo." ); p11.definirAlternativa( "É um procedimento." ); p11.definirAlternativa( "É uma rotina." ); p11.definirAlternativa( "É um método." ); tela = new Tela(); } } Classe TesteJogo.java //package teste; public class TesteJogo { public Jogo jogo; public void cenario1() { jogo = new Jogo(); jogo.perguntar(); jogo.tela.selecionar(1); jogo.tela.responder(); } public void cenario2() { jogo = new Jogo(); jogo.perguntar(); jogo.tela.selecionar(1); jogo.tela.responder(); jogo.gerarPerguntaSeguinte(); jogo.perguntar(); jogo.tela.selecionar(1); jogo.tela.responder(); } } c Copyright °1999-2004, Dr. Italo S. Vega 20-27