Nhờ giúp đỡ vấn đề trong chương trình người treo cổ viết bằng C

Chào các bạn, mình đang học c theo 1 tài liệu trên diễn đàn , và đang học tới phần cuối của tài liệu đó là viết chương trình người treo cổ .
Ok, mình có 2 vấn đề như thế này, mong các bạn giải đáp

1 ví dụ bây giờ mình muốn đưa ra một gợi ý là từ bí mật cần đoán có số lượng bao nhiêu ký tự và hiển thị sẳn một ký tự để cho người chơi đoán thì nên làm như thế nào ? mình nghĩ mãi mà không ra cách , mong các bạn hướng dẫn giúp mình
2 Trong tài liệu có nói thêm là thêm vào mục hỏi người chơi có muốn tiếp tục không , mình đã thử dùng vòng lặp bao quát toàn bộ chương trình , rồi thử dùng lệnh goto, continue … mà vẫn gặp phải lỗi , mình sẽ nêu ngay ở dưới.
Ok sau đây là toàn bộ cấu trúc code
file main.c
và mình gặp vấn đề ngay tại đây, ví dụ bây giờ khi mình đoán ra được từ bí mật , mình ấn phím 1 hoặc 0 thì chương trình vẫn hoạt động tốt, chương trình vẫn quay ngược lên đầu vòng lặp, nhưng khi mình cố tình nhập hết lượt để thua, thì khi mình nhấn phím 1 chương trình chỉ hiện ra dòng printf("\n-----Welcome To The Hangman Game--------\n"); và phần lệnh trong else, và cứ thế tiếp tục cho tới khi mình nhấn 0 để thoát chương trình, đó là vấn đề mình đang gặp phải, mong các bạn giúp đỡ giải đáp.

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include "danhmuc2.h"

char docKytu();
int win(int[],long);
int kiem_tra_ky_tu(char,char[],int[]);

int main()
{
    char ky_tu = 0; //biến này lưu trữ ký tự;
    char ky_tu_bi_mat[100] = {0}; //từ cần đoán
    int *so_ky_tu_bi_mat = NULL; // 1 mảng dạng boolean, mỗi ô tương ứng với 1 ký tự đc đoán, đúng trả về 1, sai trả về 0
    int so_lan_doan = 10; // số lượt
    int i = 0; //biến hỗ trợ
    long do_dai_tu = 0; //lưu giá trị thể hiện độ dài cùa từ
    int tiep_tuc_game;

     while(tiep_tuc_game == 1 || tiep_tuc_game !=0)
     {
        if(!chon_tu(ky_tu_bi_mat))
        exit(0);
        do_dai_tu = strlen(ky_tu_bi_mat);
        so_ky_tu_bi_mat = malloc(do_dai_tu*sizeof(int)); // cấp phát bộ nhớ
        if(so_ky_tu_bi_mat == NULL)
        exit(0);
     for(i = 0;i<do_dai_tu;i++)
        so_ky_tu_bi_mat[i] = 0;

     printf("\n-----Welcome To The Hangman Game--------\n");
     while(so_lan_doan>0 &&!win(so_ky_tu_bi_mat,do_dai_tu))
    {
        printf("\nBan %d luot doan",so_lan_doan);
        for(i = 0;i<do_dai_tu;i++)
        {
            if(so_ky_tu_bi_mat[i]) //nếu người chơi tìm thấy ký tự i
            printf("%c",ky_tu_bi_mat[i]); // hiển thị ký tự
            else
            printf("*");
        }
         printf("\ntu bi mat la gi?\n");
        printf("\nmoi ban nhap vao ky tu bi mat\n");
        ky_tu = docKytu();

        if(!kiem_tra_ky_tu(ky_tu,ky_tu_bi_mat,so_ky_tu_bi_mat))
        {
            so_lan_doan--;
        }
    }

    if(win(so_ky_tu_bi_mat,do_dai_tu))
    {
       printf("\n\nXin chuc mung, ban da thang, tu bi mat la %s",ky_tu_bi_mat);
    }
    else
    {
        printf("\n\nXin chia buon, ban da thua, tu bi mat la %s\n",ky_tu_bi_mat);
    }
    free(so_ky_tu_bi_mat);

    printf("\n\nBan co muon tiep tuc :D\n");
    printf("\nAn 1 de tiep tuc: ");
    printf("\nAn 0 de dung lai: ");
    scanf("%d",&tiep_tuc_game);
    }
  return 0;

}
char docKytu()
{
   char ky_tu_nhap_vao = 0;
   ky_tu_nhap_vao = getchar(); //đọc ký tự được nhập vào đầu tiên
   ky_tu_nhap_vao = toupper(ky_tu_nhap_vao); //viet hoa ký tự

   //lần lượt đọc từng ký tự cho đến khi xuống dòng
   while(getchar()!='\n');
   return ky_tu_nhap_vao; //trả về ký tự đọc được
}
int win(int so_ky_tu_bi_mat[],long do_dai_tu)
{
    int i = 0;
    int nguoi_choi_win = 1;
    for(int i = 0;i<do_dai_tu;i++)
    {
        if(so_ky_tu_bi_mat[i]==0)
           nguoi_choi_win = 0;
    }
    return nguoi_choi_win;
}
int kiem_tra_ky_tu(char ky_tu, char ky_tu_bi_mat[],int so_ky_tu_bi_mat[])
{
    int i = 0;
    int ky_tu_chinh_xac = 0;
    for(i = 0;ky_tu_bi_mat[i]!='\0';i++)
    {
        if(ky_tu == ky_tu_bi_mat[i])//nếu ký tự có chứa trong mảng ký tự bí mật
        {
            ky_tu_chinh_xac = 1; //ký tự sẽ đc lưu lại thể hiện nó là ký tự chính xác
            so_ky_tu_bi_mat[i] = 1; //Gửi giá trị 1 vào ô tương ứng với vị trí của ký tự đó trong mảng
        }
    }
    return ky_tu_chinh_xac;
}

còn đây là cấu trúc code filedanhmuc.c

#include <stdlib.h>
#include <time.h>
#include <string.h>
#include "danhmuc.h"
 
int chon_tu(char *tu_duoc_chon)
{
    FILE *danhmuc = NULL;
    int stt_cua_ky_tu = 0, stt_cua_ky_tu_duoc_chon = 0, i = 0;
    int save_ky_tu = 0;
    danhmuc = fopen("danhmuc.txt","r"); //tạo tập tin với mode read-only
    if(danhmuc == NULL)
    {
        printf("\nFile chua duoc tao\n");
        return 0; //trả về 0 nếu mở thất bại, kết thúc hàm
    }
    do
    {
        save_ky_tu = fgetc(danhmuc);
        if(save_ky_tu == '\n')
            stt_cua_ky_tu++;
    }while(save_ky_tu!=EOF);
    stt_cua_ky_tu_duoc_chon = tu_ngau_nhien(stt_cua_ky_tu); // hàm này chọn 1 từ ngẫu nhiên
    rewind(danhmuc);
    // chương trình đọc từ đầu và ngừng lại khi tìm thấy từ được chọn
    while(stt_cua_ky_tu_duoc_chon>0)
    {
        save_ky_tu = fgetc(danhmuc);
        if(save_ky_tu == '\n')
            stt_cua_ky_tu_duoc_chon--;
    }
    fgets(tu_duoc_chon,100,danhmuc);
    tu_duoc_chon[strlen(tu_duoc_chon)-1] = '\0';
    fclose(danhmuc);
    return 1;
}
int tu_ngau_nhien(int stt_max)
{
    srand(time(NULL));
    return (rand()%stt_max);
}

cấu trúc file danhmuc.h

#ifndef DEF_DANHMUC // nếu const này chưa được xác định , file này chưa được tạo
#define DEF_DANHMUC // Ta xác định const để lần sau file sẽ không đưa vào nữa
 
int chon_tu(char *tu_duoc_chon);
int tu_ngau_nhien(int stt_max);
 
#endif // DEF_DANHMUC

Nội dung file danhmuc.txt đây là file chứa các từ bí mật

LOVE
MONEY
PROGRAM
FUNCTION
POINTER
LOOP
INSTRUCTION
STRING
VARIABLE
CONSTANT
DEFINE

về code thì không có gì sai cả, chỉ là nó gặp phải một số vấn đề trên thôi, rất mong được giúp đỡ, xin cảm ơn :smiley:

1 Like

Hi Hoài Nam Trương.
1 Để sửa lỗi bạn dùng công cụ bắt bọ để theo dõ xem chuyện gì sảy ra.
2 Không nên dùng goto.

P/S Bạn nên xem qua về kiến trúc của chương trình game.

1 Like

là debug phải không bạn ?

1 Like

Hi Hoài Nam Trương.
Không là BẮT BỌ

nghĩa là sao bạn ? :sweat_smile: bắt bọ nghĩa là gì .

Cái ông @Phong_Ky_Vo cứ loanh quanh mãi :smile: chung quy lại vẫn là debug code và tránh dùng goto thôi :v

ths bác, bác trên nói bắt bọ làm mình cứ tưởng là gì không :sweat_smile:

Hi Hoài Nam Trương.
BẮT BỌ

  1. Code đặt tên Anh Việt lẫn lộn.
  2. Đặt tên theo kiểu lạc đà + rắn.
  3. Thụt thụt thò thò không có hàng lối gì cả.
  4. so_ky_tu_bi_mat = malloc(do_dai_tu*sizeof(int)); // Số ký tự sao lại là một mảng nhỉ ?
  5. Cái if thì có ngoặc cái thì không.
if(so_ky_tu_bi_mat[i]) //nếu người chơi tìm thấy ký tự i
            printf("%c",ky_tu_bi_mat[i]); // hiển thị ký tự
            else
            printf("*");

if(!kiem_tra_ky_tu(ky_tu,ky_tu_bi_mat,so_ky_tu_bi_mat))
        {
            so_lan_doan--;
        }
1 Like

Cái này là rộng hơn bắt bọ rồi. Nói đúng hơn, đây là vấn đề phẫu thuật thẩm mỹ code.

1 Like

Mình cũng đến “Muốn treo cổ” luôn rồi. Code mình cũng không khác gì của bạn. Nhưng chữ cái mà mình đoán đầu tiên nó luôn luôn sai dù là chữ đó có trong từ bí mật, khi đoán chữ đó lần thứ hai thì nó mới được. Của mình bị vấn đề là lần đoán đầu tiên nó luôn luôn sai, kể từ lần đoán thứ hai thì tất cả bình thường. Vậy có bạn nào chỉ cho mình với…!!

Up code lên bạn ơi. Bạn cứ nói thế này suông thì không ai biết bạn sai ở đâu cả.

1 Like

giống y chang trên kia luôn, khác mỗi cách đặt tên biến số thoi

Bạn up cả đống code thế này, thực sự mình sống không nổi :sweat:

Thiếu &

Vòng for sai 1 điều kiện, phải là < doDaiTuBM. Và không chỉ có 1 chỗ sai như thế này:

Nếu đây là dòng bạn khởi tạo từ bí mật thì hãy đưa nó ra ngoài vòng while do.

Mình chịu code của bạn thôi.

Rất cảm ơn ý kiến của bạn!
scanf("%s",&datTuBM); nếu thêm & thì có lỗi ngay tại bước đó.
Hai ý của bạn về khai báo và vòng lặp for thì đúng rồi
Nhưng vấn đề của mình như đã nói ngay từ đầu thì vẫn chưa thể giải quyết được.
Bạn hãy xem

    Che do choi 1 nguoi hay 2 nguoi?
    2
    Nguoi choi thu nhat hay dat tu bi mat...
    nguyen
    Nguoi choi thu hai hay giai tu bi mat...

     Ban co 10 luot doan de choi
     Tu bi mat la gi?  Hay chon tu  ******---------e

     Ban co 9 luot doan de choi
     Tu bi mat la gi?  Hay chon tu  ******---------e

     Ban co 9 luot doan de choi
     Tu bi mat la gi?  Hay chon tu  ****E*---------n

     Ban co 9 luot doan de choi
     Tu bi mat la gi?  Hay chon tu  N***EN---------g

     Ban co 9 luot doan de choi
     Tu bi mat la gi?  Hay chon tu  NG**EN---------u

     Ban co 9 luot doan de choi
     Tu bi mat la gi?  Hay chon tu  NGU*EN---------yyy
        Ban da chien thang     NGUYEN
    Co choi lai phan nay 0?
    1
    Nguoi choi thu nhat hay dat tu bi mat...
    nhh
    Nguoi choi thu hai hay giai tu bi mat...

     Ban co 10 luot doan de choi
     Tu bi mat la gi?  Hay chon tu  ***---------f

     Ban co 9 luot doan de choi
     Tu bi mat la gi?  Hay chon tu  ***---------h

     Ban co 9 luot doan de choi
     Tu bi mat la gi?  Hay chon tu  *HH---------n
        Ban da chien thang     NHHY
    Co choi lai phan nay 0?
    0
    Chon 0 de ket thuc/ Choi tiep chon so bat ki..2
    Che do choi 1 nguoi hay 2 nguoi?
    1


     Ban co 10 luot doan de choi
     Tu bi mat la gi?  Hay chon tu  ***********---------i


     Ban co 9 luot doan de choi
     Tu bi mat la gi?  Hay chon tu  ***********---------i


     Ban co 9 luot doan de choi
     Tu bi mat la gi?  Hay chon tu  I*******I**---------n


     Ban co 9 luot doan de choi
     Tu bi mat la gi?  Hay chon tu  IN******I*N---------t


     Ban co 9 luot doan de choi
     Tu bi mat la gi?  Hay chon tu  IN*T***TI*N---------r


     Ban co 9 luot doan de choi
     Tu bi mat la gi?  Hay chon tu  IN*TR**TI*N---------u


     Ban co 9 luot doan de choi
     Tu bi mat la gi?  Hay chon tu  IN*TRU*TI*N---------c


     Ban co 9 luot doan de choi
     Tu bi mat la gi?  Hay chon tu  IN*TRUCTI*N---------s


     Ban co 9 luot doan de choi
     Tu bi mat la gi?  Hay chon tu  INSTRUCTI*N---------o
        Ban da chien thang     INSTRUCTION
    Co choi lai phan nay 0?
    1


     Ban co 10 luot doan de choi
     Tu bi mat la gi?  Hay chon tu  ********---------

scanf không có & mới là có lỗi. Còn có mà sinh lỗi thì do datTuBM của bạn không phải là string.

1 Like

vậy mình khai báo thế này đúng không v??

Ok rồi. Dòng 77 của bạn chỉ bị warning thôi. Bạn có thể google để xem kĩ hơn nguyên nhân tại sao bị warning.

1 Like

Ủa dòng 77 phải bỏ dấu & đi khi scanf chứ nhỉ?

1 Like

scanf mà bỏ & thì gọi éo gì là scanf nữa @@
warning ở kiểu dữ liệu (argument 2) cơ mà :v

theo em nhớ nếu như char kiểu đó thì & là char, còn không có & là char *. Tại nếu mà & là nó chỉ nạp vô cái chữ cái đầu tiên thôi, còn bỏ là nạp hết, đây là %s

83% thành viên diễn đàn không hỏi bài tập, còn bạn thì sao?