11.7. Fim de jogo, vencedores e outros métodos

A cada jogada que faz, um jogador aproxima-se do fim do jogo, ou seja, do número de pontos definido como objetivo a alcançar. Quando algum(ns) jogador(es) alcança(m) uma pontuação igual ou maior que o objetivo do jogo, este termina e o(s) vencedor(es) pode(m) ser identificado(s).

11.7.1. Fim de jogo

Se tivermos um método que calcula quantos pontos tem o jogador que tem maior pontuação, e compararmos esse valor com o objetivo do jogo, então ficamos a saber se o jogo já terminou ou não.

Vamos então criar um método que calcula a maior pontuação dos jogadores do jogo. Isto é um problema de cálculo do máximo de um conjunto de valores, tal como fizemos, de forma muito geral, na secção 9.6.2.

A diferença aqui é que o nosso array é o atributo de instância jogadores e não um parâmetro do método. Além disso, aqui não temos um array com os inteiros a comparar, mas sim um array de jogadores.

Os valores que queremos comparar não são os jogadores propriamente ditos mas as suas pontuações, ou seja, para um dado jogador referenciado por um elemento do array jogadores, por exemplo, jogadores[i], o que queremos é a sua pontuação, ou seja, o resultado da invocação jogadores[i].pontuacao().

Então, para verificar se o jogo terminou basta comparar o resultado do método maiorPontuacao com o valor do atributoobjetivo:

Um exemplo de utilização deste método numa nova classe ClienteDeJogo:

Vamos analisar os vários passos do método main:

O output de uma possível execução deste programa:

 

11.7.2. Vencedor(es) – primeira tentativa

Era bom que o vencedor fosse calculado pelo próprio programa para que o utilizador não tenha que estar a fazer contas.

Quem sabe qual é o vencedor do jogo? É quem tem informação para isso, ou seja, o próprio jogo, que pode perguntar a cada um dos seus jogadores qual a sua pontuação e decidir qual o vencedor.

Vamos então agora ver como fazer isso. Se o critério para vencer o jogo fosse somente alcançar uma pontuação maior ou igual à do objetivo do jogo, então o método seguinte, que devolve o nome do vencedor, pode ser uma primeira abordagem:

Começamos por guardar nas variáveis pontos e resultado a pontuação e o nome do primeiro jogador registado no jogo (que é o primeiro elemento do array jogadores). O ciclo permite-nos aceder aos outros jogadores, por ordem de registo no jogo (a mesma ordem dos elementos no array), até encontrarmos algum cuja pontuação seja igual ou superior ao objetivo.

Se o primeiro jogador tiver uma pontuação igual ou superior ao objetivo do jogo, é o nome dele que resulta deste método. Caso contrário, o ciclo é executado para procurar o primeiro jogador, dos seguintes, a ter alcançado o objetivo. O ciclo pára logo que um jogador nessas condições é encontrado.

Repare na pré-condição: this.quantosEmJogo() > 0 && this.terminou(). Além de especificar que tem que existir pelo menos um jogador registado no jogo, requer também que o jogo já tenha terminado, ou seja, que o resultado da invocação do método terminou seja true. Isso garante que existe um vencedor, pois o jogo só termina quando pelo menos um jogador alcançou o objetivo.

Mas esta solução tem vários defeitos:

 

11.7.3. Vencedor(es) – segunda tentativa

Numa segunda tentativa, vamos fazer as seguintes modificações:

Voltando ao main da nossa classe ClienteDeJogo acima descrita, vamos fazer as seguintes alterações:

Ao executar o main, vamos obter o seguinte output (só apresentamos a parte produzida pelas novas instruções) seguido de uma exceção que provoca a terminação abrupta do programa:

Observamos que, dos dois jogadores em jogo, só a Maria conseguiu alcançar o objetivo dos 30 pontos, o que faz com que faça parte dos vencedores. Relembre que, por gerarmos as pontuaçãos com um objeto Random, o output será potencialmente diferente a cada execução. Mas só em casos muito particulares, nomeadamente quando todos os jogadores são vencedores, é que o programa prossegue sem exceções. Já vai perceber porquê.

 

 

11.7.4. Vencedor(es) – terceira, e última, tentativa

Resumindo e concluindo:

 

11.7.5. Outra forma de definir o(s) vencedor(es)

Se quisessemos obter somente o jogador que tem a maior pontuação, e devolver esse como vencedor do jogo, poderíamos deparar-nos com situações em que há mais que um jogador que tem a pontuação máxima. O seguinte método privado calcula e devolve os jogadores que têm a melhor pontuação. Iremos invocá-lo numa nova versão do método vencedores.

No caso de serem mais do que um, e quisermos desempatar, podemos fazê-lo escolhendo o que tem o valor maior para o atributo que representa o "máximo numa só jogada". De novo, aqui, podem ser mais do que um. A nova versão do método vencedores ficaria então:

 

11.7.6. Jogadores com pontuação superior a um dado valor

O seguinte método devolve os nomes dos jogadores cuja pontuação é superior a um valor dado:

 

 

 


 

Anterior: 11.6. O método toString na classe Jogo

Seguinte: 11.8. A classe Jogo completa.