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 :oops:

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;
}
 
Última edición por un moderador:
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.
 
Última edición:
Primer error:
Código:
scanf("%s",[B][COLOR=Red]&[/COLOR][/B]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 ( [B][COLOR=Red](char)[/COLOR][/B]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("[B][COLOR=Red]%c[/COLOR][/B]", (char)ing );
o más fácil:
Código:
putchar( (char)ing );
y sumá lo de palurdo...

Lo sé :cry: pero voy a mejorarlo en después :D
La típica mentira del informático...
 
Última edición:
Prueba cambiar "&palabra" a "palabra", el & no se usa cuando es array, &var significa "dirección de var", pero en un array 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.
 
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);
}
 
Última edición:
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!='\0')
{

if(cadena=='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
 
gets(cadena); // espera la cadena hasta que pisas enter.

gets deberia estar prohibida. Se debería usar siempre fgets, precisamente para evitar...

exploits_of_a_mom.png


...el temido buffer overrun/overflow.
 
Última edición:
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 :)
 
Última edición:
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?
 
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++
 
Última edición:
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.
 
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.
 
Última edición:
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();
 
¡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);
        [COLOR=Red]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++;}[/COLOR]
        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.
 
Última edición por un moderador:
Es decir, tu buscas algo similar a esto pero con guiones:

Screenshot_2016-10-11-01-19-55.jpg

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.
 
Buenas, tengo un trabajo de la universidad en el que tengo que hacer un código en C que consiste en el juego del ahorcado. Como estoy empezando en la universidad me piden que lo haga con herramientas muy sencillas. Lo he empezado pero no he podido terminarlo. Por eso pido ayuda.

En el código se utiliza un fichero donde se encuentran las palabras para adivinar.
Dejo por aquí el código hasta donde he podido llegar:

(Tambien podria utilizar la libreria <stdbool.h> pero no tengo idea de como introducirla).

C:
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
int main ()
{
    FILE *fitxer;
    int nContador, num, i, x, intents;
    char paraula[10], lletra[2];
    nContador=0;
    fitxer= fopen ("paraules.txt", "r");
    if (fitxer== NULL)
        printf ("No es pot obrir el fitxer %s \n", "paraules,txt");
    else
    {
        while (fscanf(fitxer,"%s", paraula) != -1)
        {
            nContador++;
        }
    printf ("\nNumero de paraules = %d \n", nContador);
    fclose(fitxer);
    }



    srand (time(NULL));
    num = rand ()% nContador;
    printf ("%d\n", num);
    i=0;
    fitxer= fopen ("paraules.txt", "r");
    while (i<num)
    {
        fscanf(fitxer,"%s", paraula);
        i++;
    }
    printf("%s\n", paraula);


    intents = 10;
    while (intents != 0)
    {
        scanf ("%c", &lletra[1]);
        x = 0;
        while (paraula[x] != '\0')
            {
                if (lletra[1] == paraula[x])
                {
                    printf ("%c", lletra[1]);
                }
                else
                {
                    printf ("_ ");
                }
             x++;
            }
        intents = intents -1;
    }

    fclose (fitxer);
}
 
Atrás
Arriba