Foros del Web » Programación para mayores de 30 ;) » C/C++ »

[SOLUCIONADO] Mastermind c++ (juego)

Estas en el tema de Mastermind c++ (juego) en el foro de C/C++ en Foros del Web. El Mastermind es un juego de tablero del tipo juego abstracto, donde se usa la capacidad de deducción por averiguar un código formado por letras ...
  #1 (permalink)  
Antiguo 30/11/2014, 11:46
 
Fecha de Ingreso: noviembre-2014
Mensajes: 22
Antigüedad: 9 años, 5 meses
Puntos: 0
Mastermind c++ (juego)

El Mastermind es un juego de tablero del tipo juego abstracto, donde se usa la capacidad de deducción por
averiguar un código formado por letras (colores en el original).

Cada tirada consiste en provar un código que damos, la máquina nos contestará cuantas letras hemos colocado bien, pero no cualas, y también
el número de aproximaciones que hemos puesto pero que no estan en el sitio correcto.

Os quería pedir ayuda porque ya tengo las dos primeras funciones que son:

string to_string (int valor)
Nos devolverá el entero del parámetro en forma de string.

bool válido (string, int n)
Nos devuelve cierto si todas las letras son minúsculas y que
Su longitud es igual a n.

y me falta una tercera:

string evaluar (string, string)
Debe evaluar una jugada, devolviendo un string de la forma "2A, 4ª" en el
caso de obtener 2 acertados y 4 aproximaciones.

Si alguien me pudiera ayudar estaría muy agradecido, y si alguien ha hecho este juego y quiere ayudar que envie mp jeje ^^
  #2 (permalink)  
Antiguo 30/11/2014, 11:51
 
Fecha de Ingreso: noviembre-2014
Mensajes: 22
Antigüedad: 9 años, 5 meses
Puntos: 0
Respuesta: Mastermind c++ (juego)

Si teneis alguna duda o no me he explicado suficientemente bien decidmelo porfavor
  #3 (permalink)  
Antiguo 30/11/2014, 12:35
 
Fecha de Ingreso: octubre-2014
Ubicación: Madrid
Mensajes: 1.212
Antigüedad: 9 años, 7 meses
Puntos: 204
Respuesta: Mastermind c++ (juego)

Y dónde está lo que llevas hecho de esas funciones?
  #4 (permalink)  
Antiguo 30/11/2014, 12:38
 
Fecha de Ingreso: noviembre-2014
Mensajes: 22
Antigüedad: 9 años, 5 meses
Puntos: 0
Respuesta: Mastermind c++ (juego)

Aqui las dejo:

Código C++:
Ver original
  1. string to_string (int n){
  2.  
  3.     stringstream iss;
  4.     iss<<n;
  5.     return iss.str();
  6. }


Código C++:
Ver original
  1. bool valida(string s, int n)
  2. {
  3.     if (s.size()!=n) return false; // SORTIDA IMMEDIATA DE LA FUNCIO
  4.     for (int i=0; i<s.size(); i++)
  5.     {
  6.         cout<<"Original: "<<s[i]<<" - Copia: "<<(char)tolower(s[i])<<endl;
  7.         if (s[i]!=(char)tolower(s[i]))
  8.         {
  9.             return false;
  10.         }
  11.     }
  12.     return true;
  13. }
  #5 (permalink)  
Antiguo 30/11/2014, 15:44
 
Fecha de Ingreso: septiembre-2010
Mensajes: 494
Antigüedad: 13 años, 7 meses
Puntos: 10
Respuesta: Mastermind c++ (juego)

Esta no es la mejor de las soluciones, porque hace recorridos dobles , breaks y engendros así, pero a estas horas.....
Código C++:
Ver original
  1. string evaluar (string cadena, string referencia);
  2.  
  3. int main()
  4. {
  5.  
  6.     cout<<evaluar("12345","54321")<<endl;
  7.     cout<<evaluar("abbcd","accbd")<<endl;
  8.     return 0;
  9. }
  10.  
  11. string evaluar (string cadena, string referencia)
  12. {
  13.     int acertados=0;
  14.     int aproximaciones=0;
  15.     //asumimos que las cadenas tienen el mismo tamaño
  16.     for (int i=0;i<cadena.size();i++)
  17.     {
  18.         if (cadena[i]==referencia[i])
  19.         {
  20.             acertados++;
  21.         }
  22.         else
  23.         {
  24.             for (int j=0;j<cadena.size();j++)
  25.             {
  26.                 if (cadena[i]==referencia[j])
  27.                 {
  28.                             aproximaciones++;
  29.                             break;
  30.                 }
  31.             }
  32.         }
  33.     }
  34.     stringstream iss;
  35.     iss<<acertados<<"A, "<<aproximaciones<<"a";
  36.     return iss.str();
  37. }

(creo que funciona)
Saludos!
__________________
Mi calculadora en Qt
  #6 (permalink)  
Antiguo 30/11/2014, 16:08
 
Fecha de Ingreso: octubre-2014
Ubicación: Madrid
Mensajes: 1.212
Antigüedad: 9 años, 7 meses
Puntos: 204
Respuesta: Mastermind c++ (juego)

Para comprobar si los caracteres están en minúsculas hay una forma mejor que ir recorriendo el string:

*Haces una copia del string
*Conviertes la copia a minúsculas
*Si ambos strings son iguales... pues eso

Vale que string no dispone de ningún método para hacer la conversión a minúsculas de forma directa, pero puedes valerte de la stl:

Código C++:
Ver original
  1. #include <algorithm>
  2.  
  3. std::string copia = cadena;
  4. std::transform(copia.begin(), copia.end(), copia.begin(), ::tolower);
  5.  
  6. if ( copia == cadena )
  7. ...

Por otro lado, el procedimiento para detectar las coincidencias podría ser algo más o menos así:

Código C++:
Ver original
  1. // Creamos un array para los resultados, así podemos ir marcando los aciertos
  2. std::vector< bool> resultado( cadena.length( ), false );
  3. int aciertos = 0;
  4. int aproximaciones = 0;
  5.  
  6. // Primero buscamos los aciertos
  7. for ( size_t i = 0; i < cadena.length( ); ++i )
  8. {
  9.   if ( cadena[ i ] == referencia[ i ] )
  10.   {
  11.     // Marcamos el acierto, esto nos permite evitar estos valores al contar las aproximaciones
  12.     resultado[ i ] = true;
  13.     aciertos++;
  14.   }
  15. }
  16.  
  17. // Después buscamos las aproximaciones
  18. for ( size_t i = 0; i < cadena.length( ); ++i )
  19. {
  20.   if ( !resultado[ i ] )
  21.   {
  22.     size_t aprox = 0;
  23.    
  24.     while( true )
  25.     {
  26.       // Buscamos la siguiente referencia
  27.       aprox = std::find( referencia, aprox );
  28.  
  29.       // Comprobamos si no se encuentran más referencias
  30.       if ( aprox ==  string::npos )
  31.         break;
  32.  
  33.       // Si la referencia no ha sido utilizada, la marcamos
  34.       if ( resultado[ aprox ] == 0 )
  35.       {
  36.         aproximaciones++;
  37.  
  38.         // eliminamos la aproximación de la referencia
  39.         referencia[ aprox ] = '_'; // Cualquier caracter que no pertenezca a la secuencia vale.
  40.         break;
  41.       }
  42.     }
  43.   }
  44. }
  45.  
  46. // Componemos el string
  47. return to_string( aciertos ) + "A, " + to_string( aproximaciones );

No lo he compilado, pero creo que debería funcionar.
  #7 (permalink)  
Antiguo 30/11/2014, 16:19
 
Fecha de Ingreso: noviembre-2014
Mensajes: 22
Antigüedad: 9 años, 5 meses
Puntos: 0
Respuesta: Mastermind c++ (juego)

Muchas gracias eferion por tu aportación. La verdad es que ahora me iba a la cama y no tengo tiempo de mirarmelo pero mañana lo haré a primera hora.

Gracias!
  #8 (permalink)  
Antiguo 01/12/2014, 03:32
 
Fecha de Ingreso: septiembre-2010
Mensajes: 494
Antigüedad: 13 años, 7 meses
Puntos: 10
Respuesta: Mastermind c++ (juego)

Pues si que estaba mal lo mío, ya que mi código dejaba que una posición fuera a la vez Acierto y Aproximación.

Ahora le he hecho un añadido para que no contemple esa doble condición:
Código C++:
Ver original
  1. #include <iostream>
  2. #include <cstring>
  3. #include <sstream>
  4.  
  5. using namespace std;
  6. string evaluar (string cadena, string referencia);
  7.  
  8. int main()
  9. {
  10.  
  11.     cout<<evaluar("12345","54321")<<endl;
  12.     cout<<evaluar("yybr","ygbr")<<endl;
  13.     return 0;
  14. }
  15.  
  16. string evaluar (string cadena, string referencia)
  17. {
  18.     int acertados=0;
  19.     int aproximaciones=0;
  20.     //asumimos que las cadenas tienen el mismo tamaño
  21.     for (int i=0; i<cadena.size(); i++)
  22.     {
  23.         if (cadena[i]==referencia[i])
  24.         {
  25.             acertados++;
  26.         }
  27.         else
  28.         {
  29.             for (int j=0; j<cadena.size(); j++)
  30.             {
  31.                 if (cadena[i]==referencia[j] && cadena[j]!=referencia[j])//aqui está el añadido
  32.                 {
  33.                     aproximaciones++;
  34.                     break;
  35.                 }
  36.             }
  37.         }
  38.     }
  39.     stringstream iss;
  40.     iss<<acertados<<"A, "<<aproximaciones<<"a";
  41.     return iss.str();
  42. }

A ver si ahora cumple mejor

Sobre lo de comprobar las minúsculas...eres la 2ª persona que propone esa forma (y ambos personas muy solventes), pero pienso que este método es menos eficaz, ya que obliga a crear una copia, pasarla a minúsculas, y entiendo que la sobrecarga del operador == igualmente hace un recorrido por la cadena.
¿Puede ser o estoy diciendo una tontería?
@b3salvat: En caso de duda, haz caso a eferion
__________________
Mi calculadora en Qt
  #9 (permalink)  
Antiguo 01/12/2014, 03:42
 
Fecha de Ingreso: octubre-2014
Ubicación: Madrid
Mensajes: 1.212
Antigüedad: 9 años, 7 meses
Puntos: 204
Respuesta: Mastermind c++ (juego)

Cita:
Iniciado por dehm Ver Mensaje
PSobre lo de comprobar las minúsculas...eres la 2ª persona que propone esa forma (y ambos personas muy solventes), pero pienso que este método es menos eficaz, ya que obliga a crear una copia, pasarla a minúsculas, y entiendo que la sobrecarga del operador == igualmente hace un recorrido por la cadena.
¿Puede ser o estoy diciendo una tontería?
Es un hecho que la inmensa mayoría de los programadores ve una gran preocupación en el rendimiento... antes incluso de ver la aplicación en funcionamiento.

Si necesitas que tu código se ejecute en millonésimas de segundo, o el algoritmo se ejecuta millones de veces de forma iterativa, entonces puede que tengas que preocuparte por optimizar el rendimiento (atención al "puede")... pero un algoritmo que interactua con el usuario, que se ejecuta una decena de veces, y que en cada iteración hace una copia de un string de 10 caracteres... por mucho que lo intentes optimizar no vas a notar ninguna diferencia. En cambio, sí vas a notar diferencias de tiempo entre depurar un código super optimizado y un código legible.

Y no, la optimización no suele llevarse bien con la legibilidad. Ya puestos, se podría optimizar aún más bajando a C... o a ensamblador directamente... creo que se entiende la idea.

Es menos óptimo? Sí, por supuesto
Merece la pena optimizar? Lo dudo mucho.
Decisión final? Depende de ti. Tu eres el diseñador de esa aplicación.
  #10 (permalink)  
Antiguo 01/12/2014, 08:16
 
Fecha de Ingreso: noviembre-2014
Mensajes: 22
Antigüedad: 9 años, 5 meses
Puntos: 0
Respuesta: Mastermind c++ (juego)

Dehm no me deja compilar tu último programa, me da error en la última llave (fila 36) y no sé porque..
  #11 (permalink)  
Antiguo 01/12/2014, 08:24
 
Fecha de Ingreso: octubre-2014
Ubicación: Madrid
Mensajes: 1.212
Antigüedad: 9 años, 7 meses
Puntos: 204
Respuesta: Mastermind c++ (juego)

Cita:
Iniciado por dehm Ver Mensaje
Sobre lo de comprobar las minúsculas...eres la 2ª persona que propone esa forma (y ambos personas muy solventes), pero pienso que este método es menos eficaz, ya que obliga a crear una copia, pasarla a minúsculas, y entiendo que la sobrecarga del operador == igualmente hace un recorrido por la cadena.
¿Puede ser o estoy diciendo una tontería?
@b3salvat: En caso de duda, haz caso a eferion
Por cierto, respecto a este comentario. No se si te has dado cuenta, pero tu código hace sendas copias de los strings cada vez que llamas a la función. No estás pasando los strings por referencia sino por valor, luego estás obligando a que se creen copias de las cadenas con cada llamada ;)
  #12 (permalink)  
Antiguo 01/12/2014, 08:27
 
Fecha de Ingreso: noviembre-2014
Mensajes: 22
Antigüedad: 9 años, 5 meses
Puntos: 0
Respuesta: Mastermind c++ (juego)

Además dehm, yo creo que tu primer programa hace exactamente lo que quería, pone los aciertos correctamente y las aproximaciones también..
Muchas gracias a los dos por ayudarme, marco el tema como solucionado y repito: gracias.
  #13 (permalink)  
Antiguo 01/12/2014, 09:35
 
Fecha de Ingreso: septiembre-2010
Mensajes: 494
Antigüedad: 13 años, 7 meses
Puntos: 10
Respuesta: Mastermind c++ (juego)

Cita:
Iniciado por eferion Ver Mensaje
No se si te has dado cuenta, pero tu código hace sendas copias de los strings cada vez que llamas a la función
ehhhh....quería respetar el prototipo de la función
(mentira, casi nunca me acuerdo de tener en cuenta esto)

@b3salvat: El caso es que nunca he jugado al mastermind, pero por lo que estoy viendo en el ejemplo de wikipedia, lo mio no funciona, ya que en caso de repetición de colores, siendo estos aproximaciones, sólo se consideran tantas aproximaciones como colores iguales haya en el patrón.

En el ejemplo de la wikipedia la secuencia a acertar es verde-rojo-azul-verde
Digamos que es en ingles grbg
Y se hacen dos intentos:
rojo-amarillo-rojo-verde ryrg
y
verde-verde-naranaja-rojo ggor
El primer intento arroja 1 acierto y 1 aproximación
El segundo 1 acierto y 2 aproximaciones

Pero mi código arroja 1 intento y 2 aproximaciones en ambos casos:
Código C++:
Ver original
  1. cout<<evaluar("ryrg","grbg")<<endl;
  2. cout<<evaluar("ggor","grbg")<<endl;

Eso es porque parece (viendo el ejemplo) que si tengo dos fichas rojas que no están en su sitio y un sóla ficha roja en el patrón, he de considerar sólo una aproximación.
Mira a ver el código de eferion, que seguramente lo hará mejor
__________________
Mi calculadora en Qt

Etiquetas: c++, funciones
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 14:18.