public void mezclar() {
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:
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.