A ver, por el nombre de esta clase:
OrdPalNumIncSupongo que se han de ordenar primero por el Palo, y luego por el Numero, de forma "incremental". Es decir, los palos en orden
lexicográfico (parecido al orden alfabético) AAA,AAB,ABA,ABB,ABC, etc.... y los números por orden de valor numérico: 1(as), 2,3,4, ...., hasta el 12(rey)
Ordenar por palos no es problema, pues es comparar Strings, que Java ya sabe como debe hacerlo.
Pero por números, es más complicado, porque no son Integers. También son Strings:
numeros ={"AS", "DOS", "TRES", "CUATRO",
"CINCO", "SEIS", "SIETE", "SOTA", "CABALLO", "REY"};
Así que hay que busca la forma de decirle al programa que el String AS es más pequeño que el String DOS.
Y que el String DOS es más pequeño que el String TRES, etc...
Bueno, eso lo veremos luego.
Volvamos a la clase
OrdPalNumInc De momento, nos dan esto para completar:
public class OrdPalNumInc extends AlgoritmoOrdenacion{
@Override
public void ordena(List listaCartas) {
// Algoritmo de ordenación
}
public static int comparadorCarta(Carta c1, Carta c2) {
// Comparador de cartas usado en el algoritmo de ordenación
return 0;
}
}
Primero habría que desarrollar el método comparadorCarta(), que es donde vamos escribir la lógica para que las cartas se comparen de forma que primero se ordenen según el palo, y si resulta que ambas cartas son del mismo palo, entonces se ordenan según el número.
La lógica sería:
* Si ambas cartas son exactamente iguales, se retorna 0.
* Si ambas cartas tienen el mismo palo, el orden depende de los números
- Si los números fueran iguales, se retorna 0. En realidad esto ya está contemplado
en el punto anterior.(Cartas exactamente iguales).
- Si la carta c1 tiene un número inferior al de c2, se retorna -1.
- Si la carta c2 tiene un número inferior al de c1, se retorna 1.
* Si las cartas tienen distinto palo, el número no influye. Hay que hacer una comparación lexicográfica de los nombres de los palos para decidir quién va primero al ordenar.
Las comparaciones lexicográficas son un poco complejas, pero la clase String ya sabe como hacerlas, así que se la pediremos a ella y retornaremos lo que ella diga.
Bien, esta lógica no es difícil. Solo está el problema al comparar los nombres de los números, ya que lo que necesitamos es su valor aritmético, pero el atributo "número" es un String. Sin embargo, podemos apoyarnos en el array de la clase
Baraja donde están declarados los nombres de los números:
public static final String[] numeros ={"AS", "DOS", "TRES", "CUATRO",
"CINCO", "SEIS", "SIETE", "SOTA", "CABALLO", "REY"};
Ahí están declarados en el orden correcto. Así que por ejemplo la posición que ocupa el String "AS" que es 0, nos sirve para saber que es menor que el String "DOS" el cuál ocupa la posición 1
Así que nos basta con obtener la posición que cada nombre de número ocupa en el array y hacer con ellos una comparación aritmética.
Quizás se entienda mejor leyendo el código:
public static int comparadorCarta(Carta c1, Carta c2) {
if (c1.equals(c2)) //Cartas son iguales
return 0;
else {
if (c1.getPalo().equals(c2.getPalo())) { //Mismo palo, el orden dependerá de los números
/*
* El atributo "numero" de las Cartas es un String, no es un Integer.
* Esto significa que no podemos comparar directamente esos atributos, porque en realidad
* no son números, y necesitamos lograr un orden aritmético.
*
* Por suerte, la clase Baraja tiene un array público con los nombres de estos "números"
* en el orden correcto.
* Así que podemos usar la posición que ocupa cada "nombre de número" en el array para obtener
* unos valores enteros con los que poder comparar de forma aritmética
*/
int posiC1 = 0, posiC2 = 0;
for (int i = 0; i < Baraja.numeros.length; i++) {
if (c1.getNumero().equals(Baraja.numeros[i]))
posiC1 = i;
if (c2.getNumero().equals(Baraja.numeros[i]))
posiC2 = i;
}
//Tenemos sus posiciones numéricas, podemos compararlas para decidir el orden.
if (posiC1 == posiC2)
return 0; //Número es igual
else if (posiC1 < posiC2)
return -1; //c1 es menor que c2
else
return 1; //c2 es menor que c1
}
else
return c1.getPalo().compareTo(c2.getPalo());//Retornamos la comparación por defecto de Strings
}
Ok, tenemos el método que dice como se han de compara las cartas.
Ahora hay que hacer el método ordena() que, valiéndose de estas reglas de comparación, ordene el List de Cartas.
Podemos aplicar el método de la burbuja para ordenar. Lo que haremos será comparar cartas según el algoritmo que hemos escrito antes.
Si el resultado de comparar resulta ser un valor mayor que 0, significa que la segunda carta es menor que la primera y por tanto han de intercambiar las posiciones.
@Override
public void ordena(List listaCartas) {
// Algoritmo de ordenación
for(int i = 0;i < listaCartas.size()-1;i++){
for(int j = 0;j < listaCartas.size()-i-1;j++){
int compara = comparadorCarta((Carta)listaCartas.get(j), (Carta)listaCartas.get(j+1));
//Solo hay que intercambiar posiciones si la segunda carta es menor
//es decir, si el valor de compara es positivo
//System.out.println(compara);
if (compara > 0) {
//Intercambiamos posiciones
Object aux = listaCartas.get(j+1);
listaCartas.set(j+1, listaCartas.get(j));
listaCartas.set(j, aux);
}
}
}
}
Vale, pues en principio la clase OrdPalNumInc ya está completada. Habría que ponerla a prueba.
Para ello, primero hay que ir a la clase
Mazo y completar un par de métodos.
Son muy sencillos, un setter para setear el algoritmo de ordenación que se quiere aplicar y el otro método es para ordenar que el algoritmo aplicado ordene las cartas:
public class Mazo {
List cartas;
private AlgoritmoOrdenacion algoritmo;
public void setAlgoritmo(AlgoritmoOrdenacion algoritmo) {
this.algoritmo = algoritmo;
}
public void ordena() {
if (algoritmo == null)
System.out.println("No se ha establecido ningún algoritmo de ordenación");
else
algoritmo.ordena(cartas);
}
Y ahora sí, podemos poner a prueba el algortimo.
Primero podemos poner como comentario en la clase
Main las líneas donde se aplicarían los algoritmos que aún no hemos escrito:
public class Main {
public static void main(String[] args) {
Baraja baraja = new Baraja();
Mazo mazo = baraja.getMazo();
System.out.println(mazo.toString());
mazo.setAlgoritmo(new OrdPalNumInc());
mazo.ordena();
System.out.println(mazo.toString());
/*
mazo.setAlgoritmo(new OrdPalNumDec());
mazo.ordena();
System.out.println(mazo.toString());
mazo.setAlgoritmo(new OrdNumIncPal());
mazo.ordena();
System.out.println(mazo.toString());*/
}
}
Y ahora sí, al ejecutar el programa, veremos en pantalla las cartas del mazo original y a continuación las cartas ordenadas tal y como se esperaba.
Ordenadas primero por el palo, y luego por el número, en orden incremental.
Ahora faltaría completar la clase
OrdPalNumDec, que es como la que hemos hecho pero invirtiendo el resultado de las comparaciones ya que el orden es decremental (de mayor a menor)
Y la clase
OrdNumIncPal, que supongo que primero se han de ordenar por número, y luego por palo, en orden incremental.
En la clase
AlgoritmoOrdenacion no hay que hacer nada de nada, ya que es una clase únicamente pensada para ser la "madre" de las otras tres clases de algoritmos.
De hecho, lo lógico habría sido declararla como una interface, en lugar de como una clase.
Pero bueno, este es el código que nos han dado y hay que respetarlo.
Otra cosa que no me gusta son todos esos List
"sin tipar".public void ordena(List listaCartas) {
}
Carajo, si ya sabemos el tipo de dato que van a contener estos List, pues pongámoslo para que todo quede bien parametrizado:
public void ordena(List<Carta> listaCartas) {
}
Pero bueno, si no han querido ponerlo, pues nada...
Lo importante es que se entienda la lógica de estos ejercicios.
Intenta completar esas dos clases que faltan, y si te atascas o tienes dudas, avisa por aquí y te ayudamos a terminarlo.
Un saludo.