miércoles, 12 de febrero de 2014

Juegos de Cartas. La siete y Media

Pues hoy vamos a tirarle otra vez a la herencia, pero ésta vez con un conocido juego de cartas como es la Siete y Media. Este esquema va a ser algo más feo, pero veréis como se le coge el truco en seguida ;)

sin contar la clase ManoSieteyMedia, lo demás nos sirve para crear casi cualquier juego de cartas. Es por eso por lo que hemos hecho el tipo abstracto. Más adelante usaremos estas clases para (creando una clase simple para la mano) poder crear otros juegos. Aquí teneis la clase test ;)

public class SieteyMedia {
 public static void main(String[] args) {
  //Se crean el mazo, el jugador y la banca
  Mazo mazo = new Mazo();
  ManoSieteyMedia jugador = new ManoSieteyMedia();
  ManoSieteyMedia banca = new ManoSieteyMedia();
  
  //Se reparten las cartas iniciales: 
                //Una al jugador y una a la banca
  jugador.agnadeCarta(mazo.daCarta());
  banca.agnadeCarta(mazo.daCarta());
  
  //El jugador pide cartas mientras según su estrategia
  while(jugador.cuentaPuntos()<=5){
   System.out.println(
                              "El jugador pide una carta extra");
   jugador.agnadeCarta(mazo.daCarta());
  }
  
  //La banca se planta si el jugador se ha pasado.
                //En caso contrario pide cartas
  if(jugador.cuentaPuntos()<=7.5){ 
                  //el jugador no se ha pasado
   while(banca.cuentaPuntos()<7.5 && 
                            banca.cuentaPuntos()<jugador.cuentaPuntos()){
    System.out.println(
                                       "La banca pide una carta extra");
    banca.agnadeCarta(mazo.daCarta());
   }
  }
  //Se cuentan los puntos obtenidos y se decide el ganador
  double puntosJ = jugador.cuentaPuntos();
  double puntosB = banca.cuentaPuntos();
  
  if(puntosJ<=7.5 && (puntosB>7.5 || puntosJ>puntosB)){

   System.out.println("Gana el jugador con "+jugador
                            +" ("+ puntosJ+" puntos) frente a "+ banca+
                            " ("+puntosB+" puntos) de la banca");
  }else if (puntosB<=7.5){
   System.out.println("Gana la banca con "
                            +banca+" ("+ puntosB+
                            " puntos) frente a "+ jugador+" ("+
                            puntosJ+" puntos) del jugador");
  }else{
   System.out.println("No hay ganador: Jugador "+ 
                            jugador+" ("+puntosJ+" puntos) y banca "
                            + banca +" ("+
                            puntosB+" puntos) se han pasado");
  }
 }
}
Ahora procedo a poneros las soluciones ;)

Primero la clase abstracta Mano.

public abstract class Mano{
 protected Carta[] cartas;
 protected int numCartas;
 static final int TOPE = 20;
 public Mano() {
  numCartas = 0;
  cartas = new Carta[TOPE];
 }
 
 public Mano(int num) {
  cartas = new Carta[num];
  numCartas = 0;
 }
 
 public void descartaTodas() {
  numCartas = 0;
 }
 
 public void agnadeCarta(Carta c) {
  if(numCartas >= TOPE) 
               throw new RuntimeException("No puedes añadir mas cartas");
  cartas[numCartas] = c;
  numCartas ++;
 }
 
 public int numeroDeCartas() { 
  return numCartas;
 }
 
 public abstract double cuentaPuntos();
 
 public String toString() {
  String std = "";
  for(int i = 0; i < numCartas; i++) {
   std = std + " "+ cartas[i];
  }
  return std;
 }
}

Ahora os pondré la clase Carta: Nota: Fijaos que el enum de los palos va dentro de ésta ;)
public class Carta {
 public static enum Palo { PICA, TREBOL, DIAMANTE, CORAZON};
 private static String[] nombreCarta = {"AS", "2", "3", "4",
                                               "5", "6", "7", "8",
                                               "9", "10", "J", "Q",
                                               "K"};
 
 private int valor;
 private Palo palo;
 
 public Carta(int v, Palo p){
  valor = v;
  palo = p;
 }
 public int valor() {return valor;}
 public Palo palo() {return palo;}
 public String toString() {
  return nombreCarta[valor-1] + " de " + palo;
 }
 
}
Vamos ahora con la clase Mazo ;)
import java.util.Random;
public class Mazo {
 private static Random alea = new Random();
 private Carta[] mazo;
 private int numCartas;
 
 public Mazo() {
  mazo = new Carta[52]; //Creo el array de cartas.
  for(int n = 1; n < 13; n++) {
   for(Carta.Palo p: Carta.Palo.values()) {
    mazo[numCartas] = new Carta(n, p);
    numCartas++;
   }
  }
 }

 public void baraja() {
  for(int i = 0; i< numCartas; i++) {
   int r = alea.nextInt(numCartas);
   Carta c = mazo[i];
   mazo[i] = mazo[r];
   mazo[r] = c;
  }
 }

 public int numeroDeCartas() {
  return numCartas;
 }
 
 public Carta daCarta(){ 
  if (this.numeroDeCartas()==0) 
                   throw new RuntimeException("No quedan cartas.");
  numCartas--;
  return mazo[this.numeroDeCartas()];
 }
}

Y ya por último con la clase ManoSieteYMedia:
public class ManoSieteyMedia extends Mano{
 public double cuentaPuntos() {
  double puntos = 0;
  for(int i = 0; i<numCartas; i++) {
   puntos += cartas[i].valor();
  }
  return puntos;
 }
}

Como veis no son demasiado complicadas ;) Es más, si quisieramos definir otro juego, valdría (en un principio) con definir una nueva clase 'ManoNuestroJuego' que heredara de Mano y que definiera cuentaPuntos(). Simple, ¿verdad?

Si algún día me da la picada, subiré (usando estas mismas clases) un proyecto que hice de un solitario Spider, pero ya más adelante cuando hayamos visto algo de IDEs ;)

Disfrutadlo y no olvideis comentarme vuestras impresiones.

Saludos

10 comentarios:

  1. amigo y para java ME es lo mismo??

    ResponderEliminar
    Respuestas
    1. Según tengo entendido, java ME (corrígeme si me equivoco) es sólo una 'versión' de Java para dispositivos de memoria limitada como smartTV o móviles... (más info aquí: http://www.codigofantasma.com/blog/diferencias-entre-j2ee-j2se-j2me/)

      Por lo que sí que debería funcionar, aunque dependiendo del dispositivo donde lo integres. De todos modos ésta tampoco es una aplicación "digna" para que gastes tu tiempo haciendo eso :P

      Saludos;)

      Eliminar
  2. Muy buena explicacion lo pondre en practica ya que he creado un juego de cartas con una idea original y espero aprender para desarollar mi juego tengo una pregunta si puedes subir una explicacion para hacer el juego online seria de gran ayuda gracias por tu aportacion espero lograr mi objetivo

    ResponderEliminar
  3. Amigo no funciona, se me queda así cuando lo ejecuto:
    No hay ganador: Jugador Q de CORAZON (12.0 puntos) y banca Q de DIAMANTE (12.0 puntos) se han pasado

    ResponderEliminar
  4. Amigo no funciona, cuando lo ejecuto sale esto:
    No hay ganador: Jugador Q de CORAZON (12.0 puntos) y banca Q de DIAMANTE (12.0 puntos) se han pasado

    ResponderEliminar
  5. Está muy bien el código.Lo has hecho súper sencillo,pero podría complicarse más.a mi también me toca hacerlo,pero con más cosas.Me ha servido tu juego para ver como funcionaba la lógica.

    Gracias.

    ResponderEliminar
  6. ¿Quisiera saber como se hace el juego de las siete y media en php?

    ResponderEliminar
  7. alguien sabe hacer esto pero en c++?

    ResponderEliminar
  8. me pudieran ayudar a como hago para programar el juego de cuarenta

    ResponderEliminar