Queremos agora construir um método para saber a pontuação de um jogador com um dado nome. O código seguinte serve:
/**
* A pontuacao de um dado jogador deste jogo
* @param nomeJog O nome do jogador.
* @return A pontuacao do jogador com este nome
* @requires O jogador com o nome nomeJog estah registado neste jogo
*/
public int pontuacao (String nomeJog) {
Jogador atual = null;
for (int i = 0 ; atual == null && i < this.quantosEmJogo ; i++){
if (nomeJog.equals(this.jogadores[i].nome())){
atual = this.jogadores[i];
}
}
return atual.pontuacao();
}
Repare como este método e o registarPontosJogada
da secção anterior são quase iguais:
Outros métodos de instância de que precisaremos nesta classe seguem este padrão: por exemplo, métodos para saber a pontuação máxima numa só jogada de um jogador com dado nome, para saber se um jogador com dado nome está registado no jogo, etc.
Então, vamos definir um método privado (pois é somente para ser invocado a partir dos métodos da própria classe) que encontre e devolva um dado jogador, e vamos usá-lo a partir destes métodos.
xxxxxxxxxx
/**
* Retorna o jogador correspondente a um nome, ou null se nao houver.
* Metodo privado, auxiliar.
* @param nomeJog O nome do jogador.
* @returns O jogador com este nome se existir no jogo;
* null caso contrario
*/
private Jogador obterJogador (String nomeJog) {
Jogador result = null;
for (int i = 0 ; result == null && i < this.quantosEmJogo ; i++){
if (nomeJog.equals(this.jogadores[i].nome())){
result = this.jogadores[i];
}
}
return result;
}
Vamos então modificar os dois métodos anteriores para invocarem este último e acrescentar outros ainda, que também implementam o mesmo padrão.
x/**
* Registar a pontuacao na jogada atual de um dado jogador.
* @param nomeJog O nome do jogador.
* @param pontuacao A pontuacao obtida na jogada atual.
* @requires this.estahEmJogo (nomeJog) &&
* pontuacao >= 0 && pontuacao <= 10
*/
public void registarPontosJogada (String nomeJog, int pontuacao) {
this.obterJogador(nomeJog).registarPontos(pontuacao);
}
/**
* A pontuacao de um dado jogador deste jogo
* @param nomeJog O nome do jogador.
* @return A pontuacao do jogador com este nome
* @requires this.estahEmJogo (nomeJog)
*/
public int pontuacao (String nomeJog) {
return this.obterJogador(nomeJog).pontuacao();
}
/**
* Um dado jogador estah em jogo?
* @param nomeJog O nome do jogador.
* @return true se o jogador com este nome estah registado neste jogo
* false caso contrario
*/
public boolean estahEmJogo (String nomeJog) {
return this.obterJogador(nomeJog) != null;
}
/**
* A pontuacao maxima numa soh jogada de um dado jogador deste jogo
* @param nomeJog O nome do jogador.
* @return A pontuacao maxima numa soh jogada do jogador com este nome
* @requires this.estahEmJogo (nomeJog)
*/
public int maximoNumaJogada (String nomeJog) {
return this.obterJogador(nomeJog).maximoNumaJogada();
}
Repare que também acrescentámos o método estahEmJogo
que, dado o nome de um jogador, verifica se ele está registado no jogo, retornando true
se está inscrito e false
caso contrário. Este método permite que as classes cliente verifiquem se um jogador está registado antes de invocar um dos outros métodos, em situações em que não há a certeza de que o dado jogador está registado no jogo.
Repare que substituímos o texto O jogador com o nome nomeJog estah registado neste jogo
que tínhamos nas pré-condições dos métodos acima por this.estahEmJogo (nomeJog)
.
Acrescentámos também o método maximoNumaJogada
que retorna a pontuacao máxima numa só jogada do jogador com um dado nome.
Adicionemos agora a instrução seguinte ao método main
da classe ClienteDeJogo
,
xxxxxxxxxx
meuJogo.registarPontosJogada("Maria",10);
As figuras seguintes ilustram o estado da memória em várias fases da execução desta instrução:
registarPontosJogada
é invocado (repare o valor de this
no contexto deste método – é o mesmo conteúdo da variável meuJogo
): registarPontosJogada
invoca, por sua vez, o método obterJogador
, sobre o objeto referenciado por this
; a figura seguinte mostra o estado da memória quando é feita essa invocação; repare no valor de this
no contexto deste método – é o mesmo conteúdo do this
do método registarPontosJogada
, como seria de esperar, ou seja, o objeto corrente continua a ser o mesmo: o método obterJogador
invoca, por sua vez, o método nome
sobre cada um dos objetos do tipo Jogador
que estão contidos no array jogadores
do this
; a figura seguinte mostra o estado da memória quando é feita a invocação do método nome
sobre o primeiro dos elementos do array, o de índice zero, cujo nome é "Maria"; repare no valor de this
no contexto deste método – é o objeto que representa o jogador de nome "Maria":
o método obterJogador
encontrou o jogador que procurava logo no primeiro elemento do array jogadores
; logo, o resultado do método é uma referência a esse objeto:
de seguida, o método registarPontosJogada
invoca o método registarPontos
sobre o objeto que recebeu como resultado da invocação this.obterJogador("Maria")
; a figura seguinte mostra o estado da memória já no fim da execução do método registarPontos
:
finalmente, já depois do método registarPontosJogada
terminar, o objeto referenciado pela variável meuJogo
já está atualizado pois o seu jogador de nome "Maria" já tem os seus atributos pontuacao
e maximoJogada
atualizados:
Vamos agora registar mais pontuações de jogadas para os dois jogadores; o nosso main
da classe ClienteDeJogo
passa então a ser o seguinte:
xxxxxxxxxx
public class ClienteDeJogo {
public static void main (String [] args) {
Jogo meuJogo = new Jogo(30);
System.out.println("O objetivo eh " + meuJogo.pontuacaoObjetivo());
meuJogo.juntarJogador("Maria");
meuJogo.juntarJogador("Pedro");
meuJogo.registarPontosJogada("Maria",10);
meuJogo.registarPontosJogada("Pedro",7);
meuJogo.registarPontosJogada("Maria",10);
meuJogo.registarPontosJogada("Pedro",3);
meuJogo.registarPontosJogada("Maria",10);
meuJogo.registarPontosJogada("Pedro",8);
}
}
Após a execução da última instrução do main
, o estado da memória ficará:
Anterior: 11.3. Registar pontuação de um dado jogador do jogo – 1ª versão
Seguinte: 11.5. Atributos e métodos de classe (static)