Ejercicio de Programación Orientada a Objetos. Herencia y Clases abstractasClases a implementarCartaBarajaJugadorPartidaPrograma Principal
Fecha | Versión | Descripción |
---|---|---|
23/01/2025 | 1.0.0 | Versión inicial |
En este ejercicio vamos a implementar el juego del Guiñote, que se juega con la baraja española. Vamos a implementar el juego del mismo de manera completa porque excede del tiempo necesario, pero si que vamos a tratar de al menos poder jugar una mano de este
Para ello vamos a implementar una serie de clases que se encargarán de realizar el juego.
La clase Carta deberá disponer de la siguiente estructura:
palo: Es un String que contendrá el palo de la baraja española: Oros, Bastos, Copas y Espadas.
nombre: String que contiene el nombre de la carta: As, dos, tres, cuatro, cinco, seis, siete, sota, caballo o rey.
valor: El valor que tiene en el juego de cara a la puntuación.
prioridad: Qué valor numérico tiene esta de tal manera que a mayor prioridad gana a una carta del mismo palo de menor prioridad. Aquí sólo se guardará la prioridad.
Constructor Carta(String palo, String nombre, int valor, int prioridad): El constructor recibe estos parametros en el método y los asigna a los atributos.
getPalo(): Método que devuelve el palo que tiene la carta.
getNombre: Getter que devuelve el nombre de la carta.
getValor: Getter que devuelve el valor de la carta.
getPrioridad: Getter que devuelve la prioridad de la carta.
toString(): Delvuelve el String del nombre de la carta así como su palo: Ejemplo: As de Oros.
La clase Baraja deberá disponer de la siguiente estructura:
cartas: Contendrá un ArrayList de Carta.
Constructor Baraja(): El constructor no recibe parámetros pero internamente contendrá e inicializará los siguientes elementos.
Creará para cada uno de los palos, 4, sus respectivas cartas y las añadirá al arrayList cartas. Aquí te dejo la estructura (debes tú añadir en cartas cada una de estas)
cartas = new ArrayList<>();
String[] palos = {"Oros", "Copas", "Espadas", "Bastos"};
String[] nombres = {"As", "Dos", "Tres", "Cuatro", "Cinco", "Seis", "Siete", "Sota", "Caballo", "Rey"};
int [] prioridad = {12, 2, 11, 4, 5, 6, 7, 9, 8, 10};
int[] valores = {11, 0, 10, 0, 0, 0, 0, 3, 2, 4};
barajar(): Método que ordena aleatoriamente las cartas. Este te lo doy hecho.
xxxxxxxxxx
public void barajar() {
Collections.shuffle(cartas);
}
getCartas: Devuelve el ArrayList de cartas.
xxxxxxxxxx
public ArrayList<Carta> getCartas() {
}
repartir() : Este método se encargará de devolver la primera carta. Recuerda, cuando la devuelve la elimina y nos interesa que la retorne el método. Está simulando que coge de una pila de cartas, des decir, de la baraja, la primera carta, cuando se roba carta.
xxxxxxxxxx
public Carta repartir() {
}
La clase jugador deberá disponer de la siguiente estructura:
nombre: Almacenará el nombre del jugador.
mano: ArrayList de carta que contendrá 6 cartas de la baraja.
puntos: Entero que acumulará los puntos que obtenga el jugador cada vez que gane una jugada.
Constructor Jugador(String nombre): Construye el objeto Jugador.
Recibe un nombre y lo asigna al atributo nombre.
Crea un ArrayList de carta vacio.
puntos lo inicializa a 0.
xxxxxxxxxx
public Jugador(String nombre) {
}
recibirCarta(Carta carta): Este método coge una carta y la añade al ArrayList mano.
x public void recibirCarta(Carta carta) {
}
jugarCarta(int ncarta): Este método es que a un jugador le permite seleccionar de las 6 que tiene en el ArrayList mano, una carta (ncarta). La obtiene, la borra y la devuelve:
xxxxxxxxxx
public Carta jugarCarta(int ncarta) {
return carta;
}
getNombre(): Devuelve el nombre del jugador:
xxxxxxxxxx
public String getNombre() {
}
getPuntos(): Devuelve los puntos del jugador:
xxxxxxxxxx
public int getPuntos() {
}
setPuntos(int puntos): Actualiza los puntos del jugador:
xxxxxxxxxx
public void setPuntos(int puntos) {
}
listarCartas(): Se encarga de listar del ArrayList mano las cartas que tiene el jugador:
xxxxxxxxxx
public void listarCartas() {
}
Esta va a ser la clase principal que se invocará en el programa principal. Se va a conformar con la siguiente estructura:
baraja: Atributo de tipo de datos de la clase Baraja.
jugadores: Atributo que contará con un ArrayList que almacenará jugadores.
triunfo: Atributo booleano que contiene el valor del triunfo de la ronda
Constructor Partida(): El constructor se encargara de lo siguiente. En el atributo baraja creará un objeto de tipo Baraja. También inicializará el atributo jugadores con un ArrayList de jugador vacío.
xxxxxxxxxx
public Partida() {
baraja =
jugadores =
}
agregarJugador(Jugador jugador): Este método recibirá un objeto de tipo jugador y lo añadirá al ArrayList jugdores, es decir, al atributo jugadores.
xxxxxxxxxx
public void agregarJugador(Jugador jugador) {
}
getJugadores(): Este método devolverá el atributo jugadores.
xxxxxxxxxx
public ArrayList<Jugador> getJugadores() {
return
}
getBaraja(): Método que devolverá el atributo partida de esta clase.
xxxxxxxxxx
public Baraja getBaraja() {
return
}
repartirCartas(): Este método se va a encargar de coger a cada uno de los jugadores del atributo jugadores, ArrayList, y asignarle una carta. Para ello hará uso de la combinación de los siguientes métodos:
jugador.recibirCarta
baraja.repartir
xxxxxxxxxx
private void repartirCartas() {
for (Jugador jugador : jugadores) {
}
}
}
determinarTriunfo(): Este método se va encargar de realizar lo siguiente:
Obtendrá una carta que será el triunfo. Para ello dentro del método deberá crear un objeto de tipo Carta y le asignará valor invocando el método repartir del atributo de clase baraja, que contiene ya un objeto de tipo baraja.
De esa carta obtenida previamente, obtendrá el palo de la misma, usando el getter que permite obtener el palo, y asignará al atributo triunfo de la clase Partida este valor. Adicionalmente lo podrá imprimir por pantalla.
Este método devolverá esta carta.
xxxxxxxxxx
private Carta determinarTriunfo() {
Carta cartaTriunfo =
triunfo =
System.out.println("El palo de triunfo es: " + triunfo);
return ;
}
iniciar(): Este método es el que se va a encargar de iniciar lo siguiente:
Se encargará de barajar el mazo de cartas, es decir, invocará el método barajar() del atributo baraja.
invocará al método de esta clase repartirCartas()
Devolverá el resultado de invocar determinarTriunfo()
xxxxxxxxxx
public Carta iniciar() {
return
}
El número de jugadores será por defecto 2. Debemos tener en cuenta que se trata de un juego en que pueden jugar 2 o 4 jugadores, estos últimos por parejas, pero ocurre que el objetivo es jugar unas manos, es decir, probar el funcionamiento de las clases.
En el jugo tenemos las siguientes normas:
Se juega con una baraja de 40 cartas que disponen de 4 palos: Oros, Bastos, Copas y Espadas.
Para cada uno de los palos tenemos las siguientes cartas: As, dos, tres, cuatro, cinco, seis, siete, sota, caballo y rey.
La prioridad, es decir, quien es más importante en orden decendente es el siguiente.
As, tres, rey, sota, caballo, siete, seis, cinco, cuatro, tres y dos.
Siguiendo esta prioridad tenemos que el As gana a cualquier otra siempre y cuando sean del mismo palo (Oros, bastos, ...)
Si no son del mismo palo, gana con independencia de todo aquella que sea del mismo palo que la carta/palo seleccionada como triunfo.
En el caso que ambas cartas sean diferentes y ninguna de ellas sea un triunfo, gana el jugador que tiró primero.
El valor de las cartas es el siguiente:
As: 11
Tres: 10
Rey: 4
Sota: 3
Caballo:2
Resto: 0
No vamos a tener en cuenta según las normas del juego, las 10 del monte.
Tampoco vamos a contar en el juego, según las normas del juego, "cantar las 40", por la que un jugador tiene la combinación de sota y rey del palo del triunfo. "Cantar 20" es tener la combinación de rey y sota que no son del palo triunfo.
El jugador que gana la mano, se lleva las 2 cartas, por lo tanto, acumula los puntos que tienen estas.
¿Cómo se roban las cartas del mazo?
Roba primero el jugador que ha ganado la mano y después el otro jugador.
En la clase main crea una partida. Una posible estructura de main:
xxxxxxxxxx
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
ArrayList<Jugador> players = new ArrayList<>();
Carta triunfo = null;
Carta cartaj1=null;
Carta cartaj2=null;
int njugador1=0;
int njugador2=1;
int opc=0;
// Aquí creamos un objeto de tipo partida
System.out.println("Introduce el nombre del primer Jugador: ");
// Recojo el nombre del primer jugador
String nombre = sc.nextLine();
// Creo un objeto de tipo jugador, para el primero
// Agrego el primer jugador con el método de partida para agregarlo
System.out.println("Introduce el nombre del segundo Jugador: ");
// Introduzco el nombre del segundo jugador
// Agrego el jugador a la partida, al igual que el jugador 1
//Inicio la partida. Este método además me devuelve el triunfo, el cual deberé recoger.
// Obtengo de Partida el parametro jugadores con su get, que almaceno en la variable players:
for (Jugador jugador : players) {
System.out.println("Nombre del jugador: "+ jugador.getNombre());
System.out.println("****************** Listado de cartas *******************");
jugador.listarCartas();
System.out.println("********************************************************");
}
System.out.println("Comienza tirando el primer jugador. Para ello selecciona una carta (valor numérico)");
// Este método recibe un parametro, el número de jugador, y el atributo players obtenido anteriormente.
cartaj1=tira_jugador(njugador1,players);
System.out.println("Tira el siguiente jugador. Para ello selecciona una carta (valor numérico)");
cartaj2=tira_jugador(njugador2,players);
opc=ganaMano(cartaj1,njugador1,cartaj2,njugador2,triunfo.getNombre(),players,P);
System.out.println("Gana " +players.get(opc).getNombre());
System.out.println("El/La jugador/a "+players.get(njugador1).getNombre()+" acumula "+ players.get(njugador1).getPuntos()+ " puntos.");
System.out.println("El/La jugador/a "+players.get(njugador2).getNombre()+" acumula "+ players.get(njugador2).getPuntos()+ " puntos.");
System.out.println("Quedan " + P.getBaraja().getCartas().size()+" cartas en la baraja");
}
// Este método se encarga de realizar lo que se indica en su interior.
public static Carta tira_jugador(int njugador, ArrayList<Jugador> players)
{
Scanner sc = new Scanner(System.in);
int ncarta;
Carta carta = null;
// Va a devolver una Carta. El nugador numero njugador seleccionará la carta que se va a pedir por pantalla con Scanner. Deberán estar entre 0 y 5 porque cada jugador sólo tiene 6 cartas. Si introduce un valor no numérico, generará una excepción y devolverá la que esta en la posición 0
// Con la carta seleccionada, ese jugador devolverá la carta que tiene asignada
System.out.println("El jugador "+players.get(njugador).getNombre() + " tira la carta "+carta.toString());
return carta;
}
// Este método se encarga de determinar quien gana la mano, asignar los puntos al jugador y repartir las cartas.
public static int ganaMano(Carta carta_jug1, int njug1, Carta carta_jug2,int njug2, String triunfo, ArrayList<Jugador> players, Partida partida) {
// Vamos a establecer que carta_jug1 es del jugador 1 y carta_jug2 es del jugador 2
// Primero vamos a ver si las cartas son del mismo palo. En esto nos dará igual que sea triunfo o no
// Las 2 cartas son del mismo palo
if(carta_jug1.getPalo().equals(carta_jug2.getPalo()))
{
// Siendo del mismo palo, el jugador_1 gana
if(carta_jug1.getPrioridad()>=carta_jug2.getPrioridad())
{
players.get(njug1).setPuntos(carta_jug1.getValor()+carta_jug2.getValor());
players.get(njug1).recibirCarta(partida.getBaraja().repartir());
players.get(njug2).recibirCarta(partida.getBaraja().repartir());
return njug1;
}
else if(carta_jug1.getPrioridad()<carta_jug2.getPrioridad())
{
players.get(njug2).setPuntos(carta_jug1.getValor()+carta_jug2.getValor());
players.get(njug2).recibirCarta(partida.getBaraja().repartir());
players.get(njug1).recibirCarta(partida.getBaraja().repartir());
return njug2;
}
// Ahora miramos que los palos sean diferentes. Aquí ya debemos tener en cuenta los siguientes criterios.
else if(!carta_jug1.getPalo().equals(carta_jug2.getPalo()))
{
if(carta_jug1.getPalo().equals(triunfo))
{
players.get(njug1).setPuntos(carta_jug1.getValor()+carta_jug2.getValor());
players.get(njug1).recibirCarta(partida.getBaraja().repartir());
players.get(njug2).recibirCarta(partida.getBaraja().repartir());
return njug1;
}
else if(carta_jug2.getPalo().equals(triunfo))
{
players.get(njug2).setPuntos(carta_jug1.getValor()+carta_jug2.getValor());
players.get(njug2).recibirCarta(partida.getBaraja().repartir());
players.get(njug1).recibirCarta(partida.getBaraja().repartir());
return njug2;
}
// Ninguna de las dos tiene el triunfo, por lo tanto se lleva los puntos quien tiró primero, que son los primeros
// parámetros de la llamada
else {
players.get(njug1).setPuntos(carta_jug1.getValor()+carta_jug2.getValor());
players.get(njug1).recibirCarta(partida.getBaraja().repartir());
players.get(njug2).recibirCarta(partida.getBaraja().repartir());
return njug1;
}
}
}
return njug1;
}
Ejecución:
Se recoge el nombre de los alumnos.
Se crea la partida, se realizan los sorteos y se muestra por pantalla las cartas que tiene cada jugador.
Comienza tirando el jugador 1:
Podemos ver que tira y selecciona Manu, el jugador 1, la carta Dos de Espadas.
Joan se da cuenta y la mata. Lanz el As de Espadas.
Joan se lleva las dos cartas y acumula los puntos.
Sólo jugamos a una ronda.
Realiza la entrega del proyecto en la tarea. Se cuidadoso con las clases.