elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.

 

 


Tema destacado: Sigue las noticias más importantes de seguridad informática en el Twitter! de elhacker.NET


  Mostrar Mensajes
Páginas: 1 ... 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 [90] 91 92 93 94 95 96 97 98 99 100 101 102
891  Programación / Programación C/C++ / Re: Ayuda con programa 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)
892  Programación / Programación C/C++ / Re: Compilar C/C++ en Windows en: 9 Diciembre 2018, 02:59 am
Retomo este tema para ver si alguien puede ayudarme con algo relacionado a lo que ya pregunté aquí. Bueno la cosa es que cuando compilo programas pequeños puedo hacerlo en Windows sin problemas desde la línea de comandos como me habéis comentado en las respuestas de este post; sin embargo, cuando trabajo en programas más grandes, procuro modularizar todo el código con la siguiente estructura en Linux:
/programa
|_ /bin
|_ /obj
|_ /src
|_ /include
|_ /lib
|_ Makefile

Y entonces simplemente poniéndome al nivel del Makefile en la terminal y mediante la orden <make> se compilan todos los archivos necesarios en sus correspondientes directorios.

Quería saber si puedo hacer algo equivalente a esto en Windows. Mi idea es poder compilar los códigos en ambos sistemas operativos, pero creo que para empezar tendría problemas por el sistema de archivos ya que en el Makefile los directorios se representan para un sistema Linux y no para uno Windows. Si alguien puede ayudarme... :-X :-X
893  Programación / Programación C/C++ / Re: Guardar una frase en los elementos de un vector en: 8 Diciembre 2018, 23:54 pm
GominaTilted, respecto a tu código:
- Las funciones que no reciben parámetros, no hace falta que pongas <void>. Eso creo que es más de C, en C++ se suele dejar vacío.
Código
  1. void Cabecera()
- Y la función <Cabecera()> no tiene mucho sentido, sólo para hacer un <cout>. Si fuese un conjunto de instrucciones más grande o fuese un titulo muy trabajado... Pero para hacer un <cout> lo puedes hacerlo directamente en el <main>.
- Además si no devuelven ningún valor puedes omitir el <return> del final. No es muy habitual ver un <return> en una función de tipo <void>.

Respecto a tu problema de omitir palabras que estén repetidas, la idea siempre es la misma, tener un contenedor de palabras (seguramente usarás arrays pero también puedes usar un contenedor de la STL), coger una palabra, recorrer el contenedor y si no existe ya, la metes en el contenedor.

He estado probando un código que hice hace poco para separar palabras y he intentado adaptarlo para este problema. Sin embargo, sólo me coge la primera palabra. He mirado el código original del que he sacado la estructura de la función y en el original funciona perfecto pero no consigo dar con el problema. El código que he intentado adaptar es este:
Código
  1. #include <iostream>
  2. #include <string>
  3.  
  4. using namespace std;
  5.  
  6. const int MAX_PALABRAS = 20;
  7.  
  8. size_t SepararPorPalabras(string, string*);
  9.  
  10. int main(){
  11. string frase;
  12. string palabras[MAX_PALABRAS];
  13. size_t numPalabras;
  14.  
  15. cout << "Ingresa una frase: ";
  16. getline(cin, frase);
  17.  
  18. numPalabras = SepararPorPalabras(frase, palabras);
  19.  
  20. cout << "La frase tiene " << numPalabras << " palabras: " << endl;
  21. for(size_t i = 0; i < numPalabras; i++)
  22. cout << "Palabra " << i+1 << ": " << palabras[i] << endl;
  23.  
  24. }
  25.  
  26. size_t SepararPorPalabras(string frase, string *palabras){
  27. size_t numPalabras = 0, letrasPorPalabra;
  28. string palabra;
  29.  
  30. while((letrasPorPalabra = frase.find(' ')) != string::npos && numPalabras < MAX_PALABRAS){
  31. palabra = frase.substr(0, letrasPorPalabra);
  32. frase.erase(0, letrasPorPalabra+1);
  33. palabras[numPalabras++] = palabra;
  34. }
  35. if(numPalabras < MAX_PALABRAS){
  36. palabra = frase.substr(0, letrasPorPalabra);
  37. palabras[numPalabras++] = palabra;
  38. }
  39. return numPalabras;
  40. }

La salida del programa es la siguiente:
Código:
Ingresa una frase: frase de prueba
La frase tiene 1 palabras:
Palabra 1: frase

Si alguien puede echarme una mano para encontrar el error.  :-X :-X
894  Programación / Programación C/C++ / Re: Función que diga si dos columnas/filas de una matriz son iguales. en: 8 Diciembre 2018, 22:06 pm
Supongo que con este te irá bien.
Va comprobando desde la primera hasta la penúltima columna si las siguientes son iguales a ellas. En cuánto detecta que dos elementos no son iguales va no pierde más tiempo y va a buscar la siguiente columna. Si detecta que dos columnas son iguales se detiene e informa de ello.
Hay que usar stdbool, pero se puede cambiar el bool por int y true y false por 1 y 0 respectivamente.

Código
  1. bool columnas_iguales(int matriz[][COLUMNAS]) {
  2.    bool retval = false;
  3.  
  4.    for(int i=0; !retval && i<COLUMNAS-1; ++i) {
  5.        for(int j=i+1; !retval && j<COLUMNAS; ++j) {
  6.            int m;
  7.            for(m=0; m<FILAS; ++m) {
  8.                if(matriz[m][i]!=matriz[m][j])
  9.                    break;
  10.            }
  11.            if(m==FILAS)
  12.                retval = true;
  13.        }
  14.    }
  15.  
  16.    return retval;
  17. }

Por lo que yo tengo entendido no es muy recomendable usar instrucciones como <break> (excepto en un <switch>), <goto>, etc. Entonces se puede conseguir lo mismo usando la propia variable <retval>. Supones que son iguales y cuando dos valores no coincidan, dejan de ser iguales. Quedaría así:
Código
  1. bool columnas_iguales(int matriz[][COLUMNAS]) {
  2.    bool retval = false;
  3.    for(int i=0; !retval && i<COLUMNAS-1; ++i) {
  4.        for(int j=i+1; !retval && j<COLUMNAS; ++j) {
  5.            retval = true;
  6.            for(int m=0; retval && m<FILAS; ++m)
  7.                if(matriz[m][i]!=matriz[m][j])
  8.                    retval = false;
  9.    }
  10.    return retval;
  11. }
A esto me refería cuando al principio le comenté a Hackersanfe que intentará hacerlo sin el array auxiliar.

PD: No sabía que para usar el tipo de dato <bool> en C se podía hacer con <stdbool>. Yo creaba una enumeración para poder usarlo. Algo así:
Código
  1. typedef enum {false, true} bool;
895  Programación / Programación C/C++ / Re: Ayuda con programa 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.
896  Programación / Programación C/C++ / Re: Error en compilación! en: 8 Diciembre 2018, 15:32 pm
Como te han comentado:
Fíjate en el nombre que le pusiste a la función y como la invocaste. Hay una diferencia allí.

Estás cambiando el nombre de la función. En el prototipo de la función se llama <SumaCifrasNumero()> y en la implementación (abajo) se llama <SumarCifrasNumero()>. El fallo es esa "R" de "Sumar".

Cuando un compilador te muestra este error "undefined reference to `SumaCifrasNumero(int, int)". Se debe a que no encuentra la función que le estás diciendo. En esos casos tienes que ver que el nombre sea el mismo (cosa que en tu caso no es y por eso falla) o que le estés pasando diferentes parámetros en un sitio que en otro (no es tu caso). Suerte. :-X
897  Programación / Programación C/C++ / Re: Ayuda con programa 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
898  Programación / Programación C/C++ / Re: Función que diga si dos columnas/filas de una matriz son iguales. en: 8 Diciembre 2018, 15:04 pm
Hay que darle la vuelta a la segunda parte:
Código
  1. int compararFilas(matriz[FILAS][COLUMNAS]){
  2.    int filaAComparar[COLUMNAS];
  3.    int iguales = 0;
  4.    for(int i = 0; i < FILAS - 1 && !iguales; i++){
  5.        for(int j = 0; j < COLUMNAS; j++)
  6.            filaAComparar[j] = matriz[i][j];
  7.  
  8.        for(int m = i+1; m < FILAS && !iguales; m++){
  9.            iguales = 1;
  10.            for(int n = 0; n < COLUMNAS && iguales; n++)
  11.                if(filaAComparar[n] != matriz[m][n])
  12.                    iguales = 0;
  13.        }
  14.    }
  15.    return iguales;
  16. }

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
899  Programación / Programación C/C++ / Re: Ayuda con programa 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
900  Programación / Programación C/C++ / Re: Problemas para mostrar un vector lineal dinámico en: 7 Diciembre 2018, 02:59 am
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
  1. void cargarPuntero(int *&p, int size){
  2.    p = new int[size];
  3.    for(int i = 0; i < size; i++)
  4.        *(p+i) = i; // guardamos {0, 1, 2, ..., size-1}
  5. }

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
  1. void mostrarArray(int *p, int size){
  2.    for(int i = 0; i < size; i++)
  3.        cout << *(p+i) << "  ";
  4. }

- Opción 2: Crear otro puntero e ir modificando este para que apunte al siguiente elemento:
Código
  1. void mostrarArray(int *p, int size){
  2.    int *auxiliar = p;
  3.    for(int i = 0; i < size; i++){
  4.        cout << *auxiliar << "  ";
  5.        auxiliar++;
  6.    }
  7. }
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.
Páginas: 1 ... 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 [90] 91 92 93 94 95 96 97 98 99 100 101 102
WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines