/* Genera una cadena de numeros que se tiene que adivinar. Por cada
numero que se acierta se pone una "o" en el lugar. Por cada fallo un "x" */
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <ctime>
using namespace std;
/* Prototipos de las funciones */
int elegirDificultad(void);
void generarSecuencia(int* cad, int dim);
bool unico(int* cad, int num);
bool hayGanador(int* oculto, int dim);
bool controlar(int* oculto, int* intento, int dim);
void convertirCadena(char* intento, int* intentoNumerico, int dim);
/* Funcion Principal del Juego */
int main(int argc, char* argv[]) {
int* oculto; // Secuencia generada
int* intento; // Secuencia del usuario
int dim; // Dimension de la cadena (Dificultad del juego)
cout << "********** ADIVINA EL NUMERO OCULTO **********" << endl;
dim = elegirDificultad() + 3; // Dificultad del juego
oculto = new int[dim];
generarSecuencia(oculto, dim); // Genera la secuencia
if(!hayGanador(oculto, dim)) { // Juego
cout << endl << "Lo sentimos. Mala suerte. Intentalo mas tarde" << endl;
} else {
cout << endl << "Felicidades!! Eres un experto. Aumenta la dificultad" << endl;
}
return EXIT_SUCCESS;
}
/**
* Se permite al usuario elegir la dificultad del juego
* @return: Dificultad del juego
*/
int elegirDificultad(void) {
int dificultad=0;
while(dificultad != 1 && dificultad != 2 && dificultad != 3) {
cout << "Ingrese la dificultad:" << endl;
cout << "1. Facil" << endl << "2. Medio" << endl << "3. Dificil" << endl << endl;
cout << "Dificultad: ";
cin >> dificultad;
}
return dificultad;
}
/**
* Genera la secuencia que hay que adivinar
* @var_cad: Guarda la cadena generada
* @var_dim: Dimension de la cadena generada
*/
void generarSecuencia(int* cad, int dim) {
int i, num;
int salidos[10];
// Inicializa para el control de repetidos
for(i=0; i<10; i++) {
salidos[i] = 0;
}
for(i=0; i<dim; i++) {
num
= rand() % 9 + 1; // Genera numeros entre 1-9 while(!unico(salidos, num)) { // Control de repetidos
}
salidos[i] = num;
cad[i] = num;
}
}
/**
* Controla que no existan numeros repetidos en la cadena
* @var_cad: Numeros que ya salieron
* @var_num: Numero que se quiere insertar
* @return: true si puede agregarse, false si no se puede
*/
bool unico(int* cad, int num) {
for (int i=0; i<10; i++) {
if(cad[i] == num) {
return false;
}
}
return true;
}
/**
* Argumento del juego
* @var_oculto: Secuencia a adivinar
* @var_dim: Dimension de la secuencia
* @return: true si hay ganador ; false si no hay
*/
bool hayGanador(int* oculto, int dim) {
bool win=false; // Para ver si hay ganador o no
char intento[dim]; // Secuencia del usuario
int intentoNumerico[dim];
int numIntentos=0; // Cantidad de intentos
int maxIntentos=dim*2; // Intentos Maximos
while(!win && numIntentos < maxIntentos) {
cout << endl << "Ingrese el numero de " << dim << " cifras." << endl;
cout << "Intento nro: " << ++numIntentos << " de " << maxIntentos << endl;
cin >> intento;
convertirCadena(intento, intentoNumerico, dim);
win = controlar(oculto, intentoNumerico, dim);
}
}
return win;
}
/**
* Convierte la cadena del usuario a una numerica
* @var_intento: Secuencia del usuario
* @var_intentoNumerico: Secuencia numerica
* @var_dim: Dimension de la secuencia
*/
void convertirCadena(char* intento, int* intentoNumerico, int dim) {
for(int i=0; i<dim; i++) {
switch(intento[i]) {
case '1':
intentoNumerico[i] = 1;
break;
case '2':
intentoNumerico[i] = 2;
break;
case '3':
intentoNumerico[i] = 3;
break;
case '4':
intentoNumerico[i] = 4;
break;
case '5':
intentoNumerico[i] = 5;
break;
case '6':
intentoNumerico[i] = 6;
break;
case '7':
intentoNumerico[i] = 7;
break;
case '8':
intentoNumerico[i] = 8;
break;
case '9':
intentoNumerico[i] = 9;
break;
}
}
}
/**
* Controla los aciertos del usuario
* @var_oculto: Secuencia a adivinar
* @var_intento: Secuencia del usuario
* @var_dim: Dimension de la secuencia
* @return: true si adivino todo ; false si no acerto
*/
bool controlar(int* oculto, int* intento, int dim) {
int aciertosFaltantes=dim;
for(int i=0; i<dim; i++) {
if(oculto[i] == intento[i]) {
cout << "o";
aciertosFaltantes--;
} else {
cout << "x";
}
}
cout << endl;
return !aciertosFaltantes;
}