Ayuda con programa

Iniciado por HectorSersi, 22 Noviembre 2018, 20:37 PM

0 Miembros y 1 Visitante están viendo este tema.

HectorSersi

Cita de: YreX-DwX 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).


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(...),...

K-YreX

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 (cpp) [Seleccionar]

int main(){
double puntuacionHumano, puntuacionMaquina;
int modo, numCartas;
ifstream fichero;
do{
modo = menu();
srand(time(NULL));

if(modo != 0){
numCartas = MINIMO + rand() % (MAXIMO - MINIMO + 1); // esto genera un numero en el intervalo cerrado [MINIMO, MAXIMO]
// esto tienes que hacerlo con la funcion generarMaxCartas() pero te lo dejo asi para que veas como se usa rand
fichero = abrirFichero();
}

switch(modo){
case 1:
cout << "\nEmpieza el juego (modo A: numCartas = " << numCartas << "):" << endl;
puntuacionHumano = modoA(fichero, numCartas);
puntuacionMaquina = modoA(fichero, numCartas);
determinaGanador(puntuacionHumano, puntuacionMaquina);
break;
case 2:
cout << "\nEmpieza el juego (modo B: numCartas = " << numCartas << "):" << endl;
puntuacionHumano = modoBHumano(fichero, numCartas);
puntuacionMaquina = modoBMaquina(fichero, numCartas, puntuacionHumano);
determinaGanador(puntuacionHumano, puntuacionMaquina);
break;
default:
cout << "Saliendo del juego..." << endl;
}
} while(modo != 0);
}


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.
Código (cpp) [Seleccionar]

cout << "Todos tenemos un defecto, un error en nuestro código" << endl;

HectorSersi

Cita de: YreX-DwX 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 (cpp) [Seleccionar]

int main(){
double puntuacionHumano, puntuacionMaquina;
int modo, numCartas;
ifstream fichero;
do{
modo = menu();
srand(time(NULL));

if(modo != 0){
numCartas = MINIMO + rand() % (MAXIMO - MINIMO + 1); // esto genera un numero en el intervalo cerrado [MINIMO, MAXIMO]
// esto tienes que hacerlo con la funcion generarMaxCartas() pero te lo dejo asi para que veas como se usa rand
fichero = abrirFichero();
}

switch(modo){
case 1:
cout << "\nEmpieza el juego (modo A: numCartas = " << numCartas << "):" << endl;
puntuacionHumano = modoA(fichero, numCartas);
puntuacionMaquina = modoA(fichero, numCartas);
determinaGanador(puntuacionHumano, puntuacionMaquina);
break;
case 2:
cout << "\nEmpieza el juego (modo B: numCartas = " << numCartas << "):" << endl;
puntuacionHumano = modoBHumano(fichero, numCartas);
puntuacionMaquina = modoBMaquina(fichero, numCartas, puntuacionHumano);
determinaGanador(puntuacionHumano, puntuacionMaquina);
break;
default:
cout << "Saliendo del juego..." << endl;
}
} while(modo != 0);
}


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 (cpp) [Seleccionar]
#include<iostream>
#include<cstdlib>
#include<ctime>
#include<fstream>
#include<string>

using namespace std;

const int HUMANO = 1;
const int MAQUINA = 2;

int menu();
double modoA(ifstream & archivo, int numeroAleatorio); //archivo lo puedes llamar como quieras aqui, pero luego al invocar tienes qe poner "archivo"
int determinaGanador(double puntosHumano, double puntosMaquina);
double modoBmaquina(ifstream & archivo, int numeroAleatorio, double puntosHumano);
double modoBhumano(ifstream & archivo, int numeroAleatorio);

int main()
{
int numeroAleatorio, modo;
ifstream archivo;
double puntosHumano, puntosMaquina;


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

modo = menu();

if (modo == 1)
{
string baraja;
cout << "Introduce el nombre del archivo que quieras abrir: " << endl;
cin >> baraja;

archivo.open(baraja); //archivo es lo declarado en ifstream

while (!archivo.is_open())
{
cout << "El archivo es incorrecto" << endl;
cin >> baraja;
archivo.open(baraja);
}
puntosHumano = modoA(archivo, numeroAleatorio);
puntosMaquina = modoA(archivo, numeroAleatorio);

if (determinaGanador(puntosHumano, puntosMaquina) == HUMANO) {
cout << "?as ganado!" << endl;
}
else
{
cout << "Ha ganado la maquina" << endl;
}

}
else if (modo == 2)
{
string baraja;
cout << "Introduce el nombre del archivo que quieras abrir: " << endl;
cin >> baraja;

archivo.open(baraja); //archivo es lo declarado en ifstream

while (!archivo.is_open())
{
cout << "El archivo es incorrecto" << endl;
cin >> baraja;
archivo.open(baraja);
}
puntosHumano = modoBhumano(archivo, numeroAleatorio);
puntosMaquina = modoBmaquina(archivo, numeroAleatorio,puntosHumano);
if (determinaGanador(puntosHumano, puntosMaquina) == HUMANO)
{
cout << "Ha ganado el HUMANO" << endl;
}
else
{
cout<<"El ganador es la maquina"<<endl;
}
}
else if (modo == 3)
{

}
else if (modo == 4)
{

}




return 0;
}

int menu()
{
int modo;
cout << "Elige el modo al que quieras jugar: " << endl;
cout << "Introduce 1 para Modo A: cada jugador estara obligado, cuando le llegue el turno, a robar un numero concreto de cartas." << endl;
cout << "Introduce 2 para Modo B: cada jugador podra robar el numero de cartas que desee y plantarse si no quiere mas." << endl;
cout << "Modo C " << endl;
cout << "Modo D " << endl;
cout << "Introducir 0 para salir del juego." << endl;
cin >> modo;

while (modo < 0 || modo > 4) {
cout << "No ha seleccionado ningun modo, vuelva a seleccionar el modo: ";
cin >> modo;

}


return modo;
}

double modoA(ifstream & archivo, int numeroAleatorio)
{
int final = 0, aux;
double puntos = 0;

while (final < numeroAleatorio && puntos < 7.5)
{
archivo >> aux;
if (aux > 7) {
puntos = puntos + 0.5;
}
else
{
puntos = puntos + aux;
}



}

return puntos;
}

double modoBhumano(ifstream & archivo, int numeroAleatorio)
{
int final = 0, aux, responder;
double puntos = 0;
bool continuar = true;

while (final < numeroAleatorio && puntos < 7.5 && continuar)
{
archivo >> aux;
if (aux > 7) {
puntos = puntos + 0.5;
}
else
{
puntos = puntos + aux;
}
cout << "Tu puntuacion es; " << puntos << endl;
cout << "1 para seguir y 2 para parar " << endl;
cout << "Quieres continuar? " << endl;
cin >> responder;

while (responder < 1 || responder > 2) {
cout << "No ha seleccionado ningun modo, vuelva a seleccionar el modo: ";
cin >> responder;
}

if (responder == 1) {
continuar = true;
}
else {
continuar = false;
}
}

return puntos;
}

double modoBmaquina(ifstream & archivo, int numeroAleatorio, double puntosHumano)
{
int final = 0, aux;
double puntos = 0;
bool continuar = true;

while (final < numeroAleatorio && puntos < 7.5 && continuar)
{
archivo >> aux;
if (aux > 7) {
puntos = puntos + 0.5;
}
else
{
puntos = puntos + aux;
}

if (puntosHumano > puntos)
{
continuar = true;
}

else {
continuar = false;
}
}

return puntos;
}


int determinaGanador(double puntosHumano, double puntosMaquina)
{
int ganador;
if (puntosHumano > puntosMaquina)
{
ganador = HUMANO;
}
else if (puntosHumano < puntosMaquina)
{
ganador = MAQUINA;
}
else
{
ganador = HUMANO + rand() % +(MAQUINA - HUMANO);
}


return ganador;
}

K-YreX

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.
Código (cpp) [Seleccionar]

cout << "Todos tenemos un defecto, un error en nuestro código" << endl;

HectorSersi

#14
Cita de: YreX-DwX 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.



K-YreX

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.
Código (cpp) [Seleccionar]

cout << "Todos tenemos un defecto, un error en nuestro código" << endl;

HectorSersi

Cita de: YreX-DwX 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.


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.

K-YreX

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.
Código (cpp) [Seleccionar]

cout << "Todos tenemos un defecto, un error en nuestro código" << endl;

HectorSersi

Cita de: YreX-DwX 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.

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

K-YreX

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 (cpp) [Seleccionar]

int cartasASaltar = generarAleatorio(0,5);
int cartasSaltadas = 0;
int carta;
while(!fichero.eof() && cartasSaltadas <= cartasASaltar){
    fichero >> carta;
    cartasSaltadas++;
}
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
Código (cpp) [Seleccionar]

cout << "Todos tenemos un defecto, un error en nuestro código" << endl;