Programação Orientada por Objectos
Tutorial 3: 31
In this tutorial we are going to develop a program that implements a simple game without GUI,
though. Our main goal is to practice both modelling and implementation of inheritance.
0. As always start by reading thoroughly the problem description given in the appendix. Make sure
you fully understand the problem. Should you have any doubt about it, do not hesitate to ask.
1. We must agree that this is a fairly simple game. We can think of many good possible solutions.
However, we are taking this opportunity to exercise inheritance and the design pattern Template
Method.
2. From the problem description we can identify three main classes: Jogo (Game in English),
Jogador (Player), JogadorPoupado (SparedPlayer), and JogadorGastador (SpenderPlayer).
3. From the problem description, it is clear that Jogo(Game) has a set of Jogadores(Players).
4. It is also clear that the only difference between the two types of players is the way of playing,
after the second turn. The JogadorPoupado (SparedPlayer) adds only 1 to the current count, and
the JogadorGastador (SpenderPlayer) adds always 2. Remember that during the first turn all
players do the same, i.e., they add 3 to the count.
5. This observation leads us to identify JogadorPoupado and JogadorGastador as subclasses of the
class Jogador. Inheritance implies a is-a relationship between each subclass and its superclass
and, JogadorPoupado(SparedPlayer) is-a Jogador (Player). The same apply to
JogadorGastador(SpenderPlayer). Moreover, using inheritance, we can leave everything (i.e.,
both instance variables, and methods) common superclass/subclass in the superclass. Due to
inheritance, the subclass can use them as its own.
6. This brief but most useful analysis can be documented in the following UML class diagram.
At this time, we have included explicitly the Main class (where the client code is defined) in
the diagram. We have also explicitly included the functional dependency relationship (denoted
by the dashed arrow - - - >) meaning that class Main depends on class Jogo.
http://w3.ualg.pt/~jvo/poo
POO Lab Tutorial 3 - 1
Programação Orientada por Objectos
Obviously, Main also depends on Jogador. However, this is not represented in the diagram.
The reason is that it is not always a good idea to explicitly represent all functional
dependencies between classes. If we did this, the diagram could become hard to read with all
those relationships. Therefore, we will keep the representation of functional dependencies to a
minimum, and only for those situations worth stressing.
7. We are now ready to start coding. Open Eclipse and create a new java project.
8. As always we will start by writing the client code,
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int nj = sc.nextInt();
Jogo trintaIum = new Jogo();
String nome, tipo;
for(int i=0; i< nj; i++) {
nome = sc.next();
tipo = sc.next();
if (tipo.compareToIgnoreCase("Poupado")==0)
trintaIum.add(new JogadorPoupado(nome));
else if (tipo.compareToIgnoreCase("Gastador")==0)
trintaIum.add(new JogadorGastador(nome));
else {
System.err.print("Tipo de jogador desconhecido. ");
System.exit(1);
}
}
System.out.println(trintaIum.deBocaAeliminar());
}
}
9. Since an object Jogo will be composed by, at least two objects from the hierarchy Jogador, the
next class to code will be Jogador.
abstract class Jogador{
final private String nome;
private boolean primeiraVez = true;
private static final int QPV=3; // Quantidade para a primeira vez;
protected Jogador(String n) {nome =n;}
public String toString() {return nome;}
public final int joga() {
if(primeiraVez) {
primeiraVez = false;
http://w3.ualg.pt/~jvo/poo
POO Lab Tutorial 3 - 2
Programação Orientada por Objectos
return QPV;
}
else return quantidade();
}
abstract protected int quantidade();
public void setPrimeiraVez() {primeiraVez = true;}
}
10. Notice that we have followed here the Template Method design pattern. We have prepared our
class for inheritance. Specially, we have marked the class as abstract (the class will not have
instances), we have identify joga() as the template method. It is marked final so it will not be
redefined in any of the subclasses. As it is defined, this method uses the so-called Holywood
principle “don’t call use, we call you”. Actually, the method calls function quantity() that is not
defined in Jogador. This function is an abstract protected function, meaning that it should be
redefined by Jogador subclasses.
11. With the restrictions above, the implementation of class JogadorPoupado is:
class JogadorPoupado extends Jogador{
private static final int Quantidade=1;
public JogadorPoupado(String s){ super(s); }
protected int quantidade() {return JogadorPoupado.Quantidade;}
}
12. Implement now the class JogadorGastador.
At this point we may wonder whether this program architecture is really necessary. Believe me,
it is a good opportunity for exercising inheritance and the Template Method in Java.
13. Based on what we have seen so far, we should be able to implement the class Jogo.
14. Test your program on appropriated test cases.
15. Submit your program to mooshak (http://www.deei.fct.ualg.pt/~mooshak) – problem D,
get and an Accepted, and add 10 points to your lab score.
http://w3.ualg.pt/~jvo/poo
POO Lab Tutorial 3 - 3
Programação Orientada por Objectos
Appendix: 31
// For the English version see below
A expressão “Trinta e um” parece ter origem num jogo de cartas. Diz que o jogo era bem disputado
o que invariavelmente dava lugar a desordem, zaragatas e embrulhadas. De resto, estes são os
significados da expressão em frases como: “Arranjaste um belo trinta e um”.[1]
Por outro lado, “31 de boca” significa uma declaração não confirmada por escrito, pelo que sem
validade legal.
Existe também um jogo de trinta-e-um de boca em que dois ou mais jogadores vão lançando
números até que um deles chega ou ultrapassa os 31, sendo eliminado do jogo. Naturalmente que
ganha o jogador que sobrevive.
As regras do jogo são simples. Os jogadores jogam por ordem. Na sua vez de jogar, um jogador
pode somar à contagem actual 1, 2 ou 3, sendo que só poderá somar 3 uma única vez. Quando um
jogador é eliminado, a contagem volta a zero e o primeiro jogador a jogar é o jogador seguinte ao
que foi eliminado.
Na versão do jogo que nos interessa estudar existem apenas dois tipos de jogadores. Os Poupados e
os Gastadores. Os Poupados somam invariavelmente 1 à contagem actual. Os Gastadores somam
invariavelmente 2. Com receio de se esquecerem e serem eliminados do jogo, todos os jogadores
somam 3 da primeira vez que têm oportunidade de jogar.
Use os princípios e as técnicas de Programação Orientada por Objectos para escrever um programa
em Java que simule a versão do jogo descrita acima.
Input
A primeira linha da entrada é um natural N indicando o número de jogadores.
Seguem-se N linhas, cada uma das quais é constituída pelo nome, por um espaço e pelo tipo do
jogador, que poderá ser Poupado ou Gastador.
Output
Uma string com o nome do jogador vencedor.
Sample input 1
4
Almerindo Poupado
Anacleto Gastador
Anastacio Gastador
Asdrubal Poupado
Sample output 1
Asdrubal
http://w3.ualg.pt/~jvo/poo
POO Lab Tutorial 3 - 4
Programação Orientada por Objectos
Appendix: 31
// Leia acima a versão Portuguesa
The game “trinta-e-um de boca” is named after a idiomatic portugues expression. In this game, two
or more players are counting up numbers. That player that reach 31 is eliminated. The player that
survives will become the winner.
The rules of the game are simple. Players play in turn. In his/her time of playing, a player can add to
the current count 1, 2 or 3. However, 3 can be added only once. When a player is eliminated, the
counter reset and the next to play is the player next to the eliminated one.
In our version of the game, there are only two types of players: The Poupados and the Gastadores.
The Poupados invariably add 1 to the current count. Gastores invariably add 2 to the current count.
Both type of players add 3 to count in the first time they play.
Use the principles and techniques of Object-Oriented Programming to write a program that runs the
described version of the game.
Input
A primeira linha da entrada é um natural N indicando o número de jogadores.
Seguem-se N linhas, cada uma das quais é constituída pelo nome, por um espaço e pelo tipo do
jogador, que poderá ser Poupado ou Gastador.
Output
Uma string com o nome do jogador vencedor.
Sample input 1
4
Almerindo Poupado
Anacleto Gastador
Anastacio Gastador
Asdrubal Poupado
Sample output 1
Asdrubal
http://w3.ualg.pt/~jvo/poo
POO Lab Tutorial 3 - 5
Download

Tutorial 3: 31