Ayuda con mazo de cartas!!

Iniciado por Ruusa, 2 Julio 2020, 18:59 PM

0 Miembros y 1 Visitante están viendo este tema.

Ruusa

Hola! buenas tardes, tengo un problema con un juego de cartas que estoy haciendo,
cuando quiero repartir las cartas a los jugadores reparte bien, pero luego de que no haya mas cartas en el mazo sigue repartiendo igual, nose como hacer para solucionarlo, si alguien me podría dar una ayuda se lo agradecería. Les dejo el código:


Código (java) [Seleccionar]
//palos
public enum Palos {
ORO,
COPA,
BASTO,
ESPADA

}




//la clase cartas
public class Cartas {


public int numero;
public Palos palo;
public int valor;


   public Cartas(Palos palo, int numero, int valor) {
this.palo = palo;
this.numero = numero;
this.valor = valor;
}



public String toString() {
return numero + " de " + palo;
}

public int getValor() {
return valor;
}
}



//la clase mazo
public class Mazo {
public  boolean mano=true;
private Cartas[] cartas = new Cartas[40];
public static int cartaActual = 0;
public Mazo() {
Palos[] palos = new Palos[4];
palos = Palos.values();
int carta = 0;
for(int palo = 0; palo < palos.length; palo ++) {
for(int valor = 1; valor <= 12; valor ++) {
if (!(valor==8 || valor==9 )){
cartas[carta++] = new Cartas(palos[palo],
valor,
getFigura(valor));
}
}
}
mezclar();

}

private int getFigura(int valor) {
int respuesta = 0;
switch(valor) {
case 1: respuesta=1;
break;
case 2: respuesta=2;
break;
case 3: respuesta=3;
break;
case 4: respuesta=4;
break;
case 5: respuesta=5;
break;
case 6: respuesta=6;
break;
case 7: respuesta=7;
break;
case 10:
respuesta = 8;
break;
case 11:
respuesta = 9;
break;
case 12:
respuesta = 10;
break;
}
return respuesta;
}

public void mezclar() {
Random r = new Random();
for(int i = 0; i < cartas.length; i ++) {
int pos = r.nextInt(40);
Cartas aux = cartas[i];
cartas[i] = cartas[pos];
cartas[pos] = aux;
}
cartaActual = 0;
}

public Cartas getCarta() {
Cartas c=null;
if (cartaActual >= cartas.length) {
System.out.println("No hay mas cartas");
}else {
c= cartas[cartaActual ++];

}

return c;
}

//El metodo para repartir las cartas a los jugadores de la clase juego

public void repartirJugadores() {   
     // Paso 1. Repartir cartas a jugadores
for (int i = 0; i < 3; i++) {
for (Jugador j: jugadores) {
j.agregarCarta(mazoCarta.getCarta());

}

}


notificarCambio(11);
}


MOD: Etiqueta GeSHi.

Serapis

#1
Cita de: Ruusa en  2 Julio 2020, 18:59 PM

Código (java) [Seleccionar]

public void mezclar() {
Random r = new Random();
for(int i = 0; i < cartas.length; i ++) {
int pos = r.nextInt(40);
Cartas aux = cartas[i];
cartas[i] = cartas[pos];
cartas[pos] = aux;
}
cartaActual = 0;
}

Esta función está mal.
No garantiza un reparto aleatorio.
El bucle debe empezar desde atrás hasta el comienzo... (por sencillez), pero sobre todo porque el rango aleatorio debe reducirse en cada iteración.


MAX_CARTAS = 40
...
Funcion Barajar
   Bucle para i desde MAX_CARTAS-1 hasta 1 retrocediendo
       pos = random(0 a i)
       aux = cartas(i)
       cartas(i) = cartas(pos)
       cartas(pos) = aux
   Siguiente

   cartaActual =MAX_CARTAS
Fin funcion


Así en la primera iteración se elige un valar entre 0 y 39, en la segunda entre 0 y 38, en la 3ª entre 0 y 37... pero la posición 39, ya fue depositado en la 1ª iteración, la 38º en la 2ª y el 37 en la 3ª, etc...
y cuando solo queda 1 elemento (en la posición 0), no es preciso barajarlo consigo mismo, se deja el valor que resta, por eso basta llegar hasta 1...

Si lo miras bien, de esta manera absolutamente todas las posiciones son cambiadas, salgan o no en el generador aleatorio...
del modo que tu lo haces, si la posición 20 (por ejemplo), sale elegido 3 veces, se puede afirmar que habrá 3 cartas que no cambiarán su posición de antes de barajar.

Una vez que las cartas están barajadas, se pueden tomar en orden correlativo  (no importa tanto si de arriba abajo o de abajo hacia arriba), pero igual que en la realidad e spreferible tomar la de más arriba e ir descendiendo hasta llegar a 0, favorece posteriores barajados...  luego necesitas cambiar tu función 'GetCarta'


carta = funcion GetSiguienteCarta
   si (cartaActual = 0)
        mensaje "no quedan cartas"
        // más abajo comento de cambiar este caso...
  Si no
       cartaActual  -=1
       devolver cartas(CartaActual)
  fin si
fin funcion

La función no es muy distinta a la que tienes, pero es preferible hacerlo de forma regresiva, pués empezamos, descontando cartaactual y luego devolvemos la carta en dicha posición... paramos cuando el valor llega a 0 y se reclama otra.

Según de que típo de juego se trate, pueden repartirse todas la comienzo, algo que solo será posible si el número de jugadores es congruente con el número de cartas. Opuedne repartirse una cantidad fija.
También dependeindo del juego pued ehaber descartes de cartas a medida que se juega... con ese descarte, se van amontonando juntas, y cuando el mazo está vacío se trasladan estas al mazo (sean la cantidad que sean (pero debe llevarse la cuenta)  y se barajan, ahora cartaActual  valdrá esa cantidad y por tanto en vez de decir 'no quedan cartas' , se invoca esa función que recoje el mazo de cartas descartadas, y se barajan como el mazo, al término devuelve la última. ...pero como digo, depende del tipo de juego y las reglas que tenga...
Sería más  o menos:

carta = funcion GetSiguienteCarta
   si (cartaActual = 0) // no quedan cartas"
        PasarDescarteAMazo
  fin si

  cartaActual  -=1
  devolver cartas(CartaActual)
fin funcion

// tomar mazo de descarte , pasarlo al mazo de cartas y barajarlo
funcion PasarDescarteAMazo
   entero k
   
   bucle para k desde 0 hasta DescarteActual -1      
       Cartas(k) = Descarte(k)     // Descarte es otra instancia de 'Cartas'.
   siguiente

   Barajar(DescarteActual )   // exige modificar la función barajar para que reciba el parámetro de cuantas tiene en tal momento.
fin funcion

// Una función para que un jugador pueda descartarse de alguna carta...
// se amontona en otro mazo de cartas, del que s elleva la cuenta.
funcion Descartar(carta)
   Descarte(DescarteActual ) = carta
   DescarteActual +=1
fin funcion

// una constande de la clase 'Cartas'
MAX_CARTAS = 40
...
funcion NuevaPartida
  Barajar(MAX_CARTAS)
  ...
fin funcion

Funcion Barajar(cantidad)  // ahora se recibe un parámetro que es la cantidad a barajar hasta 1.
   Bucle para i desde cantidad-1 hasta 1 retrocediendo
       pos = random(0 a i)
       aux = cartas(i)
       cartas(i) = cartas(pos)
       cartas(pos) = aux
   Siguiente

   cartaActual = cantidad
    descarteActual = 0    // el mazo de descarte ahora está vací...
Fin funcion


Luego en el bucle ese de asignar las cartas... el siguiente bucle:
Código (java) [Seleccionar]
for(int valor = 1; valor <= 12; valor ++)
sería más sencillo, claro y eficiente, separarlo en dos bucles:

bucle desde 1 hasta 7
...
bucle desde 10 hasta 12
...


Finalmente, al repartir en la función 'repartirJugadores', repartes cada vez 4 cartas a cada jugador... dependerá de cuantos jugadores sean, no podrá servir 4 cartas a cada jugador todas las veces que se llame. Mira si el juego permite descartarse... y si en el juego siempre hay cartas de descarte o si el juego puede completarse sin necsidad de tomar más cartas... las reglas del juego definirán ciertos aspectos.