/*
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Copyright 2015 Jose A. Gonzalez Cervera
Copyright 2015 Juan A. Fernández Sánchez
*/
package butterflydevs.brainstudio.extras;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
/**
* Created by juan on 4/06/15.
*/
public class matrixHelper {
static boolean depuracion = false; //Para on/off de la depuración por consola
// ### JUEGO 1 ### //
/**
* Esta es la función que se copiará en el código de AndroidStudio
*
* @param numCeldas El número de celdas a con las que jugar.
* @param numFilas El número de filas que tiene el grid de la jugada.
* @param numColumnas El número de columnas que tiene el grid de la jugada.
* @return La matriz (construida de forma aleatoria) que tendrá que adivinar el jugador.
*/
public static boolean[] obtenerMatrizJugada(int numCeldas, int numFilas, int numColumnas) {
int tamGrid = numFilas * numColumnas;
//Creamos el vector que vamos a devolver:
boolean[] matrizBooleanos = new boolean[tamGrid];
//Inicializamos el vector:
for (int i = 0; i < tamGrid; i++)
matrizBooleanos[i] = false;
//Rellenamos la matriz con el número de celdas positivas que nos indique el parámetro:
//Random que hace imposible repetir dos veces un número:
List<Integer> enteros = new ArrayList<>();
for (int i = 0; i < tamGrid; i++)
enteros.add(i);
if (depuracion) {
for (int elemento : enteros)
System.out.print(elemento);
System.out.println("");
}
ArrayList finales = new ArrayList();
//Sacamos cuantos numeros nos sean necesarios como celdas tengamos que rellenar.
int elegido;
int numFinal = tamGrid;
Random rnd = new Random();
for (int i = 0; i < numCeldas; i++) {
elegido = (int) (rnd.nextDouble() * numFinal); //Random de números entre el 0 y el numFinal
if (depuracion) System.out.println("elegido: " + elegido);
if (depuracion) {
System.out.println("Vector de enteros antes");
for (int elemento : enteros)
System.out.print(elemento);
System.out.println("");
System.out.println("Vector de enteros después");
for (int elemento : enteros)
System.out.print(elemento);
System.out.println("");
}
finales.add(enteros.get(elegido));
enteros.remove(elegido);
numFinal--;
}
for (int i = 0; i < finales.size(); i++) {
int elemento = (int) finales.get(i);
matrizBooleanos[elemento] = true;
}
return matrizBooleanos;
}
/**
* Función para comparar la matriz original y la que crea el usuario
*
* @param matrizOriginal La matriz de referencia (la correcta)
* @param matrizJugador La matriz que crea el jugador al pulsar los botones
* @param numFilas Número de filas de las matrices
* @param numColumnas Número de columnas de las matrices
* @return true si las matrices son iguales y false si no lo son
*/
public static boolean compruebaMatrices(boolean matrizOriginal[], boolean matrizJugador[], int numFilas, int numColumnas) {
/*
El único objetivo es comparar si dos matrices son iguales, para eso comprobaremos celda a celda.
*/
for (int i = 0; i < numFilas * numColumnas; i++) {
if (matrizOriginal[i] == false)
System.out.print("0");
else
System.out.print("1");
}
System.out.println("");
for (int i = 0; i < numFilas * numColumnas; i++) {
if (matrizJugador[i] == false)
System.out.print("0");
else
System.out.print("1");
}
boolean resultado = true;
int tamGrid = numFilas * numColumnas;
//De esta forma si el error está al principio no tiene que recorrer toda la matriz
int pos = 0;
while (resultado == true && pos < tamGrid) {
if (matrizOriginal[pos] != matrizJugador[pos]) resultado = false;
pos++;
}
return resultado;
}
// ### JUEGO 2 ### //
/**
* ####### FUNCIÓN RE-ADAPTADA PARA EL JUEGO2
* <p/>
* Esta es la función que se copiará en el código de AndroidStudio
*
* @param numCeldas El número de celdas a con las que jugar.
* @param numFilas El número de filas que tiene el grid de la jugada.
* @param numColumnas El número de columnas que tiene el grid de la jugada.
* @return La matriz (construida de forma aleatoria) que tendrá que adivinar el jugador.
*/
public static int[] obtenerMatrizJugada_juego2(int numCeldas, int numFilas, int numColumnas) {
int tamGrid = numFilas * numColumnas;
//Creamos el vector que vamos a devolver:
int[] matrizEnteros = new int[tamGrid];
//Inicializamos el vector:
for (int i = 0; i < tamGrid; i++)
matrizEnteros[i] = 0;
//Array de enteros para evitar que se repitan números aleatorios
List<Integer> enteros = new ArrayList<>();
for (int i = 0; i < tamGrid; i++)
enteros.add(i);
ArrayList<Integer> finales_magenta = new ArrayList<>();
ArrayList<Integer> finales_verde = new ArrayList<>();
ArrayList<Integer> finales_rojo = new ArrayList<>();
//Ahora rellenamos todas las celdas con figuras.
Random aleatorio = new Random();
int seleccion, indice_seleccionado, celdas_rellenadas = 0;
for(int i=0; i<numCeldas && celdas_rellenadas<tamGrid; i++){
//****************** Seleccionar cuadrado
indice_seleccionado = aleatorio.nextInt(enteros.size()); //Se escoge un número entre 0 y el tamaño del array enteros
seleccion = enteros.get(indice_seleccionado);
//Quitamos el elemento del ArrayList enteros para que no se vuelva a repetir el numero
enteros.remove(indice_seleccionado);
//Añadimos el numero seleccionado al array de magentas
finales_magenta.add(seleccion);
celdas_rellenadas++;
//****************** Seleccionar circulo
indice_seleccionado = aleatorio.nextInt(enteros.size()); //Se escoge un número entre 0 y el tamaño del array enteros
seleccion = enteros.get(indice_seleccionado);
//Quitamos el elemento del ArrayList enteros para que no se vuelva a repetir el numero
enteros.remove(indice_seleccionado);
//Añadimos el numero seleccionado al array de verdes
finales_verde.add(seleccion);
celdas_rellenadas++;
//**************** Seleccionar triangulo
indice_seleccionado = aleatorio.nextInt(enteros.size()); //Se escoge un número entre 0 y el tamaño del array enteros
seleccion = enteros.get(indice_seleccionado);
//Quitamos el elemento del ArrayList enteros para que no se vuelva a repetir el numero
enteros.remove(indice_seleccionado);
//Añadimos el numero seleccionado al array de rojo
finales_rojo.add(seleccion);
celdas_rellenadas++;
}
//Tenemos todos los aleatorios seleccionados. Ahora hay que rellenar la matriz
/*
Recordemos:
Boton vacío =>0
Cuadrado => 1
Triangulo => 2
Circulo => 3
*/
for(int i=0; i<finales_magenta.size();i++){
int indice = finales_magenta.get(i);
matrizEnteros[indice]=1;
}
for(int i=0; i<finales_rojo.size();i++){
int indice = finales_rojo.get(i);
matrizEnteros[indice]=3;
}
for(int i=0; i<finales_verde.size();i++){
int indice = finales_verde.get(i);
matrizEnteros[indice]=2;
}
return matrizEnteros;
}
public static boolean compruebaMatrices_juego2(int matrizOriginal[], int matrizJugador[], int numFilas, int numColumnas, int color){
boolean resultado = true;
int tamGrid = numFilas * numColumnas;
//Primero, hay que encontrar en qué posicion del vector están las figuras solución, y añadirlas a un ArayList
ArrayList<Integer> indices_solucion = new ArrayList<>();
for(int i=0; i< tamGrid;i++){
if(matrizOriginal[i]==color)
indices_solucion.add(i);
}
//Tenemos los indices solución. Debemos encontrar ahora los indices que ha contestado el usuario
ArrayList<Integer> indices_contestados = new ArrayList<>();
for (int i =0; i< tamGrid;i++){
if(matrizJugador[i]==color)
indices_contestados.add(i);
}
//Con los dos arrays de indices, comprobamos si son iguales (el jugador habría superado el nivel) o si son distintos
if (indices_contestados.size() != indices_solucion.size())
resultado = false;
else {
for (int i = 0; i < indices_contestados.size() && resultado; i++) {
if (!indices_solucion.contains(indices_contestados.get(i)))
resultado = false;
}
}
return resultado;
}
// ### JUEGO4 ### //
/**
* Función para obtener una matriz que tenga parejas dentro de ella.
* Tendrá tanatas parejas (de números) como la mitad del número de celdas.
*
* @param numFilas Numero de filas de la matriz que queremos generar
* @param numColumnas Numero de columnas de l matriz que queremos generar
* @return Un vector que simula la matriz.
*/
static public int[] obtenerMatrizParejas(int numFilas, int numColumnas) {
int tamMatriz = numFilas * numColumnas;
int numParejas = tamMatriz / 2;
int[] matrizResultado = new int[tamMatriz];
//Montamos esto con dos arrayList ya que es mas facil para no entrar en bucles del random
//Creamos una lista con los número que tendremos que hacer las parejas
List<Integer> numeros = new ArrayList<>();
if (depuracion)
System.out.println("## NUMEROS ##");
for (int i = 0; i<numParejas; i++) {
numeros.add(i);
if (depuracion)
System.out.print(numeros.get(i) + " ");
}
if (depuracion)
System.out.println("");
//Creamos una lista con las posiciones que se puede tener dentro de la matriz:
List<Integer> posiciones = new ArrayList<>();
if (depuracion)
System.out.println("## POSICIONES ##");
for (int i = 0; i < tamMatriz; i++) {
posiciones.add(i);
if (depuracion)
System.out.print(posiciones.get(i) + " ");
}
if (depuracion)
System.out.println("");
// ### ALGORITMO ###
Random rnd = new Random();
int elegido, posA, posB;
for (int i = 0; i < numParejas; i++) {
//1º. Sacamos un numero al azar del array de numeros. El numero dejara de estar en el array.
//Lo sacamos mediante un random con los indices del vector.
elegido = numeros.remove((int) (rnd.nextDouble() * numeros.size()));
//System.out.print(elegido+" ");
//2º Sacamos dos numeros de array de posiciones, que sera donde ira en la matriz resultado el numero elegido.
posA = posiciones.remove((int) (rnd.nextDouble() * posiciones.size()));
posB = posiciones.remove((int) (rnd.nextDouble() * posiciones.size()));
//System.out.print("A:"+posA+" B:"+posB);
//3º Introducimos esos valores en la matriz resultado
matrizResultado[posA] = elegido;
matrizResultado[posB] = elegido;
//System.out.println("");
}
return matrizResultado;
}
static public void leerMatrizParejas(int[] valores, int filas, int columnas) {
System.out.println("## Matriz de parejas ##");
int col = 1;
for (int i = 0; i < filas * columnas; i++) {
System.out.print(valores[i] + " ");
if (col == columnas) {
System.out.print("\n");
col = 1;
} else
col++;
}
}
static public int[] generaColores(int numColoresBase, int numColoresNecesarios){
int [] coloresDevueltos = new int[numColoresNecesarios];
//Creamos un array con los numeros.
List<Integer> numeros = new ArrayList<>();
System.out.println("## "+numColoresBase+" colores base ##");
for(int i=0; i<numColoresBase; i++){
numeros.add(i);
System.out.print(numeros.get(i)+" ");
}
System.out.println("");
//Rellenamos el vector a devolver con números extraidos de este:
//Inicializamos la semilla
Random rnd = new Random();
for(int i=0; i<numColoresNecesarios; i++){
coloresDevueltos[i]=numeros.remove((int)(rnd.nextDouble() * numeros.size()));
}
return coloresDevueltos;
}
static public void leeColores(int[] colores){
System.out.println("## "+colores.length+" colores elegidos ##");
for(int i=0; i<colores.length; i++)
System.out.print(colores[i]+" ");
}
static public String letraEquivalente(int numero){
//1 -> A
//25 -> Z
char letra = 'A'; // A es 65, el máximo es Z, 90
letra--;
letra+=numero;
return String.valueOf(letra);
}
static public String numeroRomanoEquivalente(int numero){
String n="";
switch(numero){
case 1:
n="I";
break;
case 2:
n="II";
break;
case 3:
n="III";
break;
case 4:
n="IV";
break;
case 5:
n="V";
break;
case 6:
n="VI";
break;
case 7:
n="VII";
break;
case 8:
n="VIII";
break;
case 9:
n="IX";
break;
case 10:
n="X";
break;
case 11:
n="XI";
break;
case 12:
n="XII";
break;
case 13:
n="XIII";
break;
case 14:
n="XIV";
break;
case 15:
n="XV";
break;
case 16:
n="XVI";
break;
case 17:
n="XVII";
break;
case 18:
n="XVIII";
break;
case 19:
n="XIX";
break;
case 20:
n="XX";
break;
case 21:
n="XXI";
break;
case 22:
n="XXII";
break;
case 23:
n="XXIII";
break;
case 24:
n="XXIV";
break;
case 25:
n="XXV";
break;
default:
n="";
break;
}
return n;
}
// ### JUEGO 5 ### //
/**
* Para generar de forma simple un número aleatorio entre dos valores inclusives.
* @param min Cota inferior
* @param max Cota superior
* @return Un valor aleatorio entre las cotas inclusives.
*/
static public int randInt(int min, int max) {
// NOTE: Usually this should be a field rather than a method
// variable so that it is not re-seeded every call.
Random rand = new Random();
// nextInt is normally exclusive of the top value,
// so add 1 to make it inclusive
int randomNum = rand.nextInt((max - min) + 1) + min;
return randomNum;
}
/**
* Generadora de secuencia de números aleatorios en posiciones aleatorias.
* Esta función genera una matriz (doble vector) con posiciones aleatorias y valores aleatorios
* para el 5º Juego.
* @param numElems Numero de elementos queremos generar (pareja posicion y valor)
* @param tamMatriz Tamaño de la matriz (para calcular posiciones de esta)
* @param rangoMin //Rango minimo de valores a generar.
* @param rangoMax //Rango máximo de valores a generar.
* @return El doble vector (matriz) con la información del valor en la posición que corresponde.
*/
static public int[][] generaSecuencia(int numElems, int tamMatriz, int rangoMin, int rangoMax){
final int numFilas=2;
/*
Creamos una matriz siempre de dos filas con tantas columnas como numElementos queramos rellenar.
Ojo!: No podremos construir un resultado con más elementos que el propio tamaño de la matriz, controlamos
esto y lanzamos una excepción abortando el proceso antes de nada. Por ahora no lo hacemos.
if(numElems>tamMatriz)
deten programa y lanza excepción
*/
int valores[][]= new int[numFilas][numElems];
// ## Algoritmo ## //
//Creamos y rellenamos un array con las posicones de la matriz:
List<Integer> posiciones = new ArrayList();
for(int i=0; i<tamMatriz; i++)
posiciones.add(i);
//Creamos y rellenamos un array con los posible valores:
List<Integer> numeros = new ArrayList();
for(int i=rangoMin; i<=rangoMax; i++) //Queremos que ambos valores estén dentro
numeros.add(i);
//1º Un bucle de tantos pasos como elementos queramos generar:
for(int i=0; i<numElems; i++){
//En la primera fila introducimos la POSICION en la matriz
//A la vez que introducimos sacamos ese valor de los posibles.
valores[0][i]=posiciones.remove(randInt(0,posiciones.size()-1));
//En la segunda fila introducimos el VALOR en esa posición de la matriz.
valores[1][i]=numeros.remove(randInt(0,numeros.size()-1));
}
//2º La ordenación del vector por los números (esto nos vendrá bien para aliviar de procesamiento al juego)
burbuja(valores, numElems);
return valores;
}
/**
* Adaptación del algoritmo de ordenación burbuja para matriz de dos filas donde se ordena por la fila 1.
* @param matriz Matriz a ordenar por la segunda fila
* @param size Tamaño de la matriz.
*/
public static void burbuja(int [][] matriz, int size){
int i, j, aux, aux2;
for(i=0;i<size-1;i++)
for(j=0;j<size-i-1;j++)
if(matriz[1][j+1]<matriz[1][j]){
aux=matriz[1][j+1];
matriz[1][j+1]=matriz[1][j];
matriz[1][j]=aux;
aux2=matriz[0][j+1];
matriz[0][j+1]=matriz[0][j];
matriz[0][j]=aux2;
}
}
}