Menú

Mostrar Mensajes

Esta sección te permite ver todos los mensajes escritos por este usuario. Ten en cuenta que sólo puedes ver los mensajes escritos en zonas a las que tienes acceso en este momento.

Mostrar Mensajes Menú

Mensajes - K-YreX

#831
Programación C/C++ / Re: Ayuda con programa
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 (cpp) [Seleccionar]

while(puntosMaquina < puntosHumano && puntosMaquina < 7.5)
    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 (cpp) [Seleccionar]

int determinaGanador(int puntosHumano, int puntosMaquina){
    int ganador = HUMANO;
    if(puntosHumano > 7.5 || (puntosMaquina < 7.5 && puntosHumano < puntosMaquina))
        ganador = MAQUINA;
    else if(puntosHumano == puntosMaquina)
        ganador += rand() % 2;
    return ganador;
}

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

puntosHumano = modoA(archivo, numeroAleatorio);
if(puntosHumano < 7.5)
    puntosMaquina = modoA(archivo, numeroAleatorio);
//...

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

const int PUNTUACION_LIMITE = 7.5;
// 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
#832
Hay que darle la vuelta a la segunda parte:

int compararFilas(matriz[FILAS][COLUMNAS]){
    int filaAComparar[COLUMNAS];
    int iguales = 0;
    for(int i = 0; i < FILAS - 1 && !iguales; i++){
        for(int j = 0; j < COLUMNAS; j++)
            filaAComparar[j] = matriz[i][j];

        for(int m = i+1; m < FILAS && !iguales; m++){
            iguales = 1;
            for(int n = 0; n < COLUMNAS && iguales; n++)
                if(filaAComparar[n] != matriz[m][n])
                    iguales = 0;
        }
    }
    return iguales;
}


Si no me he equivocado esa función debería funcionar. Primero, la <i> tiene que ir hasta hasta la penúltima fila ya que no tiene sentido comparar la última con la siguiente (porque no hay siguiente).
Además el array auxiliar no hace falta pasarlo como parámetro, puede ser una variable local que "desaparezca" en cuanto acabe la función.
En la parte final el bucle exterior empieza en <i+1> y el interior en 0. Esto se traduce como: "para cada fila posterior a la fila <i> recorremos toda la fila". Si le das la vuelta fíjate que en el <if> usas <v[m]> y <m> en tu caso no va de 0 a COLUMNAS-1. En tu caso <m> se queda con un valor fijo y lo que se mueve es la <n>. Siempre varía más veces el valor del bucle interior que el exterior. Suerte. :-X
#833
Programación C/C++ / Re: Ayuda con programa
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 (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
#834
Primero de todo cuando mandes un código entre etiquetas GeSHi, para que sea más fácil distinguirlo. :rolleyes:

Bueno, cuando mandas un puntero a una función para reservar memoria dentro de la función, ese puntero tiene que pasarse por referencia ya que sino al salir de la función es como que no has reservado memoria.
Código (cpp) [Seleccionar]

void cargarPuntero(int *&p, int size){
    p = new int[size];
    for(int i = 0; i < size; i++)
        *(p+i) = i; // guardamos {0, 1, 2, ..., size-1}
}


Además de eso, para mostrar el array tienes que recorrerlo, para ello tienes que desreferenciarlo, es decir, usar "*". Puedes hacerlo de varias formas, te dejo dos:
- Opción 1: Usar el contador para mostrar cada elemento:
Código (cpp) [Seleccionar]

void mostrarArray(int *p, int size){
    for(int i = 0; i < size; i++)
        cout << *(p+i) << "  ";
}


- Opción 2: Crear otro puntero e ir modificando este para que apunte al siguiente elemento:
Código (cpp) [Seleccionar]

void mostrarArray(int *p, int size){
    int *auxiliar = p;
    for(int i = 0; i < size; i++){
        cout << *auxiliar << "  ";
        auxiliar++;
    }
}

Es muy importante que si vas a modificar el puntero, tengas otro apuntando al comienzo (es decir, uno que no modifiques). Ya que si en el código anterior no creamos el puntero auxiliar y modificamos <p> si luego quieres hacer más cosas con el array, lo habrás perdido. Un objeto dinámico al que no apunta un puntero es un objeto perdido. Por eso uno apunta siempre al principio (p) y el otro se va moviendo por cada elemento (auxiliar).

Edit: En los ejemplos anteriores te he dejado también como se desreferencia un puntero, es decir, como usar "*". <p> contiene la dirección de memoria del elemento 0 del array, mientras que <*p> contiene el elemento 0 del array. Suerte.
#835
Intentaré darte un par de ideas por si quieres aplicar alguna:
- En primer lugar yo en C++ prefiero usar <string> en lugar de cadenas de caracteres C ya que creo que facilitan algunas tareas. Y para coger los datos uso <cin> de <iostream> en vez de <gets()> de <cstdio>.
- Si por lo que sea prefieres seguir usando cadenas de caracteres, cambiaría los <gets()> por <fgets()>.
- Para evitar los <fflush(stdin)> hay un par de temas en el foro que creo que ya has visto. Tienes la opción de usar <fseek()> para ponerte al final del buffer si hay más caracteres de los admitidos o si te quedan saltos de línea puedes capturarlos con un <getchar()> hasta que no quede ninguno. Eso ya depende de lo que necesite tu programa.
Suerte. :-X
#836
<"corriente" || "ahorro"> es una expresión booleana, no es una cadena de caracteres <char*>. Tienes que comparar con una y después con la otra por separado. Suerte.
#837
Para copiar por ejemplo los caracteres útiles de <nombre> en <p_nombre> puedes usar la función <strncpy()> que te permite introducir cuántos caracteres se van a copiar. Ya que el problema que tú estabas teniendo es que en ningún momento asignas un valor a <p_nombre>. No es lo mismo reservar espacio que asignar, primero haces hueco para meter algo, pero luego tienes que meter ese algo. Y recuerda al trabajar con memoria dinámica liberarla al terminar el programa. Suerte.
#838
No entiendo esto:
Código (cpp) [Seleccionar]

int menu1();


Este trozo de código creo que no tiene ni pies ni cabeza. Si <i> vale uno menos que <n>, incrementas <i> (ahora <i  == n>) y asignas el valor de <i> a <j> y mientras <j> sea menor que <n> (cosa que ya no es ya que <j == n>)... da igual lo que haga después ya que no se va a hacer.
Código (cpp) [Seleccionar]

else if(x=true&&i==n-1){
                    i++;
                    cout<<"Este DNI no existe en nuestros datos"<<endl;
                for(int j=i;j<n;j++){
                    variosClientes.Clientes[j] = variosClientes.Clientes[j+1];


Además de eso tienes algunos errores de asignación y comparación. Un igual "=" para asignar un valor <x = false>. Dos iguales "==" para comparar un valor <x == false>. En algunos trozos del programa los usas al revés.

Aparte de eso tener un <while(x == true)> equivale a tener <while(x)> y tener un <while(x == false)> equivale a tener <while(!x)>. Así es más fácil de ver.

También es recomendable en programas con muchas variables sobre todo usar nombres que te ayuden a ver qué hace esa variable ya que yo veo de repente una "t" o una "p" y tengo que ir arriba para ver que era eso.

Tampoco sé cómo has implementado las funciones de lectura que aparecen por ahí entonces no soy capaz de ver cuál es el error. Ya que tampoco sé exactamente cuál es el error, si quieres puedes probar a meter un par de <cout> con las variables que estás comparando en el <if> y así ver cuánto valen y poder encontrar el error.
#839
Has creado un puntero a <char>. Como su nombre indica un puntero apunta y el tuyo no apunta a ningún sitio. Lo que haces con <malloc> es reservar espacio en ese puntero pero en este caso ya tienes una cadena C que es <nombre> entonces con hacer que <p_nombre> apunte a <nombre> ya está.

int main(){
printf("Introduzca su nombre: ");
char nombre[20],*p_nombre;
fgets(nombre, 20, stdin);
p_nombre = nombre;
printf("%s",p_nombre);
}


Además de eso te he modificado la función <gets()> ya que es mejor usar <fgets()> y así especificar el número de caracteres que va a coger la función. De todos modos si lo dejas así e introduces 19 o 20 caracteres se te va a quedar el último o los dos últimos en el buffer ya que tienes capacidad para 20 caracteres pero tienes que contar el salto de línea "\n" cuando pulsas enter y el "\0" que indica el final de cadena.
#840
Programación C/C++ / Re: Ayuda con programa
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.