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

Al repetir el programa tengo problemas con fichero o logica

Estas en el tema de Al repetir el programa tengo problemas con fichero o logica en el foro de C/C++ en Foros del Web. hola amigos, gracias por toda su ayuda. He terminado el juego de el ahorcado pero, tengo un problema a la hora de repetirlo. 1. Termina ...
  #1 (permalink)  
Antiguo 09/11/2015, 13:34
RGT
Usuario no validado
 
Fecha de Ingreso: noviembre-2008
Mensajes: 505
Antigüedad: 15 años, 5 meses
Puntos: 5
Pregunta Al repetir el programa tengo problemas con fichero o logica

hola amigos, gracias por toda su ayuda.

He terminado el juego de el ahorcado pero, tengo un problema a la hora de repetirlo.

1. Termina el juego.
2. Guardo el nombre del jugador, el puntaje y la palabra que se jugo en un fichero
3. Si se repite el programa, leo esos datos y los imprimo
4. Ahora entra el problema

Screenshot:


Se supone que me permita escribir el nombre, pero no lo hace. Esto empezó cuando puse la opcion de repetir el programa y cuando puse que se muestre esos datos guardados.

Abré hecho algo mal?..

Código completo:
Código:
#include <iostream>
#include <fstream>  // Librería para el manejo de archivos
#include <string>   // Librería para el manejo de strings
#include <cstdlib>  // Librería para el uso de system("cls"), system("pause") y atoi()
#include <cctype>   // Librería para clasificar y transformar caracteres individuales

using namespace std;

bool ValidarNombreJugador(string NombreJugador);
bool ValidarNumeroIngresado(string NumeroLetras);
bool ValidarPalabra(int NumeroLetras, fstream &FicheroPalabras);
void GuardarScore(string NombreJugador, string Palabra, int Intentos, fstream &FicheroScore);
void ProximaParteDibujo(int Linea);

string PalabraAdivinar;

int main()
{
    int RepetirPrograma = 1;
    bool VecesJugado = false;

    do
    {
        system("cls");

    fstream FicheroPalabras, FicheroScore;
    string NombreJugador, NumeroLetras, Respuesta;
    char Letra;
    int i, Intentos = 0, y = 0;
    const int MAX_INTENTOS = 7;
    bool LetraEncontrada = false, LetraRepetida = false;

/*  Creamos el fichero con las palabras a adivinar
------------------------------------------------------------------------*/
    cout << "Creando fichero con palabras..." << endl;
    FicheroPalabras.open("palabras.txt", ios::out);
    FicheroPalabras << "baloncesto\n";
    FicheroPalabras << "atletismo\n";
    FicheroPalabras << "natacion\n";
    FicheroPalabras << "beisbol\n";
    FicheroPalabras << "futbol\n";
    FicheroPalabras << "rugby\n";
    FicheroPalabras << "golf";
    FicheroPalabras.close();
    cout << "Fichero creado exitosamente..." << endl;

/*  Header del programa
------------------------------------------------------------------------*/
    cout << "\nJuego de El Ahorcado\n--------------------" << endl;
    cout << "Tema: Deportes\n" << endl;

/*  Mostramos el score del jugador anterior
------------------------------------------------------------------------*/
    if (VecesJugado == true)
    {
        string Nombre, Palabra, Numero;

        FicheroScore.open("score.txt", ios::in);
        FicheroScore >> Nombre >> Palabra >> Numero;
        cout << "BEST SCORE por " << Nombre << " con la palabra " << Palabra << " en " << Numero << " intentos." << endl;
        FicheroScore.close();
    }

/*  Content del programa
------------------------------------------------------------------------*/
    do
    {
        cout << "Escribe tu primer nombre: ";
        getline(cin, NombreJugador);
    } while(ValidarNombreJugador(NombreJugador));

    do
    {
        cout << "N\243mero de letras de la palabra: ";
        getline(cin, NumeroLetras);

    } while(!ValidarNumeroIngresado(NumeroLetras) || ValidarPalabra(atoi(NumeroLetras.c_str()), FicheroPalabras));

    Respuesta = "";
    for (int i = 0; i < PalabraAdivinar.size(); i++)
    {
         Respuesta += "_"; 
    }

    system("pause");

    do
    {
        system("cls");

        cout << "-------------------------------------------" << endl;
        cout << "| A D I V I N A     L A     P A L A B R A |";
        cout << "\n-------------------------------------------" << endl;
        cout << "                           INTENTOS: " << Intentos << " de " << MAX_INTENTOS << endl;

        cout << endl;
        for(i = 0; i < Respuesta.size(); i++)
        {
            cout << (char)toupper(Respuesta[i]) << "   ";
        }
        cout << endl;
        ProximaParteDibujo(Intentos);

       	if (LetraRepetida)
        {
            cout << "\n\tAviso!, letra ya ingresada..." << endl;
        }

        y = PalabraAdivinar.compare(Respuesta);
        if (y == 0)
            break;

        do
        {
            cout << "\nIntroduzca una letra ==> ";
            cin >> Letra;

            Letra = tolower(Letra);

            cout << "\n\tAviso!, solo se permiten letras..." << endl;

        } while(!isalpha(Letra));

        LetraEncontrada = false;
        LetraRepetida = false;

        for(i = 0; i < PalabraAdivinar.size(); i++)
        {
            if (Letra == Respuesta[i])
            {
                LetraRepetida =  true;
            }

            if (Letra == tolower(PalabraAdivinar[i]))
            {
                Respuesta[i] = Letra;
                LetraEncontrada = true;
            }

        }
        
        if (!LetraEncontrada)
        {
            Intentos++;
        }

    } while(Intentos < MAX_INTENTOS);

    if (Intentos == MAX_INTENTOS || y == 0)
    {
        if (y == 0)
        {
            cout << "\nFELICIDADES!, adivinaste la palabra..." << endl;
        }

        else
        {
            system("cls");

            cout << "-------------------------------------------" << endl;
            cout << "| A D I V I N A     L A     P A L A B R A |";
            cout << "\n-------------------------------------------" << endl;
            cout << "                           INTENTOS: " << Intentos << " de " << MAX_INTENTOS << endl;

            cout << endl;
            for(i = 0; i < Respuesta.size(); i++)
            {
                cout << (char)toupper(Respuesta[i]) << "   ";
            }
            cout << endl;

            ProximaParteDibujo(Intentos);

            cout << "\nINCORRECTO!, la palabra correcta era \"" << PalabraAdivinar << "\"." << endl;
            cout << "\n|====================================|" << endl;
            cout << "|\tFIN\tDEL\tJUEGO\t     |" << endl;
            cout << "|====================================|" << endl;
        }
    }

    //Guardamos el Score en otro fichero
    GuardarScore(NombreJugador, PalabraAdivinar, Intentos, FicheroScore);
    VecesJugado = true;

    cout << "\nDes\202a jugar otra vez? (OTRO NUMERO = SI, 0 = NO) ==> ";
    cin >> RepetirPrograma;

    } while(RepetirPrograma != 0);

    return 0;
}

/*  Validar el nombre del jugador
------------------------------------------------------------------------*/
bool ValidarNombreJugador(string NombreJugador)
{
    int i = 0, Salir = 0;

    while(NombreJugador[i])
    {
        if (isalpha(NombreJugador[i]))
            Salir++;

        else
            Salir = 0;

        i++;
    }

    if (Salir == NombreJugador.size())
    {
        cout << "\n\tEnhorabuena!, nombre v\240lido...\n" << endl;
        return false;
    }

    else
    {
        cout << "\n\tError!, nombre inv\240lido...\n" << endl;
        return true;
    }
}

/*  Validar el número ingresado
------------------------------------------------------------------------*/
bool ValidarNumeroIngresado(string NumeroLetras)
{

    if (isdigit(NumeroLetras[0]))
    {
        cout << "\n\tEnhorabuena!, n\243mero v\240lido...\n" << endl;
        return true;
    }

    else
    {
        cout << "\n\tError!, n\243mero inv\240lido...\n" << endl;
        return false;
    }
}

/*  Validar que exista una palabra con el número de letras ingresado
------------------------------------------------------------------------*/
bool ValidarPalabra(int NumeroLetras, fstream &FicheroPalabras)
{
    string Palabra;
    bool PalabraEncontrada = true;
    int Resultado;

    FicheroPalabras.open("palabras.txt", ios::in);

    while (PalabraEncontrada)
    {
        if (FicheroPalabras.eof())
        {
            PalabraEncontrada = false;
            Resultado = 1;
        }

        else
        {
            getline(FicheroPalabras, Palabra);

            if (Palabra.size() == NumeroLetras)
            {
                PalabraAdivinar = Palabra;  //Guardamos la palabra en una variable global
                PalabraEncontrada = false;
                Resultado = 2;
            }
        }
    }

    FicheroPalabras.close();

    if (Resultado == 1)
    {
        cout << "\tError!, no hay palabras de " << NumeroLetras << " letras en el juego...\n" << endl;
        return true;
    }

    else
    {
        cout << "\tEnhorabuena!, palabra de " << NumeroLetras << " letras encontrada..." << endl;
        return false;
    }
}

/*  Guardamos el score en otro fichero
------------------------------------------------------------------------*/
void GuardarScore(string NombreJugador, string Palabra, int Intentos, fstream &FicheroScore)
{
    cout << "\nGuardando el score en otro fichero..." << endl;
    FicheroScore.open("score.txt", ios::out);
    FicheroScore << NombreJugador << endl;
    FicheroScore << Palabra << endl;
    FicheroScore << Intentos;
    FicheroScore.close();
    cout << "Fichero creado exitosamente..." << endl;
}

/*  El muñeco ahorcado
------------------------------------------------------------------------*/
void ProximaParteDibujo(int Linea)
{
    string dibujo[] =
    {
    	"__________\n",
    	"|     |   \n",
    	"|     |   \n",
    	"|     O   \n",
    	"|   /{ }\\\n",
    	"|    [ ]  \n",
    	"|   _| |_ \n"
    };

    for (int i = 0; i < Linea; i++)
        cout << dibujo[i];
}
Espero puedan ayudarme, ya no encuentro solucion.
Marque en rojo los cambios que hize...
  #2 (permalink)  
Antiguo 10/11/2015, 03:07
 
Fecha de Ingreso: octubre-2014
Ubicación: Madrid
Mensajes: 1.212
Antigüedad: 9 años, 6 meses
Puntos: 204
Respuesta: Al repetir el programa tengo problemas con fichero o logica

Insisto... ¿por qué esa obsesión por pasar el stream como argumento? ¿Tienes miedo a crear el stream cada vez que lo vayas a usar?
__________________
La ayuda se paga con esfuerzo o con dinero. Si no estás dispuesto a esforzarte y quieres que te hagan los deberes pide presupuesto, al menos así ahorrarás tiempo.
  #3 (permalink)  
Antiguo 10/11/2015, 04:32
 
Fecha de Ingreso: febrero-2015
Mensajes: 404
Antigüedad: 9 años, 2 meses
Puntos: 3
Respuesta: Al repetir el programa tengo problemas con fichero o logica

Es que pasar un fstream por referencia para luego abrirlo y cerrarlo dentro de la funcion y no sacar ningun probecho de ello es lo mismo que declararla dentro de la funcion y que se quede solo con ese ambito. Pasarla como parametro es inutil ahi. Otra cosa es que por ejemplo se abriese en esa funcion y se cerrase en otro lugar pero si todo lo haces en una misma funcion es absurdo pasarle el parametro ese.
  #4 (permalink)  
Antiguo 10/11/2015, 08:39
RGT
Usuario no validado
 
Fecha de Ingreso: noviembre-2008
Mensajes: 505
Antigüedad: 15 años, 5 meses
Puntos: 5
Pregunta Respuesta: Al repetir el programa tengo problemas con fichero o logica

Cita:
Iniciado por eferion Ver Mensaje
Insisto... ¿por qué esa obsesión por pasar el stream como argumento? ¿Tienes miedo a crear el stream cada vez que lo vayas a usar?
Ambos tienen razón, simplemente estaba probando, practicando se podria decir..... Viendo los pros y los cons....... Lo arreglare.

Aun asi sigo con el problema comentado en este topic, podria ayudarme a identificar cual es....... :(
  #5 (permalink)  
Antiguo 10/11/2015, 09:13
 
Fecha de Ingreso: octubre-2014
Ubicación: Madrid
Mensajes: 1.212
Antigüedad: 9 años, 6 meses
Puntos: 204
Respuesta: Al repetir el programa tengo problemas con fichero o logica

Cita:
Iniciado por RGT Ver Mensaje
Viendo los pros y los cons.......
Un método únicamente debe recibir un parámetro cuando realmente lo necesita y esto es:
  • Si el método necesita información que no es capaz de calcular por sí mismo
  • Si el método necesita información que no es conveniente que calcule por sí mismo (por ejemplo cálculos costosos que se puedan precalcular o porque no sea competencia de dicha clase)
  • Si el método necesita proporcionar un resultado via ese parámetro
Si no se cumple ninguna de esas condiciones lo más normal es que el parámetro que intentas poner sea, dicho claramente, absurdo. Hay ciertas prácticas que ayudan a que el código sea más complicado de mantener y, en cambio, no aportan absolutamente nada... este tipo de casos encajan en este perfil.

Por otro lado, te interesará saber que cada vez que pasas por valor un std::string como parámetro de una función realmente estás haciendo una copia de ese string... lo cual podría ser una práctica a evitar. La norma general al pasar objetos a funciones (siempre y cuando éstos no vayan a ser modificados dentro del método) es pasarlos como referencia ya que así evitas realizar copias sin sentido de los objetos.

Reconozco también que este último punto ya empieza a entrar en la parte oscura de C++ y remarco que depende de la clase que estemos gestionando. En el caso de std::string pues sí, es recomendable, sin embargo hay otras clases que internamente gestionan su estado como si de un smart pointer se tratase. En estos casos sería irrelevante pasar el objeto por valor o referencia ya que el coste computacional va a ser prácticamente el mismo.

Cita:
Iniciado por RGT Ver Mensaje
Aun asi sigo con el problema comentado en este topic, podria ayudarme a identificar cual es....... :(
Ahora mismo el programa te muestra los datos de ese fichero no cuando juegas una segunda vez... sino cuando juegas una segunda partida consecutiva. Es decir, cada vez que arranques el juego te quedarás sin ver los records, estos únicamente se mostrarán si, al terminar la una partida decides iniciar otra sin salir del programa.

¿No es lo que quieres? tal vez entonces necesitas reconsiderar la lógica de tu programa. No se, quizás dejando de evaluar VecesJugado que, todo dicho sea de paso, a mi ese nombre me invita a pensar que contiene un entero, no un booleano. Quizás ese nombre no sea el más adecuado. Aunque esto te parezca una soberana tontería ya te adelanto que no lo es. Cuando tengas que lidiar con un programa con decenas de variables, como te de por poner nombres raros vas a flipar cuando tengas que corregir errores.

Piensa al respecto que una de las técnicas para dificultar que alguien copie un código fuente para uso propio consiste en ofuscarlo... y en ese proceso una de las primeras tareas a realizar es sustituir los nombres de las variables y de los métodos por otros aleatorios... y te garantizo que el código resultante es bastante infumable así de primeras. Imagínate algo del tipo:

Código C++:
Ver original
  1. int A003(int m00, int m000, std::string m0000)
  2. {
  3.   if( m00 < m000 && m00 ) A045(m00+4,m00-3);
  4.   else if( m000 ) Z404(m0000);
  5.   else return m000-m00;
  6.  
  7.   return  __d34d(m0000);
  8. }

Piensa en ello.
__________________
La ayuda se paga con esfuerzo o con dinero. Si no estás dispuesto a esforzarte y quieres que te hagan los deberes pide presupuesto, al menos así ahorrarás tiempo.

Última edición por eferion; 10/11/2015 a las 09:21
  #6 (permalink)  
Antiguo 10/11/2015, 09:23
RGT
Usuario no validado
 
Fecha de Ingreso: noviembre-2008
Mensajes: 505
Antigüedad: 15 años, 5 meses
Puntos: 5
Respuesta: Al repetir el programa tengo problemas con fichero o logica

Vale, entiendo tu punto, haré algunas correciones. Gracias por tu ayuda y por la explicacion..

Una ultima cosa, al forma que utilizo (do-while) para repetir el programa, esta bien hecho?.
  #7 (permalink)  
Antiguo 10/11/2015, 09:27
 
Fecha de Ingreso: octubre-2014
Ubicación: Madrid
Mensajes: 1.212
Antigüedad: 9 años, 6 meses
Puntos: 204
Respuesta: Al repetir el programa tengo problemas con fichero o logica

Cita:
Introduce un número aleatorio diferente de 0 si quieres iniciar una nueva partida
Te suena bien ese mensaje? Parece lógico y coherente? Te gustaría recibir un mensaje así cuando te matan mientras juegas una partida?

Cita:
Quieres jugar de nuevo? 1 => SI, 0 => NO
¿Qué opinas de este otro? ¿Cual te parece más adecuado?

El do-while, como tal... pues si, está bien; funciona de forma coherente al mensaje que pones. Ahora a la pregunta ¿debería funcionar así? no te podría responder afirmativamente.
__________________
La ayuda se paga con esfuerzo o con dinero. Si no estás dispuesto a esforzarte y quieres que te hagan los deberes pide presupuesto, al menos así ahorrarás tiempo.
  #8 (permalink)  
Antiguo 10/11/2015, 09:31
 
Fecha de Ingreso: febrero-2015
Mensajes: 404
Antigüedad: 9 años, 2 meses
Puntos: 3
Respuesta: Al repetir el programa tengo problemas con fichero o logica

Para esto es muy bueno plantear antes el código con pseudocodigo o aun mejor con organigramas. Para esto último tienes un programa muy bueno llamado Visustin que convierte tu código en organigrama y te ayuda a ver mejor lo que pasa.
  #9 (permalink)  
Antiguo 10/11/2015, 09:32
RGT
Usuario no validado
 
Fecha de Ingreso: noviembre-2008
Mensajes: 505
Antigüedad: 15 años, 5 meses
Puntos: 5
Respuesta: Al repetir el programa tengo problemas con fichero o logica

Hola, En un inicio la segunda forma que mencionas, era la que yo quería, pero en su momento no logré hacerlo.

Ej:

int RepetirPrograma = 1;

do
{
cout << "Desea repetir el programa (1 = SI, 0 = NO):";
cin >> RepetirPrograma;
} while (RepetirPrograma == 1);

Esta correcto eso?...
  #10 (permalink)  
Antiguo 10/11/2015, 09:47
 
Fecha de Ingreso: octubre-2014
Ubicación: Madrid
Mensajes: 1.212
Antigüedad: 9 años, 6 meses
Puntos: 204
Respuesta: Al repetir el programa tengo problemas con fichero o logica

Cita:
Iniciado por RGT Ver Mensaje
Esta correcto eso?...
Si introduces un 5:
  1. ¿Qué sucede?
  2. ¿Es el comportamiento esperado?

Yo a esto respondería lo siguiente:
  1. se cierra el programa
  2. hombre, yo esperaría un mensaje de error y que me volviese a preguntar... lo mismo me he confundido y quería decir que sí, que quiero jugar de nuevo.
__________________
La ayuda se paga con esfuerzo o con dinero. Si no estás dispuesto a esforzarte y quieres que te hagan los deberes pide presupuesto, al menos así ahorrarás tiempo.
  #11 (permalink)  
Antiguo 10/11/2015, 12:28
 
Fecha de Ingreso: febrero-2015
Mensajes: 404
Antigüedad: 9 años, 2 meses
Puntos: 3
Respuesta: Al repetir el programa tengo problemas con fichero o logica

Para eso que te dice eferion lo mejor es usar switch y usas la opción default para las respuestas que se salgan de lo esperado. Un ejemplo muy básico:
Código C:
Ver original
  1. int op, salir=0;
  2. do {
  3.    printf("1.repetir   2.salir");
  4.    scanf ("%i",&op);
  5.    switch (op){
  6.        case 1:
  7.           //función a repetir;
  8.           break;
  9.        case 2:
  10.           salir=1;
  11.           break;
  12.        default:
  13.           printf ("Opción elegida no válida.  Vuelve a inrentarlo");
  14.    }
  15. }while (salir==0);

Última edición por aguml; 10/11/2015 a las 12:37
  #12 (permalink)  
Antiguo 10/11/2015, 14:28
RGT
Usuario no validado
 
Fecha de Ingreso: noviembre-2008
Mensajes: 505
Antigüedad: 15 años, 5 meses
Puntos: 5
Pregunta Respuesta: Al repetir el programa tengo problemas con fichero o logica

Cita:
Iniciado por eferion Ver Mensaje
Insisto... ¿por qué esa obsesión por pasar el stream como argumento? ¿Tienes miedo a crear el stream cada vez que lo vayas a usar?
Es de esta manera cierto:

Código:
/*  Creamos el fichero con las palabras a adivinar
------------------------------------------------------------------------*/
    ofstream FicheroPalabras;
    cout << "Creando fichero con palabras..." << endl;
    FicheroPalabras.open("palabras.txt", ios::out);
    FicheroPalabras << "baloncesto\n";
    FicheroPalabras << "atletismo\n";
    FicheroPalabras << "natacion\n";
    FicheroPalabras << "beisbol\n";
    FicheroPalabras << "futbol\n";
    FicheroPalabras << "rugby\n";
    FicheroPalabras << "golf";
    FicheroPalabras.close();
    cout << "Fichero creado exitosamente..." << endl;
Si es asi, pregunta: si lo hago de esa manera siempre, ofstream para escribir y ifstream para leer. Si en otro sitio vuelvo a declararlo de esa forma para abrir el fichero, debo ponerle ios::app siempre?. o solamente es si voy a escribir otras cosas?

esto de los ficheros y sus reglas me confunde.
  #13 (permalink)  
Antiguo 10/11/2015, 15:07
 
Fecha de Ingreso: febrero-2015
Mensajes: 404
Antigüedad: 9 años, 2 meses
Puntos: 3
Respuesta: Al repetir el programa tengo problemas con fichero o logica

Cita:
Iniciado por RGT Ver Mensaje
Es de esta manera cierto:

Código:
/*  Creamos el fichero con las palabras a adivinar
------------------------------------------------------------------------*/
    ofstream FicheroPalabras;
    cout << "Creando fichero con palabras..." << endl;
    FicheroPalabras.open("palabras.txt", ios::out);
    FicheroPalabras << "baloncesto\n";
    FicheroPalabras << "atletismo\n";
    FicheroPalabras << "natacion\n";
    FicheroPalabras << "beisbol\n";
    FicheroPalabras << "futbol\n";
    FicheroPalabras << "rugby\n";
    FicheroPalabras << "golf";
    FicheroPalabras.close();
    cout << "Fichero creado exitosamente..." << endl;
Si es asi, pregunta: si lo hago de esa manera siempre, ofstream para escribir y ifstream para leer. Si en otro sitio vuelvo a declararlo de esa forma para abrir el fichero, debo ponerle ios::app siempre?. o solamente es si voy a escribir otras cosas?

esto de los ficheros y sus reglas me confunde.
Aquí puedes ver para que es cada parametro:
http://www.cplusplus.com/doc/tutorial/files/
Deberías leer algún tutorial o algún libro sobre C++ porque vas dando palos de ciego.
  #14 (permalink)  
Antiguo 10/11/2015, 15:16
RGT
Usuario no validado
 
Fecha de Ingreso: noviembre-2008
Mensajes: 505
Antigüedad: 15 años, 5 meses
Puntos: 5
Respuesta: Al repetir el programa tengo problemas con fichero o logica

Cita:
Iniciado por aguml Ver Mensaje
Aquí puedes ver para que es cada parametro:
http://www.cplusplus.com/doc/tutorial/files/
Deberías leer algún tutorial o algún libro sobre C++ porque vas dando palos de ciego.
Bien me sirvio, este es mi codigo ahora:
http://codeshare.io/OSq4R

como lo ves?.

Etiquetas: caracteres, char, fichero, int, logica, numero, programa, repetir, string
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 18:25.