Haz una pregunta
  Foros de Electrónica » Diseño digital » Microcontroladores y sistemas embebidos
Foros Registrarse ¿Olvidaste tu contraseña?

Temas similares

05/10/2016 #1


Juego del Ahorcado en C
Buenos días, estoy teniendo un problema con este programa y quería ver si me pueden ayudar...

Lo que debería hacer el programa es preguntar la palabra con la que se jugará al ahorcado, luego borra la pantalla. Después pide que ingreses una letra de la palabra, si esta coincide con una letra de la palabra ingresada, dará un mensaje por pantalla diciendo ""Ha acertado una de las letras: " y al lado la letra que acertó, y le sumará 1 al contador del while. Sigue el programa aumentando 1 a contador 2 hasta que este tenga la cantidad de letras de la palabra ingresada (así compobará letra por letra). Se sale del while general cuando la cantidad de letras sea la misma a la palabra que se ingreso (se saldría recién cuando adivinen todas las letras).
Cuando sale de los while (que por ende ya estaría adivinada la palabra) da un mensaje diciendo "¡Adivino la palabra!: " y al lado "lapalabraqueseingresó".

El código es este, aver si alguien puede ayudarme

Código:
#include <stdio.h>
#include <stdlib.h>

int main(){
    int cont,cont2,ing;
    char palabra[10];

    cont=0;
    cont2=0;

    printf("Ingrese la palabra para jugar al ahorcado: ");
    scanf("%s",&palabra);

    while (cont<strlen(palabra)){
        palabra[cont]=toupper(palabra[cont]);
        cont++;}

    cont=0;

    system("cls");

    while (cont<strlen(palabra)){
    printf("Ingrese una letra de la palabra: ");
    scanf("%s",&ing);
    while (cont2<strlen(palabra)){
    if (ing==palabra[cont2]){
        printf("Ha acertado una de las letras: ");
        printf("%s",ing);
        cont++;}
        cont2++;}}

    printf("¡Adivino la palabra!: ");
    printf("%s",palabra);

    return 0;
}
05/10/2016 #2

Avatar de Dr. Zoidberg

Davok dijo: Ver Mensaje
Buenos días, estoy teniendo un problema con este programa y quería ver si me pueden ayudar...
Y cual se supone que es el problema...???

PD: Bastante ESPANTOSA la forma de poner las llaves de apertura y cierre...
05/10/2016 #3


Dr. Zoidberg dijo: Ver Mensaje
Y cual se supone que es el problema...???

PD: Bastante ESPANTOSA la forma de poner las llaves de apertura y cierre...
El problema es que al ingresar una letra correctamente sigue pidiendo que ingreses y no hace nada, ni da el mensaje de "Ha acertado una letra"!

Lo sé pero voy a mejorarlo en después
05/10/2016 #4

Avatar de palurdo

Adiós, scanf("%s",&ing);
Hola, ing=getchar();

Adiós, printf("%s",ing);
Hola, putchar(ing);

Adios toupper.


De todas formas tu enfoque no va a funcionar.

Mira:
Código:
Ingrese la palabra para jugar al ahorcado: cielo
Ingrese una letra de la palabra: o
Ha acertado una de las letras: o
Ingrese una letra de la palabra: o
Ha acertado una de las letras: o
Ingrese una letra de la palabra: o
Ha acertado una de las letras: o
Ingrese una letra de la palabra: o
Ha acertado una de las letras: o
Adivinó la palabra cielo.
05/10/2016 #5

Avatar de Dr. Zoidberg

Primer error:
Código:
scanf("%s",&palabra);
palabra es un arreglo de char (string, ponele) y el nombre de un arreglo es un puntero al primer elemento (te perdiste esa clase??). Así que como el scanf espera un puntero, lo que tenés que usar es:
Código:
scanf("%s",palabra);
de todas formas leer un string con una scanf es parecido a suicidarse, y lo que hay que usar es la función gets (debería usar la fgets, pero por ahora vamos bien así). Algo como:
Código:
gets( palabra );
Segundo error:
Código:
  if (ing==palabra[cont2]){
palabra[cont2] es un char e ing es un int, así que la comparación correcta sería con un cast:
Código:
  if ( (char)ing == palabra[cont2] ){
Tercer error:
Te dije que ing es un char!!! no un char[], así que está mal esto:
Código:
printf("%s",ing);
y para mostrarlo tenés que hacer:
Código:
printf("%c", (char)ing );
o más fácil:
Código:
putchar( (char)ing );
y sumá lo de palurdo...

Lo sé pero voy a mejorarlo en después
La típica mentira del informático...
05/10/2016 #6

Avatar de Nuyel

Prueba cambiar "&palabra" a "palabra", el & no se usa cuando es array, &var significa "dirección de var", pero en un array[i] el valor "array" ya es en si un puntero y por lo tanto, hacer &array es dirección de array no a donde este apunta.
05/10/2016 #7

Avatar de palurdo

En fin, estudia este código anda...

estúdialo, no lo copies....

Código:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>

void main(){

	int vidas=7, aciertos=0;
	char palabra[50],adivina[50]="",incognitas[2]="*",tecla;

	printf("\nIntroduce palabra a adivinar: ");
	fgets(palabra,50,stdin);
	for(int i=0;i<strlen(palabra);i++) if(palabra[i]=='\n') palabra[i]=0;
	for(int i=0;i<strlen(palabra);i++) strcat(adivina,incognitas);

	while(vidas&&stricmp(palabra,adivina)){
		printf("\nIntroduce un caracter de la palabra: ");
		while((tecla=getchar())=='\n');
		aciertos=0;
		for(int i=0;i<strlen(palabra);i++)
			if ((tolower(tecla)==tolower(palabra[i]))&&(tolower(tecla)!=tolower(adivina[i]))){
				adivina[i]=palabra[i];
				aciertos++;
			}
			else if (tolower(tecla)==tolower(adivina[i])) aciertos=-1;
		switch(aciertos){
		case -1:
			printf("Has repetido la letra %c en la palabra %s.\nTe penalizo una vida bandido!!\n",tecla,adivina);
			vidas--;
			break;
		case 0:
			vidas--;
			printf("No se encuentra la letra %c en la palabra %s.\nTe quedan %d vidas.\n",tecla,adivina,vidas);
			break;
		case 1:
			printf("La letra %c se encuentra en la palabra %s una vez.\nTe quedan %d vidas.\n",tecla,adivina,vidas);
			break;
		default:
			printf("La letra %c se encuentra en la palabra %s unas %d veces.\nTe quedan %d vidas.\n",tecla,adivina,aciertos,vidas);

		}
	}
	if(vidas) printf("\nHas acertado!! la palabra es %s\n",palabra);
	else printf("Agotaste tus vidas, la palabra era %s, toorpe...",palabra);
}
05/10/2016 #8

Avatar de TRILO-BYTE

para ingresar una cadena de caracteres puedes usar gets(); de c++;

digamos:

char cadena[15]; // mi cadena de carcteres
char caracter; //mi caracter para comparar caracteres
int i; //mi contador


printf("mete una cadena\n"); //mostrara meter cadena.
gets(cadena); // espera la cadena hasta que pisas enter.


para comprobar la letra que pises puedes usar scanf;

scanf( "%c", caracter ); //leemos solo 1 caracter

ahora para saber si esta o no en la cadena puedes hacer un barrido facil

digamos que en la palabra transistor buscaremos las letras "s" que hay 2

es simple con un bucle while buscaremos letra a letra dentro de la cadena si llegamos a caracter nulo que se representa asi : '\n' se acaba la busqueda.


i=0;
while(cadena[i]!='\0')
{

if(cadena[i]=='s')
{
printf("se encontro la letra: s");
}
i++;
}


bueno pude haber resuelto tu problema pero te di las bases para que hagas bien tu programa
05/10/2016 #9

Avatar de palurdo

TRILO-BYTE dijo: Ver Mensaje
gets(cadena); // espera la cadena hasta que pisas enter.
gets deberia estar prohibida. Se debería usar siempre fgets, precisamente para evitar...



...el temido buffer overrun/overflow.
05/10/2016 #10

Avatar de Dr. Zoidberg

palurdo dijo: Ver Mensaje
gets deberia estar prohibida. Se debería usar siempre fgets, precisamente para evitar...

http://es.xkcd.com/site_media/strips...s_of_a_mom.png

...el temido buffer overrun/overflow.
Si, pero la caricatura no es de ataque de "buffer overflow" sino de un "sql injection"
05/10/2016 #11

Avatar de palurdo

Dr. Zoidberg dijo: Ver Mensaje
Si, pero la caricatura no es de ataque de "buffer overflow" sino de un "sql injection"
Si, eso ya lo se, pero de xkcd no hay ningun chiste que yo sepa sobre el buffer overflow, asi que he puesto esa viñeta porque es un ataque como tantos otros donde interviene una cadena "especial", vamos, que hay que tomar precauciones, ya sea por SQL injection, por Buffer Overflow, XSS Scripting, ARP poisoning, DNS hijacking (esta es la favorita de los malwares) etc...

Edit: Si que hay una caricatura de xkcd sobre el buffer overflow... Pero no es tan graciosa
05/10/2016 #12

Avatar de TRILO-BYTE

estan escribiendo algo que mi no entender y si mi no entender el colega que pregunto por un programa de escuela pues lo estan haciendo bolas.

ahora fgets ¿no es para abrir un fichero y obtener una cadena de caracteres?

yo se que es un programa en C pero no se podria usar funciones del C++ y en ese caso usar IOSTREAM para abrir ficheros?
05/10/2016 #13

Avatar de Dr. Zoidberg

fgets te permite operar (no abrir) sobre archivos, pero si usas stdin (que es un archivo --> FILE *) te permite leer del teclado directamente.
El C es muy poderoso, pero hay que saber lo que estas haciendo...
PD: no podes mezclar la stdio.h con la iostream.h por que se desincronizan los buffers I/O. Sinceramente echaria a los docentes que enseñan esas barbaridades. No tienen NPI de C ni de C++
05/10/2016 #14

Avatar de TRILO-BYTE

jeje por desgracia ami nadie me enseño a programar.
tube que aprender de libros viejos de la biblioteca.

asi que pues aprendi como dicen en mi pais a la brava, por eso no es de extrañar que diga palurdeces como mezclar C++ con C.
06/10/2016 #15

Avatar de palurdo

TRILO-BYTE dijo: Ver Mensaje
asi que pues aprendi como dicen en mi pais a la brava, por eso no es de extrañar que diga palurdeces como mezclar C++ con C.
¿Alguien me ha invocado?

En Spain se usa la variante "a las bravas". De todas formas hay cosas de programación que no se aprenden en la escuela... (Sobre todo la programación "harry el sucio").

Edit: la diferencia entre gets y fgets es que ademas de que fgets acepta como entrada cualquier dispositivo de entrada y no solo stdin como gets, fgets conoce de antemano la cantidad maxima de bytes que puede volcar desde el buffer de entrada a la variable referenciada, pero gets no. Si por ejemplo tienes memoria reservada para 10bytes y la entrada son 25bytes, gets va a escribir 15 bytes de memoria perteneciente a otra zona reservada, posiblemente una dirección de retorno de una rutina que si esta bien calculada apunta al código sobreescrito que puede tener las instrucciones necesarias para empezar a invadir la máquina.
06/10/2016 #16

Avatar de TRILO-BYTE

fijate eso no tenia idea y si me referia a yo como inepto "palurdo" no se si en otro lado palurdo sea sinonimo de inepto pero con ligeros conocimientos en programacion.

por desgracia tube malos maestros en programacion y pues como me daba curiosidad aprendi a la brava.
desconocia eso del uso del fgets();

esa funcion la usaba unicamente para abrir archivos binarios y trabajar byte a byte hasta EOF();
10/10/2016 #17


¡Gracias a todos! Pude solucionar el problema.

Le agregué algunas cosas. Para terminarlo solamente me faltaría saber (ya que no he podido resolverlo) es, cómo hacer para que funcione la parte del código que les mostraré a continuación.

Lo que debería hacer, es mostrar guiones con la cantidad de letras de la palabra ingresada, cuando se ingresa una letra correcta, el guión es reemplazado por ésta, si hay varias letras, las reemplazará en el lugar correspondiente.
Es para que el usuario sepa las letras que ingresó y que se oriente algo. (Ustedes entienden.)

Acá el código:
Código:
#include <stdio.h>
#include <stdlib.h>

int main(){
    int cont,cont2,cont3,cont4,tope,flag,vidas,dibu,acerto;
    char palabra[50],ingresadas[26],ing,guiones[50];

    cont=0;
    cont2=0;
    cont3=0;
    tope=1;
    vidas=6;
    dibu=0;

    printf("Ingrese la palabra para jugar al ahorcado: ");
    scanf("%s",palabra);

    while (cont<strlen(palabra)){
        palabra[cont]=tolower(palabra[cont]);
        cont++;}

    cont=0;

    while (cont<strlen(palabra)){
        guiones[cont]='_';
        cont++;}

    cont=0;

    system("cls");

    printf("Le quedan %d vidas.\n\n",vidas);


    while ((cont<strlen(palabra)) && (vidas>0)){
    printf("Ingrese una letra de la palabra: ");
    scanf("%s",&ing);
    ing=tolower(ing);
    fflush(stdin);
    flag=0;
    cont2=0;
    while ((flag==0)&&(cont2<tope)){
        if (ing==ingresadas[cont2]){
        flag=1;}
        cont2++;
            }
    if (flag==1){
        printf("La letra ya se ingreso anteriormente.\n\n");}
    else{
        ingresadas[tope]=(char)ing;
        tope++;
    cont2=0;
    acerto=0;
    while(cont2<strlen(palabra)){
    if (ing==palabra[cont2]){
        printf("Ha acertado una de las letras: ");
        printf("%c\n\n",ing);
        acerto=1;
        cont++;}
        cont2++;}
        if (acerto==0){
        vidas--;
        dibu++;
        system("cls");
        printf("Le quedan %d vidas.\n\n",vidas);
        cont4=0;
        while (cont4<strlen(palabra)){
        if (ing==palabra[cont4]){
            guiones[cont4]=ing;}
        else {guiones[cont4]='_';}
        cont4++;}
        cont4=0;
        while (cont4<strlen(palabra)){
        if (guiones[cont4]==palabra[cont4]){
            printf("%s",palabra[cont4]);}
        if (guiones[cont4]!=palabra[cont4]){
            printf("%c",'_');}
        cont4++;}
        dibujo(dibu);
        printf("\n");
        }}}

    cont=0;

    while (cont<strlen(palabra)){
        palabra[cont]=toupper(palabra[cont]);
        cont++;}

    if (vidas==0){
        printf("\t\t\t¡PERDIO EL JUEGO! LA PALABRA ERA: %s",palabra);}
    else{
    printf("\t\t\t¡ADIVINO LA PALABRA!: ");
    printf("%s",palabra);}



    return 0;
}


int dibujo(int errados){

    if (errados > 0) {
       printf ("  O  \n");}
    if (errados > 1) {
       printf ("  |  \n");}
    if (errados > 2) {
       printf (" / \\ \n");}
    if (errados > 3) {
       printf ("  |  \n");}
    if (errados > 4) {
       printf (" / \\ \n");}
    if (errados > 5) {
       printf ("_   _\n");}
}
Lo que remarqué en rojo es la parte que no funciona.
10/10/2016 #18

Avatar de palurdo

Es decir, tu buscas algo similar a esto pero con guiones:



Esto lo hace el código que te programé en unos minutos en unos mensajes atrás. Como ves no utiliza tantos contadores ni tantas comprobaciones. El enfoque del código es realmente sencillo. Simplemente hace lo que haria el maestro del juego. ¿que dispone en cada turno el maestro? El conteo de vidas, la palabra oculta, y las casillas (los guiones o asteriscos o huecos para las letras) que el jugador debe rellenar. Opcionalmente un contador para el numero de aciertos por turno, pero nada mas. El maestro del juego, tras conocer la palabra a adivinar, crea unas casillas con el mismo numero de letras. Tu lo has hecho casi bien, solo te falta, justo después de cerrar el bucle while, la sentencia guiones[cont]=0; ya que necesitas marcar el fin de la palabra generada con casillas.

No necesitas hacer mucho más. Cada turno, cuando cojes una letra, recorres con un índice la palabra secreta. Pueden pasar 3 cosas. Que la letra tecleada no coincida con ninguna de las posiciones de la palabra secreta, por lo tanto la letra es un fallo, que la letra se encuentre una o varias veces en la palabra, y en los lugares donde irian las letras en las casillas haya huecos vacios, por lo que habria uno o mas aciertos e inmediatamente los huecos vacios se reemplacen por la letra acertada, o bien la letra se encuentre una o varias veces en la palabra y en las casillas los huecos de las posiviones coincidentes ya se hayan rellenado, por lo que la letra es repetida. Esta situacion última yo la marco haciendl que el numero de aciertos sea -1 para despues mostrar el mensaje correspondiente y tomar la acción asociada, que es restar una vida. En los mensajes del turno de juego, la pista es precisamente la palabra guiones que poco a pocl se iria rellenando con las letras, como lo harias en el juego de papel. El juego termina cuando las vidas se agotan o cuando las casillas contienen la misma palabra que la palabra secreta (puedes usar la funcion stricmp para averiguarlo).

PD: El programa lo hice a correprisa así que se puede mejorar muchísimo y reducir el codigo a la mitad o menos, añadiendo mas funciones.

PD2: Usa los bucles while, solo los necesarios. Aprovecha la potencia del bucle for, acostumbrate a el y tu programación sera mas sencilla y potente.
Imágenes Adjuntas
Tipo de Archivo: jpg Screenshot_2016-10-11-01-19-55.jpg (57,7 KB (Kilobytes), 33 visitas)
Respuesta
¿Tienes una mejor respuesta a este tema? ¿Quieres hacerle una pregunta a nuestra comunidad y sus expertos? Registrate

Foros de Electrónica » Diseño digital » Microcontroladores y sistemas embebidos

Powered by vBulletin® Version 3.8.4
Copyright ©2000 - 2016, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO ©2011, Crawlability, Inc.