Foro de elhacker.net

Programación => Programación C/C++ => Mensaje iniciado por: HectorSersi en 22 Noviembre 2018, 20:37 pm



Título: Ayuda con programa
Publicado por: HectorSersi en 22 Noviembre 2018, 20:37 pm
Hola buenas, me gustaria hacer que al escoger el modo A, se abriese un archivo de texto(el que el usuario teclee) para poder leer varios numeros. El problema es que creo que ya tengo el codigo bien pero no me ejecuta y no se que hacer para poder acabarlo... por favor una ayudita.

Gracias :)

Código
  1. #include <iostream>
  2. #include <cstdlib>
  3. #include<ctime>
  4. #include<conio.h>
  5. #include<fstream>
  6. #include<string>
  7. #include<istream>
  8.  
  9. using namespace std;
  10. int menu();
  11. int abrir();
  12.  
  13.  
  14. int main()
  15. {
  16. int modo;
  17.  
  18.  
  19. modo = menu();
  20.  
  21.  
  22.  
  23. system("PAUSE");
  24.  
  25. return 0;
  26. }
  27.  
  28.  
  29. int menu()
  30. {
  31. int modo;
  32.  
  33. bool exit = false;
  34. do {
  35.  
  36. cout << "Introduce 1 para Modo A: cada jugador estara obligado, cuando le llegue el turno, a robar un numero concreto de cartas." << endl;
  37. cout << "Introduce 2 para Modo B: cada jugador podra robar el numero de cartas que desee y plantarse si no quiere mas." << endl;
  38. cout << "Introducir 0 para salir del juego." << endl;
  39. cout << endl;
  40. cout << "Introduce el modo al que quieres jugar; 1, 2 o 0: ";
  41. cin >> modo;
  42.  
  43.  
  44. switch (modo)
  45. {
  46. case 1: cout << "Ha elegido el modo A" << endl; break;
  47. case 2: cout << "Ha elegido el modo B" << endl; break;
  48. case 0: exit = true;
  49. default: cout << "No ha seleccionado ningun modo." << endl;
  50. }
  51.  
  52.  
  53. } while (modo < 0 || modo > 2);
  54.  
  55.  
  56. system("PAUSE");
  57.  
  58.  
  59. return(modo);
  60.  
  61. }
  62.  
  63.  
  64. int abrir(int menu)
  65. {
  66. int modo;
  67.  
  68.  
  69. if (modo == 1)
  70. {
  71.  
  72.  
  73. ifstream archivo;
  74. string text, texto;
  75.  
  76. cout << "Ingrese nombre o direccion del archivo a leer: ";
  77. getline(cin, text);
  78. text += ".txt";
  79.  
  80. archivo.open(text.c_str(), ios::in);
  81.  
  82.  
  83. if (archivo.fail()) {
  84.  
  85. cout << "No se ha podido abrir el archivo";
  86. exit(1);
  87.  
  88. }
  89.  
  90. while (!archivo.eof())
  91. {
  92. getline(archivo, text);
  93. cout << text << endl;
  94.  
  95. }
  96.  
  97. archivo.close();
  98.  
  99. _getch();
  100.  
  101.  
  102. }
  103.  
  104. return (menu);
  105. }


Título: Re: Ayuda con programa
Publicado por: K-YreX en 22 Noviembre 2018, 22:28 pm
No estás usando la función <abrir>, así es imposible que funcione. Además de eso no sé si el fallo es ese o es otra cosa entonces si te sale algún error de compilación inclúyelo en el mensaje.

PD: Por favor, no usar <conio.h>, ni <system("pause")> y creo recordar que la librería <istream> no es necesaria.


Título: Re: Ayuda con programa
Publicado por: HectorSersi en 24 Noviembre 2018, 14:16 pm
No estás usando la función <abrir>, así es imposible que funcione. Además de eso no sé si el fallo es ese o es otra cosa entonces si te sale algún error de compilación inclúyelo en el mensaje.

PD: Por favor, no usar <conio.h>, ni <system("pause")> y creo recordar que la librería <istream> no es necesaria.


Hola, gracias por responder, he quitado el system("PAUSE") y las librerias que me has dicho pero sigo sin saber como hacer para usar la funcion abir... y los errores que me salen al compilar son estos:

"El identificador getch no esta definido"
"No se encontró el identificador _getch"


Título: Re: Ayuda con programa
Publicado por: K-YreX en 24 Noviembre 2018, 14:31 pm
<getch()> es una función de la librería <conio.h> pero esta librería no es estándar por eso no se recomienda su uso. Hay alternativas estándar para <getch()> como por ejemplo <cin.get()>.
Prueba a cambiar eso y me comentas. Suerte.

Edit: El <system("pause")> también puede sustituirse por <cin.get()> ya que su objetivo es hacer una pausa pero de esta manera no tienes que hacer una llamada al sistema lo cual es bastante costoso.


Título: Re: Ayuda con programa
Publicado por: HectorSersi en 24 Noviembre 2018, 23:03 pm
<getch()> es una función de la librería <conio.h> pero esta librería no es estándar por eso no se recomienda su uso. Hay alternativas estándar para <getch()> como por ejemplo <cin.get()>.
Prueba a cambiar eso y me comentas. Suerte.

Edit: El <system("pause")> también puede sustituirse por <cin.get()> ya que su objetivo es hacer una pausa pero de esta manera no tienes que hacer una llamada al sistema lo cual es bastante costoso.


Muchas gracias, solo me queda el tema de la funcion abrir... me salen 2 errores al compilar:

"abrir" no todas las rutas de acceso de control devuelven un valor
se utilizo la variable local "modo" sin inicializar

no entiendo muy bien lo de modo.


Título: Re: Ayuda con programa
Publicado por: K-YreX en 24 Noviembre 2018, 23:17 pm
El prototipo de la función <abrir> no tiene parámetros pero luego en su implementación sí tiene un parámetro de tipo <int> :huh:
Si estás haciendo cambios en el programa vuelve a mandar el código para ver como lo tienes ahora ya que no es igual que el que mandaste al principio.


Título: Re: Ayuda con programa
Publicado por: HectorSersi en 25 Noviembre 2018, 12:10 pm
El prototipo de la función <abrir> no tiene parámetros pero luego en su implementación sí tiene un parámetro de tipo <int> :huh:
Si estás haciendo cambios en el programa vuelve a mandar el código para ver como lo tienes ahora ya que no es igual que el que mandaste al principio.

Estos son los cambios que he hecho, y los errores son los mismos del mensaje anterior.

Código
  1. #include <iostream>
  2. #include <cstdlib>
  3. #include<ctime>
  4. #include<fstream>
  5. #include<string>
  6.  
  7.  
  8. using namespace std;
  9. int menu();
  10. int abrir();
  11.  
  12.  
  13. int main()
  14. {
  15. int modo;
  16.  
  17.  
  18. modo = menu();
  19.  
  20.  
  21.  
  22. system("PAUSE");
  23.  
  24. return 0;
  25. }
  26.  
  27.  
  28. int menu()
  29. {
  30. int modo;
  31.  
  32. bool exit = false;
  33. do {
  34.  
  35. cout << "Introduce 1 para Modo A: cada jugador estara obligado, cuando le llegue el turno, a robar un numero concreto de cartas." << endl;
  36. cout << "Introduce 2 para Modo B: cada jugador podra robar el numero de cartas que desee y plantarse si no quiere mas." << endl;
  37. cout << "Introducir 0 para salir del juego." << endl;
  38. cout << endl;
  39. cout << "Introduce el modo al que quieres jugar; 1, 2 o 0: ";
  40. cin >> modo;
  41.  
  42.  
  43. switch (modo)
  44. {
  45. case 1: cout << "Ha elegido el modo A" << endl; break;
  46. case 2: cout << "Ha elegido el modo B" << endl; break;
  47. case 0: exit = true;
  48. default: cout << "No ha seleccionado ningun modo." << endl;
  49. }
  50.  
  51.  
  52. } while (modo < 0 || modo > 2);
  53.  
  54.  
  55. system("PAUSE");
  56.  
  57.  
  58. return(modo);
  59.  
  60. }
  61.  
  62.  
  63. int abrir(int menu)
  64. {
  65. int modo;
  66.  
  67.  
  68. if (modo == 1)
  69. {
  70.  
  71.  
  72. ifstream archivo;
  73. string text, texto;
  74.  
  75. cout << "Ingrese nombre o direccion del archivo a leer: ";
  76. getline(cin, text);
  77. text += ".txt";
  78.  
  79. archivo.open(text.c_str(), ios::in);
  80.  
  81.  
  82. if (archivo.fail()) {
  83.  
  84. cout << "No se ha podido abrir el archivo";
  85. exit(1);
  86.  
  87. }
  88.  
  89. while (!archivo.eof())
  90. {
  91. getline(archivo, text);
  92. cout << text << endl;
  93.  
  94. }
  95.  
  96. archivo.close();
  97.  
  98. cin.get();
  99.  
  100.  
  101. }
  102.  
  103. }


Título: Re: Ayuda con programa
Publicado por: K-YreX en 25 Noviembre 2018, 13:43 pm
Lo primero que no sé que idea tienes en la cabeza entonces no sé por qué haces algunas de las cosas que haces:
- El prototipo de la función <abrir()> no tiene parámetros, pero la definición de la función <abrir()> tiene un parámetro de tipo <int>. :huh:
- La función <menu()> está casi bien. Si la opción es 0 cambias el valor a una variable de tipo bool que no sé cual es su utilidad.  :huh:
- Además según tú, la función <abrir()> devuelve un valor de tipo <int> y tu función no devuelve nada. :huh:
- En la función <abrir()> compruebas que la variable <modo> sea 1 pero la variable <modo> no está inicializada.  :huh: Ahí lo único que tendría un poco de sentido sería que en vez de <modo == 1> quieras hacer <menu == 1>. Pero tienes que corregirlo.
- Y por último en todo el programa no llamas a la función <abrir()>  :huh:


Título: Re: Ayuda con programa
Publicado por: HectorSersi en 3 Diciembre 2018, 22:23 pm
Lo primero que no sé que idea tienes en la cabeza entonces no sé por qué haces algunas de las cosas que haces:
- El prototipo de la función <abrir()> no tiene parámetros, pero la definición de la función <abrir()> tiene un parámetro de tipo <int>. :huh:
- La función <menu()> está casi bien. Si la opción es 0 cambias el valor a una variable de tipo bool que no sé cual es su utilidad.  :huh:
- Además según tú, la función <abrir()> devuelve un valor de tipo <int> y tu función no devuelve nada. :huh:
- En la función <abrir()> compruebas que la variable <modo> sea 1 pero la variable <modo> no está inicializada.  :huh: Ahí lo único que tendría un poco de sentido sería que en vez de <modo == 1> quieras hacer <menu == 1>. Pero tienes que corregirlo.
- Y por último en todo el programa no llamas a la función <abrir()>  :huh:


Vale, te explico. Lo que quiero hacer es un juego de cartas. He hecho un menú y lo que quiero hacer es que al seleccionar el modo A en el menú, ponga: "Se ha seleccionado el modo A" y depues de esto se me abra el archivo de texto que tiene una serie de numeros enteros ( que son las cartas)... lo que quiero es hacer el llamamiento del double modoA del archivo de texto a esta funcion pero no se como. Se me pide que el juego use •   double modoA(ifstream & file, int numCartas)  que permite a cualquiera de los dos jugadores realizar su turno en el modo de juego A. Recibe el archivo con el mazo y el número de cartas que hay que robar, y devuelve los puntos obtenidos tras robar ese número de cartas, obtener 7,5 o pasarse. El archivo que quiero abrir se llama: text, lo digo para indicarme el que cambiar.

Necesito ayuda con el codigo(lo he cambiado y creo que esta mejor), estoy perdido... Gracias.

Código
  1. #include <cstdlib>
  2. #include<ctime>
  3. #include<fstream>
  4. #include<string>
  5.  
  6.  
  7. using namespace std;
  8.  
  9. #define HUMANO =1;
  10. #define MAQUINA =2;
  11.  
  12. int menu();
  13. int abrir();
  14.  
  15. void lectura(int modo);
  16.  
  17. int main()
  18. {
  19. int modo;
  20.  
  21. modo = menu();
  22. lectura(modo);
  23.  
  24. system("PAUSE");
  25.  
  26. return 0;
  27. }
  28.  
  29.  
  30. int menu()
  31. {
  32. int modo;
  33.  
  34. bool exit = false;
  35. do {
  36.  
  37. cout << "Introduce 1 para Modo A: cada jugador estara obligado, cuando le llegue el turno, a robar un numero concreto de cartas." << endl;
  38. cout << "Introduce 2 para Modo B: cada jugador podra robar el numero de cartas que desee y plantarse si no quiere mas." << endl;
  39. cout << "Introducir 0 para salir del juego." << endl;
  40. cout << endl;
  41. cout << "Introduce el modo al que quieres jugar: 1, 2 o 0: ";
  42. cin >> modo;
  43.  
  44.  
  45. switch (modo)
  46. {
  47. case 1: cout << "Ha elegido el modo A" << endl; break;
  48. case 2: cout << "Ha elegido el modo B" << endl; break;
  49. case 0: exit = true;
  50. default: cout << "No ha seleccionado ningun modo." << endl;
  51. }
  52.  
  53.  
  54. } while (modo < 0 || modo > 2);
  55.  
  56.  
  57. system("PAUSE");
  58.  
  59.  
  60. return(modo);
  61.  
  62. }
  63.  
  64.  
  65. void lectura(int modo){
  66.  
  67. ifstream archivo;
  68. string text,texto;
  69. cout<<"Introduce el nombre o ubicacion del archivo: "<<endl;
  70.  
  71. archivo.open(text.c_str(),ios::in); //Abrimos el archivo en modo lectura
  72.  
  73. if(archivo.fail()){
  74. cout<<"No se pudo abrir el archivo";
  75. exit(1);
  76. }
  77.  
  78. while(!archivo.eof()){ //mientras no sea final del archivo
  79. getline(archivo,texto);
  80. cout<<texto<<endl;
  81. }
  82.  
  83. archivo.close(); //Cerramos el archivo
  84.  
  85. }
  86.  
  87. double modoA(ifstream & archivo, int numCartas)
  88. {
  89.  
  90.  
  91.  
  92.  
  93.  
  94.  
  95.  
  96.  
  97. }



PD: creo que la funcion void lectura() no deberia ser tipo void, pero no estoy seguro...


Título: Re: Ayuda con programa
Publicado por: K-YreX en 3 Diciembre 2018, 23:14 pm
Lo siento pero sigo sin entender el funcionamiento del programa del todo. Como ya te comenté creo:
- Usar una variable <bool exit> que es <false> y si la opción es 0 se pone a <true> no tiene mucho sentido ya que esa variable no tiene ningún propósito.
- Y sustituye los <system("pause")> por <cin.get()>. Vas a conseguir lo mismo, una pausa hasta que teclees algo pero sin tener que hacer una llamada al sistema.
- Tienes que incluir el archivo de cabecera <iostream> ya que sino no puedes usar <cin> ni <cout>.

Ahora vamos a profundizar en el código:
- La función <menu()> la entiendo. Muestras un menú, el usuario elige una opción y esa se devuelve al programa principal. Hasta ahí todo bien. No sé que uso le vas a dar pero dentro de cada <case> puedes poner todo lo que hay que hacer en caso de elegir esa opción. Pero personalmente si la función se llama menú prefiero que sólo muestre el menú y no haga más todo lo demás se haga en el <main> o en otra función creada específicamente para esa tarea.
Lo que no sé es lo que vas a hacer en la función <lectura()> entonces no sé cómo ayudarte... :-X
Supongo que la función <lectura()> llama internamente a <modoA()> usando el fichero que ha abierto. Pero qué más hace? O qué hace la función <modoA()> porque sino sería hacer otro <switch> en la función <lectura()> y según el <modo> que le pases como parámetro llame a la función <modoA()> o <modoB()> (si existe) o lo que tenga que hacer.

Tampoco sé si te mandan usar unas funciones obligatorias o lo estás estructurando cómo tú quieres porque tal y como lo estás haciendo como la opción va de un lado para otro, tienes que estar comparándola un montón de veces para ver que hacer. Si puedes dime que funciones tienes o quieres usar y que tienes en la cabeza que haga cada una (si puedes especificar parámetros o valores de retorno mejor).


Título: Re: Ayuda con programa
Publicado por: HectorSersi en 3 Diciembre 2018, 23:39 pm
Lo siento pero sigo sin entender el funcionamiento del programa del todo. Como ya te comenté creo:
- Usar una variable <bool exit> que es <false> y si la opción es 0 se pone a <true> no tiene mucho sentido ya que esa variable no tiene ningún propósito.
- Y sustituye los <system("pause")> por <cin.get()>. Vas a conseguir lo mismo, una pausa hasta que teclees algo pero sin tener que hacer una llamada al sistema.
- Tienes que incluir el archivo de cabecera <iostream> ya que sino no puedes usar <cin> ni <cout>.

Ahora vamos a profundizar en el código:
- La función <menu()> la entiendo. Muestras un menú, el usuario elige una opción y esa se devuelve al programa principal. Hasta ahí todo bien. No sé que uso le vas a dar pero dentro de cada <case> puedes poner todo lo que hay que hacer en caso de elegir esa opción. Pero personalmente si la función se llama menú prefiero que sólo muestre el menú y no haga más todo lo demás se haga en el <main> o en otra función creada específicamente para esa tarea.
Lo que no sé es lo que vas a hacer en la función <lectura()> entonces no sé cómo ayudarte... :-X
Supongo que la función <lectura()> llama internamente a <modoA()> usando el fichero que ha abierto. Pero qué más hace? O qué hace la función <modoA()> porque sino sería hacer otro <switch> en la función <lectura()> y según el <modo> que le pases como parámetro llame a la función <modoA()> o <modoB()> (si existe) o lo que tenga que hacer.

Tampoco sé si te mandan usar unas funciones obligatorias o lo estás estructurando cómo tú quieres porque tal y como lo estás haciendo como la opción va de un lado para otro, tienes que estar comparándola un montón de veces para ver que hacer. Si puedes dime que funciones tienes o quieres usar y que tienes en la cabeza que haga cada una (si puedes especificar parámetros o valores de retorno mejor).


Gracias, el iostream si lo he utilizado lo que pasa es que me lo he comido al enseñarte el codigo.
Lo del bool tendria que cambiarlo a true? o borrarlo, ya que si lo borro no me compila. Lo del cin.get() ya lo he cambiado.

Te explico lo que tengo que hacer y que me piden que use. Me ayudarias muchísimo por lo menos con el modoA. Gracias.

Hay que ir desarrollando de manera incremental un programa que permita jugar a distintas variantes, cada vez más perfeccionadas, de Las siete y media. En todas las variantes intervendrán dos jugadores en cada partida: el jugador humano y la máquina, en este orden.
En el juego se usa un mazo con las 40 cartas de la baraja española dispuestas de forma aleatoria. En una baraja española las 40 cartas están divididas en cuatro grupos (oros, copas, espadas, bastos) de diez cartas cada uno. Las cartas que tienen asociado un número entre uno y siete se llaman como el número que tienen y las cartas que tienen asociado un diez, un once o un doce se llaman sota, caballo y rey, respectivamente. En nuestro juego cada carta tiene un valor dependiendo del número que tiene asociado, de forma que si el número asociado está entre el uno y el siete, el valor de esa carta es dicho número; y si el número de la carta es diez, once o doce (sota, caballo o rey) el valor de esa carta es 0,5 puntos.
El objetivo del juego es que, en cada partida, cada uno de los jugadores, a base de robar cartas de forma consecutiva del mazo, consiga acercarse lo más posible a siete y media, sin pasarse. La puntuación obtenida por el jugador en una partida es la suma de los valores de sus cartas. Si con las cartas robadas del mazo un jugador supera los 7,5 puntos, perderá automáticamente la partida y ganará su oponente. Si ninguno de los dos jugadores se pasa (ninguno supera los 7,5 puntos), ganará el que más se acerque a los 7,5 puntos. Si obtienen el mismo número de puntos, se elegirá aleatoriamente quién es el ganador.
1.   Versión 1
Descripción de la funcionalidad
En esta primera versión del juego el mazo con las 40 cartas estará en un fichero de texto y se ofrecerá un menú en el que el jugador humano decidirá si juegan la partida en el modo A, en el modo B o si finaliza el programa. El programa actuará de forma cíclica, permitiendo jugar hasta que se elija finalizar el programa. Si se elige jugar una partida, ya sea en el modo A o en el modo B, el jugador humano introducirá el nombre del archivo donde está el mazo de cartas y a continuación se procederá a jugar la partida, volviendo a aparecer el menú cuando la partida haya acabado.
En el modo A cada jugador estará obligado, cuando le llegue el turno, a robar un número concreto de cartas . Ese número de cartas, que será el mismo para los dos jugadores, se generará aleatoriamente al comenzar la partida y estará en el rango [3, 5].
En el modo B, antes de comenzar la partida se generará aleatoriamente el número máximo de cartas, max_cartas, en el intervalo [3, 5], que cualquiera de los dos jugadores podrá coger, pero los jugadores no estarán obligados a coger max_cartas cartas sino que se pueden plantar antes si temen que van a pasarse. Así, el primer jugador (humano) robará una primera carta del mazo de cartas y seguirá robando cartas del mazo hasta que decida plantarse (es decir, podrá parar de coger cartas si considera que su puntuación es suficientemente buena), hasta que haya cogido max_cartas cartas o hasta que se haya pasado. Cuando llegue el turno de la máquina ésta hará lo mismo, pero como se tratará de una máquina muy simple (¡y a la que le gusta asumir riesgos!) como regla de decisión para plantarse usará una que compruebe si su puntuación supera la del humano o ha conseguido 7,5 puntos.
En ambos modos, cada vez que un jugador roba una carta, se mostrarán por pantalla tanto la carta robada como la puntuación del jugador debidamente actualizada. Si el jugador humano se pasa, automáticamente finalizará la partida; lo mismo ocurrirá si se pasa la máquina.
Detalles de implementación
Formato de los archivos de entrada (archivos de cartas)
Los archivos que contienen los mazos con las 40 cartas son archivos de texto con 40 números, representando cada uno de ellos una carta de la baraja. Puesto que se trata de números no hay información acerca del palo.

---Generación de números aleatorios
Para generar números aleatorios debes utilizar las funciones rand() y srand(semilla) de la biblioteca cstdlib. Una secuencia de números aleatorios comienza en un primer número entero que se denomina semilla. Para establecer la semilla el programa deberá invocar a la función srand con el argumento deseado. Lo que hace que la secuencia se comporte de forma aleatoria es precisamente la semilla. Una semilla habitual es el valor de la hora del sistema que se obtiene con una invocación a time(null_ptr), de la biblioteca ctime, ya que así es siempre distinta para cada ejecución. Así pues, el programa deberá invocar una vez a srand(time(null_ptr)). Una vez establecida la semilla, la función rand() genera, de forma pseudoaleatoria, otro entero positivo a partir del anterior. Si quieres que los números aleatorios generados estén en un determinado intervalo, deberás utilizar el operador %. Así para obtener un entero aleatorio en el intervalo [limiteInferior, limiteSuperior) hay que usar la expresión limiteInferior + rand() % (limiteSuperior - limiteInferior).
Constantes y funciones
Define dos constantes (HUMANO = 1, MAQUINA = 2) para los jugadores e implementa, al menos, los siguientes subprogramas:
•   double modoA(ifstream & file, int numCartas)   Permite a cualquiera de los dos jugadores realizar su turno en el modo de juego A. Recibe el archivo con el mazo y el número de cartas que hay que robar, y devuelve los puntos obtenidos tras robar ese número de cartas, obtener 7,5 o pasarse.
•   double modoBhumano(ifstream & file, int numCartas)  Permite realizar el turno del jugador humano en el modo B. Recibe el archivo con el mazo y el número máximo de cartas que puede robar, y devuelve los puntos obtenidos tras robar ese número de cartas, obtener 7,5, pasarse o plantarse.
•   double modoBmaquina(ifstream & file, int numCartas, double puntosHumano)   Permite realizar el turno del jugador máquina en el modo B. Recibe el archivo con el mazo, el número máximo de cartas que puede robar y la puntuación obtenida por el jugador humano, y devuelve los puntos obtenidos tras robar ese número de cartas, obtener 7,5, pasarse o plantarse.
•   int determinaGanador(double puntosJugador, double puntosMaquina)  Recibe los puntos obtenidos por el jugador humano y por la máquina, y devuelve un valor que indica quién gana (utiliza las constantes HUMANO, MAQUINA).
•    int generarMaxCartas(…),…


Título: Re: Ayuda con programa
Publicado por: K-YreX en 4 Diciembre 2018, 01:17 am
No tenía pensado ponerme a implementar este programa pero al final para dejártelo de ayuda he acabado haciendo toda la función principal. Bueno la función principal a mi manera, lo he hecho de forma que se entienda bien todo lo que se va haciendo para que puedas ir viendo lo que se hace en cada momento.

Código
  1. int main(){
  2. double puntuacionHumano, puntuacionMaquina;
  3. int modo, numCartas;
  4. ifstream fichero;
  5. do{
  6. modo = menu();
  7. srand(time(NULL));
  8.  
  9. if(modo != 0){
  10. numCartas = MINIMO + rand() % (MAXIMO - MINIMO + 1); // esto genera un numero en el intervalo cerrado [MINIMO, MAXIMO]
  11. // esto tienes que hacerlo con la funcion generarMaxCartas() pero te lo dejo asi para que veas como se usa rand
  12. fichero = abrirFichero();
  13. }
  14.  
  15. switch(modo){
  16. case 1:
  17. cout << "\nEmpieza el juego (modo A: numCartas = " << numCartas << "):" << endl;
  18. puntuacionHumano = modoA(fichero, numCartas);
  19. puntuacionMaquina = modoA(fichero, numCartas);
  20. determinaGanador(puntuacionHumano, puntuacionMaquina);
  21. break;
  22. case 2:
  23. cout << "\nEmpieza el juego (modo B: numCartas = " << numCartas << "):" << endl;
  24. puntuacionHumano = modoBHumano(fichero, numCartas);
  25. puntuacionMaquina = modoBMaquina(fichero, numCartas, puntuacionHumano);
  26. determinaGanador(puntuacionHumano, puntuacionMaquina);
  27. break;
  28. default:
  29. cout << "Saliendo del juego..." << endl;
  30. }
  31. } while(modo != 0);
  32. }

Te comento:
- La función <menu()> tiene un filtro <do while> para mostrar las opciones y elegir una opcion {0,1,2}. Y en cuanto tenga una opción válida la devuelve, es decir que quitamos el <switch> que teníamos en esa función.
- La función <generarMaxCartas()> simplemente crea un número aleatorio y lo devuelve. Yo te recomendaría pasarle dos parámetros con el mínimo y el máximo.
- La función <determinaGanador()> compara ambas puntuaciones para ver cual es mayor y muestra por pantalla quien ha ganado. No tiene ningún misterio.

Nos quedan las funciones más complejas que son las que manejan archivos. Yo te recomiendo que por ahora mires el código que he hecho, me comentes si tienes alguna duda al respecto, hagas las pruebas que quieras (tú decides lo que quieres mostrar por pantalla y esas cosas) y te asegures de poder ejecutar las funciones anteriores sin errores antes de empezar con las complicadas.
Haz programas de prueba pequeños donde puedas ver que las funciones simples funcionan correctamente.

Cuando tengas estas funciones entendidas tanto en valores de retorno como en parámetros te ayudo con las otras funciones que quedan para que veas como manejar archivos. Aunque tener un archivo con las cartas y coger de ahí los valores es un tanto complejo ya que tienes que hacerlo de manera aleatoria. Y no sé si tendrás que tener en cuenta que si el máximo de cartas a coger es 5, no se pueden coger 5 cartas iguales, ya que no existen en la baraja. Ya me dirás.


Título: Re: Ayuda con programa
Publicado por: HectorSersi en 4 Diciembre 2018, 21:15 pm
No tenía pensado ponerme a implementar este programa pero al final para dejártelo de ayuda he acabado haciendo toda la función principal. Bueno la función principal a mi manera, lo he hecho de forma que se entienda bien todo lo que se va haciendo para que puedas ir viendo lo que se hace en cada momento.

Código
  1. int main(){
  2. double puntuacionHumano, puntuacionMaquina;
  3. int modo, numCartas;
  4. ifstream fichero;
  5. do{
  6. modo = menu();
  7. srand(time(NULL));
  8.  
  9. if(modo != 0){
  10. numCartas = MINIMO + rand() % (MAXIMO - MINIMO + 1); // esto genera un numero en el intervalo cerrado [MINIMO, MAXIMO]
  11. // esto tienes que hacerlo con la funcion generarMaxCartas() pero te lo dejo asi para que veas como se usa rand
  12. fichero = abrirFichero();
  13. }
  14.  
  15. switch(modo){
  16. case 1:
  17. cout << "\nEmpieza el juego (modo A: numCartas = " << numCartas << "):" << endl;
  18. puntuacionHumano = modoA(fichero, numCartas);
  19. puntuacionMaquina = modoA(fichero, numCartas);
  20. determinaGanador(puntuacionHumano, puntuacionMaquina);
  21. break;
  22. case 2:
  23. cout << "\nEmpieza el juego (modo B: numCartas = " << numCartas << "):" << endl;
  24. puntuacionHumano = modoBHumano(fichero, numCartas);
  25. puntuacionMaquina = modoBMaquina(fichero, numCartas, puntuacionHumano);
  26. determinaGanador(puntuacionHumano, puntuacionMaquina);
  27. break;
  28. default:
  29. cout << "Saliendo del juego..." << endl;
  30. }
  31. } while(modo != 0);
  32. }

Te comento:
- La función <menu()> tiene un filtro <do while> para mostrar las opciones y elegir una opcion {0,1,2}. Y en cuanto tenga una opción válida la devuelve, es decir que quitamos el <switch> que teníamos en esa función.
- La función <generarMaxCartas()> simplemente crea un número aleatorio y lo devuelve. Yo te recomendaría pasarle dos parámetros con el mínimo y el máximo.
- La función <determinaGanador()> compara ambas puntuaciones para ver cual es mayor y muestra por pantalla quien ha ganado. No tiene ningún misterio.

Nos quedan las funciones más complejas que son las que manejan archivos. Yo te recomiendo que por ahora mires el código que he hecho, me comentes si tienes alguna duda al respecto, hagas las pruebas que quieras (tú decides lo que quieres mostrar por pantalla y esas cosas) y te asegures de poder ejecutar las funciones anteriores sin errores antes de empezar con las complicadas.
Haz programas de prueba pequeños donde puedas ver que las funciones simples funcionan correctamente.

Cuando tengas estas funciones entendidas tanto en valores de retorno como en parámetros te ayudo con las otras funciones que quedan para que veas como manejar archivos. Aunque tener un archivo con las cartas y coger de ahí los valores es un tanto complejo ya que tienes que hacerlo de manera aleatoria. Y no sé si tendrás que tener en cuenta que si el máximo de cartas a coger es 5, no se pueden coger 5 cartas iguales, ya que no existen en la baraja. Ya me dirás.


Buenas, lo primero gracias por ayudarme :D. He estado con un amigo haciendolo y he avanzado bastante.Hemos hecho el modo A y el modo B, me compila bien y tal pero a la hora de abrir el archivo no me lo abre cuando me pregunta el nombre del archivo, yo escribo "baraja"(no se si deberia ser "baraja.txt") y no me lo abre( no se si deberia ser el nombre del archivo "mazo"). El txt lo guardo donde el .cpp no?

Te envio el codigo y me dices cual puede ser el error?

Código
  1. #include<iostream>
  2. #include<cstdlib>
  3. #include<ctime>
  4. #include<fstream>
  5. #include<string>
  6.  
  7. using namespace std;
  8.  
  9. const int HUMANO = 1;
  10. const int MAQUINA = 2;
  11.  
  12. int menu();
  13. double modoA(ifstream & archivo, int numeroAleatorio); //archivo lo puedes llamar como quieras aqui, pero luego al invocar tienes qe poner "archivo"
  14. int determinaGanador(double puntosHumano, double puntosMaquina);
  15. double modoBmaquina(ifstream & archivo, int numeroAleatorio, double puntosHumano);
  16. double modoBhumano(ifstream & archivo, int numeroAleatorio);
  17.  
  18. int main()
  19. {
  20. int numeroAleatorio, modo;
  21. ifstream archivo;
  22. double puntosHumano, puntosMaquina;
  23.  
  24.  
  25. srand(time(NULL));
  26. numeroAleatorio = 3 + rand() % (5 - 3);
  27.  
  28. modo = menu();
  29.  
  30. if (modo == 1)
  31. {
  32. string baraja;
  33. cout << "Introduce el nombre del archivo que quieras abrir: " << endl;
  34. cin >> baraja;
  35.  
  36. archivo.open(baraja); //archivo es lo declarado en ifstream
  37.  
  38. while (!archivo.is_open())
  39. {
  40. cout << "El archivo es incorrecto" << endl;
  41. cin >> baraja;
  42. archivo.open(baraja);
  43. }
  44. puntosHumano = modoA(archivo, numeroAleatorio);
  45. puntosMaquina = modoA(archivo, numeroAleatorio);
  46.  
  47. if (determinaGanador(puntosHumano, puntosMaquina) == HUMANO) {
  48. cout << "&#65311;as ganado!" << endl;
  49. }
  50. else
  51. {
  52. cout << "Ha ganado la maquina" << endl;
  53. }
  54.  
  55. }
  56. else if (modo == 2)
  57. {
  58. string baraja;
  59. cout << "Introduce el nombre del archivo que quieras abrir: " << endl;
  60. cin >> baraja;
  61.  
  62. archivo.open(baraja); //archivo es lo declarado en ifstream
  63.  
  64. while (!archivo.is_open())
  65. {
  66. cout << "El archivo es incorrecto" << endl;
  67. cin >> baraja;
  68. archivo.open(baraja);
  69. }
  70. puntosHumano = modoBhumano(archivo, numeroAleatorio);
  71. puntosMaquina = modoBmaquina(archivo, numeroAleatorio,puntosHumano);
  72. if (determinaGanador(puntosHumano, puntosMaquina) == HUMANO)
  73. {
  74. cout << "Ha ganado el HUMANO" << endl;
  75. }
  76. else
  77. {
  78. cout<<"El ganador es la maquina"<<endl;
  79. }
  80. }
  81. else if (modo == 3)
  82. {
  83.  
  84. }
  85. else if (modo == 4)
  86. {
  87.  
  88. }
  89.  
  90.  
  91.  
  92.  
  93. return 0;
  94. }
  95.  
  96. int menu()
  97. {
  98. int modo;
  99. cout << "Elige el modo al que quieras jugar: " << endl;
  100. cout << "Introduce 1 para Modo A: cada jugador estara obligado, cuando le llegue el turno, a robar un numero concreto de cartas." << endl;
  101. cout << "Introduce 2 para Modo B: cada jugador podra robar el numero de cartas que desee y plantarse si no quiere mas." << endl;
  102. cout << "Modo C " << endl;
  103. cout << "Modo D " << endl;
  104. cout << "Introducir 0 para salir del juego." << endl;
  105. cin >> modo;
  106.  
  107. while (modo < 0 || modo > 4) {
  108. cout << "No ha seleccionado ningun modo, vuelva a seleccionar el modo: ";
  109. cin >> modo;
  110.  
  111. }
  112.  
  113.  
  114. return modo;
  115. }
  116.  
  117. double modoA(ifstream & archivo, int numeroAleatorio)
  118. {
  119. int final = 0, aux;
  120. double puntos = 0;
  121.  
  122. while (final < numeroAleatorio && puntos < 7.5)
  123. {
  124. archivo >> aux;
  125. if (aux > 7) {
  126. puntos = puntos + 0.5;
  127. }
  128. else
  129. {
  130. puntos = puntos + aux;
  131. }
  132.  
  133.  
  134.  
  135. }
  136.  
  137. return puntos;
  138. }
  139.  
  140. double modoBhumano(ifstream & archivo, int numeroAleatorio)
  141. {
  142. int final = 0, aux, responder;
  143. double puntos = 0;
  144. bool continuar = true;
  145.  
  146. while (final < numeroAleatorio && puntos < 7.5 && continuar)
  147. {
  148. archivo >> aux;
  149. if (aux > 7) {
  150. puntos = puntos + 0.5;
  151. }
  152. else
  153. {
  154. puntos = puntos + aux;
  155. }
  156. cout << "Tu puntuacion es; " << puntos << endl;
  157. cout << "1 para seguir y 2 para parar " << endl;
  158. cout << "Quieres continuar? " << endl;
  159. cin >> responder;
  160.  
  161. while (responder < 1 || responder > 2) {
  162. cout << "No ha seleccionado ningun modo, vuelva a seleccionar el modo: ";
  163. cin >> responder;
  164. }
  165.  
  166. if (responder == 1) {
  167. continuar = true;
  168. }
  169. else {
  170. continuar = false;
  171. }
  172. }
  173.  
  174. return puntos;
  175. }
  176.  
  177. double modoBmaquina(ifstream & archivo, int numeroAleatorio, double puntosHumano)
  178. {
  179. int final = 0, aux;
  180. double puntos = 0;
  181. bool continuar = true;
  182.  
  183. while (final < numeroAleatorio && puntos < 7.5 && continuar)
  184. {
  185. archivo >> aux;
  186. if (aux > 7) {
  187. puntos = puntos + 0.5;
  188. }
  189. else
  190. {
  191. puntos = puntos + aux;
  192. }
  193.  
  194. if (puntosHumano > puntos)
  195. {
  196. continuar = true;
  197. }
  198.  
  199. else {
  200. continuar = false;
  201. }
  202. }
  203.  
  204. return puntos;
  205. }
  206.  
  207.  
  208. int determinaGanador(double puntosHumano, double puntosMaquina)
  209. {
  210. int ganador;
  211. if (puntosHumano > puntosMaquina)
  212. {
  213. ganador = HUMANO;
  214. }
  215. else if (puntosHumano < puntosMaquina)
  216. {
  217. ganador = MAQUINA;
  218. }
  219. else
  220. {
  221. ganador = HUMANO + rand() % +(MAQUINA - HUMANO);
  222. }
  223.  
  224.  
  225. return ganador;
  226. }


Título: Re: Ayuda con programa
Publicado por: K-YreX en 4 Diciembre 2018, 21:28 pm
El nombre del archivo tiene que ir con la ruta en donde esté. Quiero decir si tu archivo se llama "baraja.txt" y está en el mismo directorio donde estás ejecutando el programa entonces su nombre es "baraja.txt".
En cambio si está en otro sitio tienes que especificar la ruta, por ejemplo si estás compilando en GNU/Linux y tienes el ejecutable y al mismo nivel una carpeta "docs/" donde está el fichero "baraja.txt" entonces el nombre del archivo sería "./docs/baraja.txt".

Edit: Prueba a hacer un programa que sólo abra un fichero y muestre su contenido así puedes ver donde está el error más fácil.


Título: Re: Ayuda con programa
Publicado por: HectorSersi en 6 Diciembre 2018, 15:08 pm
El nombre del archivo tiene que ir con la ruta en donde esté. Quiero decir si tu archivo se llama "baraja.txt" y está en el mismo directorio donde estás ejecutando el programa entonces su nombre es "baraja.txt".
En cambio si está en otro sitio tienes que especificar la ruta, por ejemplo si estás compilando en GNU/Linux y tienes el ejecutable y al mismo nivel una carpeta "docs/" donde está el fichero "baraja.txt" entonces el nombre del archivo sería "./docs/baraja.txt".

Edit: Prueba a hacer un programa que sólo abra un fichero y muestre su contenido así puedes ver donde está el error más fácil.




Título: Re: Ayuda con programa
Publicado por: K-YreX en 6 Diciembre 2018, 15:13 pm
Tu código para generar números aleatorios genera números entre [3,5). Fíjate que el límite superior tiene el intervalo abierto, por lo que los posibles resultados son {3,4}.
Para generar números entre [3,5] el código es: <3 + rand() % 5-3+1>. Si entiendes lo que hace el operador módulo <%> está claro, este te devuelve el resto de dividir <rand()> entre 2 en tu caso. Ese resto siempre va a ser {0,1}. Entonces 3+{0,1}={3,4}. En cambio si haces módulo 3, te queda 3 + {0,1,2} = {3,4,5}. Suerte.

Edit: Además la carta que robas no es <numeroAleatorio>, <numeroAleatorio> es el número de cartas que robas.


Título: Re: Ayuda con programa
Publicado por: HectorSersi en 6 Diciembre 2018, 15:43 pm
Tu código para generar números aleatorios genera números entre [3,5). Fíjate que el límite superior tiene el intervalo abierto, por lo que los posibles resultados son {3,4}.
Para generar números entre [3,5] el código es: <3 + rand() % 5-3+1>. Si entiendes lo que hace el operador módulo <%> está claro, este te devuelve el resto de dividir <rand()> entre 2 en tu caso. Ese resto siempre va a ser {0,1}. Entonces 3+{0,1}={3,4}. En cambio si haces módulo 3, te queda 3 + {0,1,2} = {3,4,5}. Suerte.

Edit: Además la carta que robas no es <numeroAleatorio>, <numeroAleatorio> es el número de cartas que robas.


Vale gracias, entonces por que siempre me roba 4 cartas, si se supone que deberia ser entre [3,5] , es decir aleatoriamente, unas veces 3, otras 4...no?

Otra pregunta es como hago que me muestre la carta que he sacado?

Gracias.


Título: Re: Ayuda con programa
Publicado por: K-YreX en 6 Diciembre 2018, 16:10 pm
Según tu código la carta que robas la guardas en <aux> en cada una de las funciones <modoA()> y <modoB()>. Entonces para ver la carta sólo tendrías que hacer un <cout> de <aux>.

Un par de consejos:
- Si no recuerdo mal lo de generar el número aleatorio tenías que hacerlo con una función, no en el <main>.
- En vez de usar <if> anidados para cada opción del menú, es mejor usar el <switch>.
- En el <modoBHumano()> si la variable <continuar> le asignas <true> al empezar, luego no le asignes <true> otra vez cada vez que el usuario quiere otra carta. Sólo asígnale <false> cuando no quiera más cartas, hasta entonces ya vale <true>.
- La variable <continuar> de <modoBMaquina()> más de lo mismo.
- En la función <determinaGanador()> en caso de empate siempre gana el humano por lo que te he comentado antes de los números aleatorios. Estás haciendo <rand() % 1> y eso siempre es 0, por lo que HUMANO + 0 = HUMANO.

Aparte de esas cosillas, como el archivo se lee en orden, siempre van a salir los <numeroAleatorio>-primeros números del archivo.


Título: Re: Ayuda con programa
Publicado por: HectorSersi en 7 Diciembre 2018, 13:05 pm
Según tu código la carta que robas la guardas en <aux> en cada una de las funciones <modoA()> y <modoB()>. Entonces para ver la carta sólo tendrías que hacer un <cout> de <aux>.

Un par de consejos:
- Si no recuerdo mal lo de generar el número aleatorio tenías que hacerlo con una función, no en el <main>.
- En vez de usar <if> anidados para cada opción del menú, es mejor usar el <switch>.
- En el <modoBHumano()> si la variable <continuar> le asignas <true> al empezar, luego no le asignes <true> otra vez cada vez que el usuario quiere otra carta. Sólo asígnale <false> cuando no quiera más cartas, hasta entonces ya vale <true>.
- La variable <continuar> de <modoBMaquina()> más de lo mismo.
- En la función <determinaGanador()> en caso de empate siempre gana el humano por lo que te he comentado antes de los números aleatorios. Estás haciendo <rand() % 1> y eso siempre es 0, por lo que HUMANO + 0 = HUMANO.

Aparte de esas cosillas, como el archivo se lee en orden, siempre van a salir los <numeroAleatorio>-primeros números del archivo.

Si esas cosillas las estuve corriegiendo gracias, pero como puedo hacer para que los numeros del archivo de texto se lean de forma aleatoria?


Título: Re: Ayuda con programa
Publicado por: K-YreX en 7 Diciembre 2018, 13:32 pm
Para eso tienes varias alternativas:
- Una sería usar ficheros de acceso aleatorio mediante funciones como <seekp()> y <seekg()>. Puedes buscar más información buscando "ficheros de acceso aleatorio c++" o buscando directamente las funciones que te he comentado y ver cómo funcionan.

Si no tienes ni idea de trabajar con ficheros de acceso aleatorio, yo te recomendaría usar la segunda opción que consistiría en aplicar lo que ya sabes para conseguir una lectura aleatoria:
- Yo generaría un número aleatorio pequeño para no irme al final del fichero y saltaría esos números. Así no coges siempre los n-primeros.
Código
  1. int cartasASaltar = generarAleatorio(0,5);
  2. int cartasSaltadas = 0;
  3. int carta;
  4. while(!fichero.eof() && cartasSaltadas <= cartasASaltar){
  5.    fichero >> carta;
  6.    cartasSaltadas++;
  7. }
  8. cout << "Tu carta es: " << carta << endl;

Ahí tienes un trozo de prueba para que veas a lo que me refiero. Con la función que te comenté hace un tiempo para generar números aleatorios le pasas el mínimo y el máximo (como coges como mucho 5 cartas, saltando un máximo de 5 cartas en cada vuelta es seguro que no te sales del fichero, podrías saltarte más eso ya te dejo que lo calcules tú si quieres) Para hacerlo más aleatorio puedes generar un número aleatorio distinto en cada vuelta para que no siga el mismo patrón. Suerte. :-X

Mientras escribía esto me he dado cuenta de que también puedes empezar con un fichero vacío y el propio programa genere el fichero (simulando que se está barajando). Creas números aleatorios entre [1,10] y los escribes en el archivo. Así la baraja no empezaría ordenada. En este caso tendrías que controlar que no se repitan más de 4 veces cada valor ya que en la baraja cada valor numérico se repite hasta 4 veces. Mi recomendación si lo haces así que la verdad me parece bastante interesante es que hagas un array y cada vez que generes un número, compruebes que no has generado ya 4 veces ese número y  le sumes 1 al (i-1)-elemento. Me explico por si no se entiende:
- Tienes un array <maximos[10] = {0,0,0,0,0,0,0,0,0,0}> que indica cuantas veces has generado cada valor.
- Generas x valor (imagina un 1).
- Compruebas que (maximos[x-1] < 4) Si no es menor que 4 generas otro número distinto.
- Si es menor que 4, lo agregas al fichero y haces <maximos[x-1] += 1>, es decir le sumas 1 en la posición correspondiente.

Suerte y espero que te animes a intentar el último método que te he comentado. O incluso puedes mezclarlos, eso ya depende de la imaginación del programador. Personalmente creo que es mejor que resuelvas un problema con las herramientas que conoces hasta que estudies otras y no que uses herramientas que no sabes como funcionan para salir del paso. La decisión final es tuya. Suerte. :-X :-X


Título: Re: Ayuda con programa
Publicado por: HectorSersi en 8 Diciembre 2018, 14:03 pm
Para eso tienes varias alternativas:
- Una sería usar ficheros de acceso aleatorio mediante funciones como <seekp()> y <seekg()>. Puedes buscar más información buscando "ficheros de acceso aleatorio c++" o buscando directamente las funciones que te he comentado y ver cómo funcionan.

Si no tienes ni idea de trabajar con ficheros de acceso aleatorio, yo te recomendaría usar la segunda opción que consistiría en aplicar lo que ya sabes para conseguir una lectura aleatoria:
- Yo generaría un número aleatorio pequeño para no irme al final del fichero y saltaría esos números. Así no coges siempre los n-primeros.
Código
  1. int cartasASaltar = generarAleatorio(0,5);
  2. int cartasSaltadas = 0;
  3. int carta;
  4. while(!fichero.eof() && cartasSaltadas <= cartasASaltar){
  5.    fichero >> carta;
  6.    cartasSaltadas++;
  7. }
  8. cout << "Tu carta es: " << carta << endl;

Ahí tienes un trozo de prueba para que veas a lo que me refiero. Con la función que te comenté hace un tiempo para generar números aleatorios le pasas el mínimo y el máximo (como coges como mucho 5 cartas, saltando un máximo de 5 cartas en cada vuelta es seguro que no te sales del fichero, podrías saltarte más eso ya te dejo que lo calcules tú si quieres) Para hacerlo más aleatorio puedes generar un número aleatorio distinto en cada vuelta para que no siga el mismo patrón. Suerte. :-X

Mientras escribía esto me he dado cuenta de que también puedes empezar con un fichero vacío y el propio programa genere el fichero (simulando que se está barajando). Creas números aleatorios entre [1,10] y los escribes en el archivo. Así la baraja no empezaría ordenada. En este caso tendrías que controlar que no se repitan más de 4 veces cada valor ya que en la baraja cada valor numérico se repite hasta 4 veces. Mi recomendación si lo haces así que la verdad me parece bastante interesante es que hagas un array y cada vez que generes un número, compruebes que no has generado ya 4 veces ese número y  le sumes 1 al (i-1)-elemento. Me explico por si no se entiende:
- Tienes un array <maximos[10] = {0,0,0,0,0,0,0,0,0,0}> que indica cuantas veces has generado cada valor.
- Generas x valor (imagina un 1).
- Compruebas que (maximos[x-1] < 4) Si no es menor que 4 generas otro número distinto.
- Si es menor que 4, lo agregas al fichero y haces <maximos[x-1] += 1>, es decir le sumas 1 en la posición correspondiente.

Suerte y espero que te animes a intentar el último método que te he comentado. O incluso puedes mezclarlos, eso ya depende de la imaginación del programador. Personalmente creo que es mejor que resuelvas un problema con las herramientas que conoces hasta que estudies otras y no que uses herramientas que no sabes como funcionan para salir del paso. La decisión final es tuya. Suerte. :-X :-X


Okey gracias, por ultimo, me gustaría hacer que al pasarse de 7.5 tanto la maquina como el humano, pierdan la partida automáticamente con un cout<<"Has perdido la partida", para ello habia creado esto, pero no me funciona.

Código
  1. int determinaGanador(double puntosHumano, double puntosMaquina)
  2. {
  3. int ganador;
  4.  
  5. while (puntosHumano || puntosMaquina < 7.5)
  6. {
  7. if (puntosHumano > puntosMaquina)
  8. {
  9. ganador = HUMANO;
  10. }
  11. else if (puntosHumano < puntosMaquina)
  12. {
  13. ganador = MAQUINA;
  14. }
  15.  
  16. else if (puntosHumano == puntosMaquina)
  17. {
  18. ganador = HUMANO + rand() % +(MAQUINA - HUMANO);
  19. }
  20. }
  21.  
  22. while (puntosHumano || puntosMaquina > 7.5)
  23. {
  24. if (puntosHumano > 7.5)
  25. {
  26. cout << "Has perdido ";
  27. }
  28. if (puntosMaquina > 7.5)
  29. {
  30. cout << "La maquina ha perdido ";
  31. }
  32. }
  33. return ganador;
  34. }



Título: Re: Ayuda con programa
Publicado por: K-YreX en 8 Diciembre 2018, 15:24 pm
Primero para la función que tienes no se usa un <while> sino un <if>. Es muy común traducir una sentencia como "mientras..." pero en realidad es "si...".Un <while> se usa si vas a repetir un trozo de código hasta que se cumpla una condición, por lo tanto los valores de la condición tienen que ir cambiando dentro del <while>, por ejemplo:
Código
  1. while(puntosMaquina < puntosHumano && puntosMaquina < 7.5)
  2.    puntosMaquina += carta;
Eso sería un <while>. Mientras los puntos de la máquina no superen al humano ni el 7.5 entonces le sumamos otra carta. No digo que lo tengas que hacer así ya que tienes tus propias funciones para robar cartas. Es sólo para que veas el uso del <while>.

En tu caso si es para determinar un ganador es con un <if>. Además en programación lo que se suele hacer para dar menos vueltas es asumir un caso y si la condición es la opuesta, modificar el resultado, tu caso:
Código
  1. int determinaGanador(int puntosHumano, int puntosMaquina){
  2.    int ganador = HUMANO;
  3.    if(puntosHumano > 7.5 || (puntosMaquina < 7.5 && puntosHumano < puntosMaquina))
  4.        ganador = MAQUINA;
  5.    else if(puntosHumano == puntosMaquina)
  6.        ganador += rand() % 2;
  7.    return ganador;
  8. }
Esa es tu función que una vez tiene los puntos de ambos, te dice quien es el ganador. No contempla el caso de que los dos jugadores se hayan pasado del 7.5. Eso ya te lo dejo a ti.  :rolleyes:

Si lo que quieres es interrumpir el programa en cuanto uno de los dos pasa de 7.5. Entonces la modificación la tienes que hacer al momento en que van robando cartas. He mirado un poco tu programa por encima y en cada función del modo de juego ya compruebas que no se haya pasado de 7.5, eso está bien. Lo que puedes hacer en el <main> sería algo así:
Código
  1. puntosHumano = modoA(archivo, numeroAleatorio);
  2. if(puntosHumano < 7.5)
  3.    puntosMaquina = modoA(archivo, numeroAleatorio);
  4. //...
Así si el humano se pasa de 7.5 tal y como te he hecho la función anterior ganaría la máquina sin necesidad de robar cartas. Esto tendrías que implementarlo para cada uno de los modos. Además te recomiendo no usar números mágicos, es decir, números que aparecen literalmente por ahí y no se sabe lo que son. Dale un nombre a 7.5 y sustitúyelo en el programa por ejemplo:
Código
  1. const int PUNTUACION_LIMITE = 7.5;
  2. // y en el resto del programa poner PUNTUACION_LIMITE donde ponga 7.5
Así cambiando sólo ese número puedes cambiar el límite del juego sin tener que ir cambiando todo el programa. Suerte. :-X


Título: Re: Ayuda con programa
Publicado por: CalgaryCorpus en 8 Diciembre 2018, 16:10 pm
Sugiero hacer un cambio en esta parte

Código
  1. if(puntosHumano == puntosMaquina)
  2.        ganador += rand() % 2;

pues depende mucho del valor de las constantes, y que valor tiene "ganador" antes de llegar aqui, y si una de las constantes esta separada exactamente en 1 de la otra.

Cambiando ligeramente el codigo todas estas dependencias ya no estaran.

Ejemplo:

Código
  1. if(puntosHumano == puntosMaquina) {
  2.       if( rand() % 2 ) {
  3.          ganador = MAQUINA;
  4.       }
  5. }

Con esta modificacion, no importa el valor de las constantes, o que esten separadas en 1 una de otra, podrian ser otros valores y estar separadas en mas de 1 sus valores.


Título: Re: Ayuda con programa
Publicado por: K-YreX en 8 Diciembre 2018, 18:20 pm
Es cierto, pero si no recuerdo mal, él había declarado lo siguiente:
Código
  1. const int HUMANO = 1;
  2. const int MAQUINA = 2;
Por eso lo he hecho así, sin embargo, tu idea es mejor por el tema que dices de que el valor no se diferencie en 1.


Título: Re: Ayuda con programa
Publicado por: CalgaryCorpus en 8 Diciembre 2018, 19:18 pm
Las enumeraciones parecen calzar mejor aquí


Título: Re: Ayuda con programa
Publicado por: HectorSersi en 9 Diciembre 2018, 13:56 pm
Primero para la función que tienes no se usa un <while> sino un <if>. Es muy común traducir una sentencia como "mientras..." pero en realidad es "si...".Un <while> se usa si vas a repetir un trozo de código hasta que se cumpla una condición, por lo tanto los valores de la condición tienen que ir cambiando dentro del <while>, por ejemplo:
Código
  1. while(puntosMaquina < puntosHumano && puntosMaquina < 7.5)
  2.    puntosMaquina += carta;
Eso sería un <while>. Mientras los puntos de la máquina no superen al humano ni el 7.5 entonces le sumamos otra carta. No digo que lo tengas que hacer así ya que tienes tus propias funciones para robar cartas. Es sólo para que veas el uso del <while>.

En tu caso si es para determinar un ganador es con un <if>. Además en programación lo que se suele hacer para dar menos vueltas es asumir un caso y si la condición es la opuesta, modificar el resultado, tu caso:
Código
  1. int determinaGanador(int puntosHumano, int puntosMaquina){
  2.    int ganador = HUMANO;
  3.    if(puntosHumano > 7.5 || (puntosMaquina < 7.5 && puntosHumano < puntosMaquina))
  4.        ganador = MAQUINA;
  5.    else if(puntosHumano == puntosMaquina)
  6.        ganador += rand() % 2;
  7.    return ganador;
  8. }
Esa es tu función que una vez tiene los puntos de ambos, te dice quien es el ganador. No contempla el caso de que los dos jugadores se hayan pasado del 7.5. Eso ya te lo dejo a ti.  :rolleyes:

Si lo que quieres es interrumpir el programa en cuanto uno de los dos pasa de 7.5. Entonces la modificación la tienes que hacer al momento en que van robando cartas. He mirado un poco tu programa por encima y en cada función del modo de juego ya compruebas que no se haya pasado de 7.5, eso está bien. Lo que puedes hacer en el <main> sería algo así:
Código
  1. puntosHumano = modoA(archivo, numeroAleatorio);
  2. if(puntosHumano < 7.5)
  3.    puntosMaquina = modoA(archivo, numeroAleatorio);
  4. //...
Así si el humano se pasa de 7.5 tal y como te he hecho la función anterior ganaría la máquina sin necesidad de robar cartas. Esto tendrías que implementarlo para cada uno de los modos. Además te recomiendo no usar números mágicos, es decir, números que aparecen literalmente por ahí y no se sabe lo que son. Dale un nombre a 7.5 y sustitúyelo en el programa por ejemplo:
Código
  1. const int PUNTUACION_LIMITE = 7.5;
  2. // y en el resto del programa poner PUNTUACION_LIMITE donde ponga 7.5
Así cambiando sólo ese número puedes cambiar el límite del juego sin tener que ir cambiando todo el programa. Suerte. :-X




Título: Re: Ayuda con programa
Publicado por: K-YreX en 9 Diciembre 2018, 16:11 pm
No es que la puntuación de la máquina salga al final, simplemente al ser un bucle en el que el usuario no tiene que hacer nada el programa se ejecuta muy rápido y por eso se muestra la puntuación y de seguido el ganador. Si quieres ver la puntuación en cada iteración lo que puedes hacer es meter una pausa por ejemplo con <cin.get()>. Así se va a parar en cada vuelta hasta que pulses enter.
Código
  1. double modoBmaquina(ifstream & archivo, int numeroAleatorio, double puntosHumano){
  2. int final = 0, aux;
  3. double puntos = 0;
  4.  
  5. while (final < numeroAleatorio && puntosHumano < puntos && puntos < PUNTUACION_LIMITE){
  6. archivo >> aux;
  7. if (aux > 7)
  8. puntos += 0.5;
  9. else
  10. puntos += aux;
  11. cout << "La maquina ha robado : " << aux << endl;
  12. cout << "La puntuacion de la maquina es : " << puntos << endl;
  13.                cin.get();
  14.        }
  15. return puntos;
  16. }

El tema de la <PUNTUACION_LIMITE> si lo único que has hecho ha sido declarar la variable y sustituir en cada <7.5> por <PUNTUACION_LIMITE> el programa no tiene que cambiar. Puede que sea que si usas números aleatorios para la cantidad de cartas que se roban y has aplicado alguno de los métodos que te comenté para robar cartas desordenadas haya coincidido que el humano haya tenido 7 puntos con las cartas que ha robado y la máquina se haya pasado en la última iteración a 8.
Prueba a quitar los trozos de código aleatorios para que las cartas que se cogen siempre sean las mismas y así poder controlar los resultados.

Un par de consejos más:
Código
  1. if (determinaGanador(puntosHumano, puntosMaquina) == HUMANO) {
  2. cout << "Ha ganado el HUMANO" << endl;
  3. cin.get();
  4. }
  5. else{
  6. cout<<"El ganador es la maquina"<<endl;
  7. cin.get();
  8. }
Si tienes un <if> que ejecuta una instrucción y un <else> que ejecuta la misma instrucción, esa instrucción se ejecutará siempre. Entonces se pone después del <else> y así sólo se pone una vez.
Código
  1. if (determinaGanador(puntosHumano, puntosMaquina) == HUMANO)
  2. cout << "Ha ganado el HUMANO" << endl;
  3. else
  4. cout<<"El ganador es la maquina"<<endl;
  5. cin.get();

Y esto:
Código
  1. while (responder < 1 || responder > 2)
Sería más correcto usar el operador "distinto" <!=>.
Código
  1. while(responder != 1 && responder != 2)


Título: Re: Ayuda con programa
Publicado por: CalgaryCorpus en 9 Diciembre 2018, 18:50 pm
Estas instrucciones
Código
  1.                archivo >> aux;
  2. if (aux > 7)
  3. puntos += 0.5;
  4. else
  5. puntos += aux;

Podrían ser una función, parecen repetirse varias veces en el código enviado.

Si nadie se tienta a hacerlo por ti, sugiero que crees una función que convierta lo anterior en

Código
  1.     puntos += puntosAdicionales(archivo);


Título: Re: Ayuda con programa
Publicado por: HectorSersi en 10 Diciembre 2018, 18:53 pm
Código:
[quote author=YreX-DwX link=topic=489919.msg2180460#msg2180460 date=1544368262]
No es que la puntuación de la máquina salga al final, simplemente al ser un bucle en el que el usuario no tiene que hacer nada el programa se ejecuta muy rápido y por eso se muestra la puntuación y de seguido el ganador. Si quieres ver la puntuación en cada iteración lo que puedes hacer es meter una pausa por ejemplo con <cin.get()>. Así se va a parar en cada vuelta hasta que pulses enter.
[code=cpp]
double modoBmaquina(ifstream & archivo, int numeroAleatorio, double puntosHumano){
int final = 0, aux;
double puntos = 0;
 
while (final < numeroAleatorio && puntosHumano < puntos && puntos < PUNTUACION_LIMITE){
archivo >> aux;
if (aux > 7)
puntos += 0.5;
else
puntos += aux;
cout << "La maquina ha robado : " << aux << endl;
cout << "La puntuacion de la maquina es : " << puntos << endl;
                cin.get();
        }
return puntos;
}

El tema de la <PUNTUACION_LIMITE> si lo único que has hecho ha sido declarar la variable y sustituir en cada <7.5> por <PUNTUACION_LIMITE> el programa no tiene que cambiar. Puede que sea que si usas números aleatorios para la cantidad de cartas que se roban y has aplicado alguno de los métodos que te comenté para robar cartas desordenadas haya coincidido que el humano haya tenido 7 puntos con las cartas que ha robado y la máquina se haya pasado en la última iteración a 8.
Prueba a quitar los trozos de código aleatorios para que las cartas que se cogen siempre sean las mismas y así poder controlar los resultados.

Un par de consejos más:
Código
  1. if (determinaGanador(puntosHumano, puntosMaquina) == HUMANO) {
  2. cout << "Ha ganado el HUMANO" << endl;
  3. cin.get();
  4. }
  5. else{
  6. cout<<"El ganador es la maquina"<<endl;
  7. cin.get();
  8. }
Si tienes un <if> que ejecuta una instrucción y un <else> que ejecuta la misma instrucción, esa instrucción se ejecutará siempre. Entonces se pone después del <else> y así sólo se pone una vez.
Código
  1. if (determinaGanador(puntosHumano, puntosMaquina) == HUMANO)
  2. cout << "Ha ganado el HUMANO" << endl;
  3. else
  4. cout<<"El ganador es la maquina"<<endl;
  5. cin.get();

Y esto:
Código
  1. while (responder < 1 || responder > 2)
Sería más correcto usar el operador "distinto" <!=>.
Código
  1. while(responder != 1 && responder != 2)
[/quote]


   srand(time(NULL));
   numeroAleatorio = 3 + rand() % 5 - 3 + 1;

   return numeroAleatorio;
}[/code]


Título: Re: Ayuda con programa
Publicado por: HectorSersi en 10 Diciembre 2018, 21:17 pm
No es que la puntuación de la máquina salga al final, simplemente al ser un bucle en el que el usuario no tiene que hacer nada el programa se ejecuta muy rápido y por eso se muestra la puntuación y de seguido el ganador. Si quieres ver la puntuación en cada iteración lo que puedes hacer es meter una pausa por ejemplo con <cin.get()>. Así se va a parar en cada vuelta hasta que pulses enter.
Código
  1. double modoBmaquina(ifstream & archivo, int numeroAleatorio, double puntosHumano){
  2. int final = 0, aux;
  3. double puntos = 0;
  4.  
  5. while (final < numeroAleatorio && puntosHumano < puntos && puntos < PUNTUACION_LIMITE){
  6. archivo >> aux;
  7. if (aux > 7)
  8. puntos += 0.5;
  9. else
  10. puntos += aux;
  11. cout << "La maquina ha robado : " << aux << endl;
  12. cout << "La puntuacion de la maquina es : " << puntos << endl;
  13.                cin.get();
  14.        }
  15. return puntos;
  16. }

El tema de la <PUNTUACION_LIMITE> si lo único que has hecho ha sido declarar la variable y sustituir en cada <7.5> por <PUNTUACION_LIMITE> el programa no tiene que cambiar. Puede que sea que si usas números aleatorios para la cantidad de cartas que se roban y has aplicado alguno de los métodos que te comenté para robar cartas desordenadas haya coincidido que el humano haya tenido 7 puntos con las cartas que ha robado y la máquina se haya pasado en la última iteración a 8.
Prueba a quitar los trozos de código aleatorios para que las cartas que se cogen siempre sean las mismas y así poder controlar los resultados.

Un par de consejos más:
Código
  1. if (determinaGanador(puntosHumano, puntosMaquina) == HUMANO) {
  2. cout << "Ha ganado el HUMANO" << endl;
  3. cin.get();
  4. }
  5. else{
  6. cout<<"El ganador es la maquina"<<endl;
  7. cin.get();
  8. }
Si tienes un <if> que ejecuta una instrucción y un <else> que ejecuta la misma instrucción, esa instrucción se ejecutará siempre. Entonces se pone después del <else> y así sólo se pone una vez.
Código
  1. if (determinaGanador(puntosHumano, puntosMaquina) == HUMANO)
  2. cout << "Ha ganado el HUMANO" << endl;
  3. else
  4. cout<<"El ganador es la maquina"<<endl;
  5. cin.get();

Y esto:
Código
  1. while (responder < 1 || responder > 2)
Sería más correcto usar el operador "distinto" <!=>.
Código
  1. while(responder != 1 && responder != 2)

Por lo menos dime por que me da error en tCartasPorAparecer (error de sintaxis) y en "cartas"(en las primeras lineas)

Agradeceria mucho la ayuda.


Título: Re: Ayuda con programa
Publicado por: K-YreX en 10 Diciembre 2018, 21:25 pm
Primero si no es para citar algo concreto de otro mensaje no incluyas una cita a cada respuesta porque cada mensaje se hace larguísimo. Además de eso un tema se crea para resolver una duda específica, no para hacer un programa entero. Ya sé que es mucho más cómodo abrir un tema y que esté activo hasta que tu programa funcione completamente pero no es así. Ese programa cada vez es más largo y no vamos a estar revisándolo entero. Cuando tengas una duda, específica la duda y manda el código necesario para resolverla, a veces será el programa entero, otras veces sólo será necesario mandar una función o un bloque. Si hace falta más código ya te lo diremos.

Segundo tu función de generar un número aleatorio en un sitio tiene una definición y en otro sitio otra. Te recomiendo que si la función se encarga de generar números aleatorios, tenga dos parámetros que indiquen el mínimo y el máximo para determinar el rango.Así la función será más polivalente que si simplemente cogemos un trozo del <main> lo metemos en una función y lo dejamos igual, hay que aprovechar las ventajas de las funciones.

Un prototipo que yo creo que estaría bastante bien para generar números aleatorios puede ser:
Código
  1. int generarNumeroAleatorio(int minimo, int maximo);
Si no quieres que tu función sea así y tenga otra definición, es tu decisión pero fíjate en lo que le pasas como parámetros ya que primero has puesto un código donde le pasas un entero y luego en el programa entero tiene otro prototipo sin parámetros.

Precisamente ahí si te da un problema al usar la función eso es lo que tienes que mandar para que te ayudemos, la función y explicar el error que te da, no decir que te da algún error y soltar 357 líneas de código.
Hay que tener un poco de consideración en lo que se pide, no estamos aquí para salvarte de cada problema que tengas. Aquí el que más tiene que poner de su parte eres tú, no nosotros.

En otro tema posterior a este he comentado como usar <typedef>, me había confundido así que ahora voy a modificar ese mensaje y de momento te dejo la respuesta correcta por aquí:
Código
  1. typedef int array10[10];
  2. int main(){
  3.    array10 miArray;
  4.    for(int i = 0; i < 10; i++)
  5.        miArray[i] = i;
  6. }
Ahí tienes como se usa el <typedef> para lo que tú querías hacer y un ejemplo de uso para que veas como se usan los índices, no tiene mucha complicación eso.

Por mi parte si tienes una duda concreta en un trozo de código concreto igual puedo ayudarte, revisar 357 líneas de código para solucionar todos tus problemas es algo que no voy a hacer. Suerte. :-X

PD: Tampoco recortes el programa y mandes lo mismo con menos código. Dudas concretas es preguntar por qué te sale un error o cómo puedes hacer tal cosa y te podremos dar una idea ya sea un ejemplo de código o una explicación en pseudocódigo para que tú después te encargues de implementarlo.


Título: Re: Ayuda con programa
Publicado por: HectorSersi en 10 Diciembre 2018, 21:30 pm
Primero si no es para citar algo concreto de otro mensaje no incluyas una cita a cada respuesta porque cada mensaje se hace larguísimo. Además de eso un tema se crea para resolver una duda específica, no para hacer un programa entero. Ya sé que es mucho más cómodo abrir un tema y que esté activo hasta que tu programa funcione completamente pero no es así. Ese programa cada vez es más largo y no vamos a estar revisándolo entero. Cuando tengas una duda, específica la duda y manda el código necesario para resolverla, a veces será el programa entero, otras veces sólo será necesario mandar una función o un bloque. Si hace falta más código ya te lo diremos.

Segundo tu función de generar un número aleatorio en un sitio tiene una definición y en otro sitio otra. Te recomiendo que si la función se encarga de generar números aleatorios, tenga dos parámetros que indiquen el mínimo y el máximo para determinar el rango.Así la función será más polivalente que si simplemente cogemos un trozo del <main> lo metemos en una función y lo dejamos igual, hay que aprovechar las ventajas de las funciones.

Un prototipo que yo creo que estaría bastante bien para generar números aleatorios puede ser:
Código
  1. int generarNumeroAleatorio(int minimo, int maximo);
Si no quieres que tu función sea así y tenga otra definición, es tu decisión pero fíjate en lo que le pasas como parámetros ya que primero has puesto un código donde le pasas un entero y luego en el programa entero tiene otro prototipo sin parámetros.

Precisamente ahí si te da un problema al usar la función eso es lo que tienes que mandar para que te ayudemos, la función y explicar el error que te da, no decir que te da algún error y soltar 357 líneas de código.
Hay que tener un poco de consideración en lo que se pide, no estamos aquí para salvarte de cada problema que tengas. Aquí el que más tiene que poner de su parte eres tú, no nosotros.

En otro tema posterior a este he comentado como usar <typedef>, me había confundido así que ahora voy a modificar ese mensaje y de momento te dejo la respuesta correcta por aquí:
Código
  1. typedef int array10[10];
  2. int main(){
  3.    array10 miArray;
  4.    for(int i = 0; i < 10; i++)
  5.        miArray[i] = i;
  6. }
Ahí tienes como se usa el <typedef> para lo que tú querías hacer y un ejemplo de uso para que veas como se usan los índices, no tiene mucha complicación eso.

Por mi parte si tienes una duda concreta en un trozo de código concreto igual puedo ayudarte, revisar 357 líneas de código para solucionar todos tus problemas es algo que no voy a hacer. Suerte. :-X

PD: Tampoco recortes el programa y mandes lo mismo con menos código. Dudas concretas es preguntar por qué te sale un error o cómo puedes hacer tal cosa y te podremos dar una idea ya sea un ejemplo de código o una explicación en pseudocódigo para que tú después te encargues de implementarlo.

Vale perdon, soy bastante nuevo, pero gracias por todo en serio, todavia me queda bastante pero gracias por todo hasta ahora :)


Título: Re: Ayuda con programa
Publicado por: CalgaryCorpus en 11 Diciembre 2018, 05:52 am
Dado que parece no entender esto de no repetir todo lo anterior, sugiero poner respuestas de un par de líneas.