您的位置:首页 > 编程语言 > C语言/C++

吊死鬼游戏Hangman游戏的C语言实现代码

2009-12-03 00:36 931 查看
游戏特色
有三种难度等级可供选择,分别挖空1、2、3个单词位置。

内置有10个单词,猜词时会随机抽取一个单词,并随机决定挖空哪个位置,使游戏更具趣味性。

用户可以自己添加想猜的单词(10个以内均可)。

用户猜错后会给出正确答案

解题思路
要显示单词,而且要用户在指定位置输入字母,故应用到一个函数,可以将光标定位到单词被挖空的位置等待用户输入。我构建了一个gotoxy()函数,是基于网上找到得一个源代码稍加修改而得到的。调用时只需将坐标传递给gotoxy()即可将光标跳到指定坐标。
在输入字母、打印吊死鬼图案时,将多次用到定位光标的函数。

由于游戏可能进行多次,所以清屏函数system("CLS")的使用时非常必要的。可将上一次游戏进行的内容全部清空重新开始新一轮游戏。

为了增加趣味性,游戏允许用户自己添加单词用于猜词。

故我构建了一个函数,先把原先存储单词的字符串数组元素全部赋值为'/0',防止用户输入的单词没有原先字符串中以存储的单词长而导致猜词时输出的单词不伦不类(合成词?~_~)。
然后设置循环,依次给10个字符串数组赋值,并通过string.h下的strlen()函数判断,如果输入单词过短则提示用户重新输入,如果只按回车键,那么将跳出函数,返回主函数开始猜词。
由于设置了3个难度,故每个难度都构建了一个函数,这三个函数算法基本类同。

以难度2为例:首先生成一个0~9的随机数,并通过switch()函数,根据生成的随机数判断本次游戏要猜的单词(w0~w9),并用一个指针指向该单词;
第二步是将存有该单词的字符串数组复制给另一个数组,用于猜词;
第三步,产生两个随机数并确保它们不相等,随机数最大为单词的长度,这两个随机数将决定单词被挖空的字母位置,即将数组相应位置的元素赋值为下划线;
下一步则要输出绞刑架图案和已被挖空两个字母的单词,并将光标定位在第一个空位上;
待用户输入一个字母后,判断该字符是否与正确字符相等(这就是将字符串数组复制的原因) 若相同,则跳到下一出空位继续等待输入,若不相同,则提示错误,并在绞刑架图案上一次输出头、躯干、胳膊等等。
当用户全部输入正确(输错次数在7次以内)时,恭喜玩家成功猜出单词,并邀请玩家再玩一次。
当输错7次(用循环计数器实现)后,提示玩家失败,并将正确答案提示玩家,邀请玩家再玩一次。

源代码(C语言)
#include<stdio.h>

#include<stdlib.h>

#include<math.h>

#include<string.h>

#include <windows.h>

#define MAX 17             //最长单词的长度

 
int gotoxy(int,int);

int level1();

int level2();

int level3();

int addnew();

    char w0[]="christian";

    char w1[]="programming";

    char w2[]="network";

    char w3[]="project";

    char w4[]="environment";

    char w5[]="freedom";

    char w6[]="protection";

    char w7[]="firewall";

    char w8[]="paradise";

    char w9[]="carrot";

    

int main()

{

 
    char difflv;

    printf("Difficulty Level(1~3, 0 to Quit, 4 to Add New Words): ");

    while((difflv=getchar()) !='0')

    {

        switch(difflv)

        {

            case '1':system("CLS");level1();break;

            case '2':system("CLS");level2();break;

            case '3':system("CLS");level3();break;

            case '4':addnew();fflush(stdin);

                        printf("Difficulty Level(1~3, 0 to Quit, 4 to Add New Words): ");

                        continue;

            default:

                        printf("Wrong Input!/n");

                        printf("Difficulty Level(1~3, 0 to Quit, 4 to Add New Words): ");

                        fflush(stdin);

                        continue;

        }    //switch OVER

        gotoxy(11,0); //转到第11行

        printf("Difficulty Level(1~3, 0 to Quit, 4 to Add New Words): ");

        fflush(stdin);

    }    //while OVER

    return 0;

}    //main OVER

 

 

 
//============================================================================================

 

 

 
int gotoxy(int x,int y)        //定位光标的位置 ,超级实用!

{

COORD coord;

coord.X=y;                //位置调换,调用函数是第一个参数是行,第二个参数是列

coord.Y=x;

SetConsoleCursorPosition( GetStdHandle( STD_OUTPUT_HANDLE ), coord );

return 0;

}

 

 

 
//===============================================================================================

 

 

 
int addnew()

{

    char j,i;//计数器

    char word[MAX]="a";

    

    fflush(stdin);

    printf("Please Input New Words(Press ENTER to return):/n");

    for(j=0;j<10 && strlen(word)!=0;j++)

    {

        gets(word);

        if(strlen(word)==0)return 0;

        else if(strlen(word)<4){printf("Too Short!/n");j--;continue;}

        else

        switch(j)

        {

            case 0:

                    for(i=0;w0[i]!='/0';i++)w0[i]='/0';

                    for(i=0;word[i]!='/0';i++)w0[i]=word[i];w0[i]='/0';break;

            case 1:

                    for(i=0;w1[i]!='/0';i++)w1[i]='/0';

                    for(i=0;word[i]!='/0';i++)w1[i]=word[i];w0[i]='/0';break;

            case 2:

                    for(i=0;w2[i]!='/0';i++)w2[i]='/0';

                    for(i=0;word[i]!='/0';i++)w2[i]=word[i];w0[i]='/0';break;

            case 3:

                    for(i=0;w3[i]!='/0';i++)w3[i]='/0';

                    for(i=0;word[i]!='/0';i++)w3[i]=word[i];w0[i]='/0';break;

            case 4:

                    for(i=0;w4[i]!='/0';i++)w4[i]='/0';

                    for(i=0;word[i]!='/0';i++)w4[i]=word[i];w0[i]='/0';break;

            case 5:

                    for(i=0;w5[i]!='/0';i++)w5[i]='/0';

                    for(i=0;word[i]!='/0';i++)w5[i]=word[i];w0[i]='/0';break;

            case 6:

                    for(i=0;w6[i]!='/0';i++)w6[i]='/0';

                    for(i=0;word[i]!='/0';i++)w6[i]=word[i];w0[i]='/0';break;

            case 7:

                    for(i=0;w7[i]!='/0';i++)w7[i]='/0';

                    for(i=0;word[i]!='/0';i++)w7[i]=word[i];w0[i]='/0';break;

            case 8:

                    for(i=0;w8[i]!='/0';i++)w8[i]='/0';

                    for(i=0;word[i]!='/0';i++)w8[i]=word[i];w0[i]='/0';break;

            case 9:

                    for(i=0;w9[i]!='/0';i++)w9[i]='/0';

                    for(i=0;word[i]!='/0';i++)w9[i]=word[i];w0[i]='/0';break;

        }//switch OVER

    }//for OVER

    return 0;

}

 

 

 

 
//============================================================================================

 

 

 
int level1()            //难度1

{

    char n;                //n为赋值计数器兼单词挖空位置

    char *p,word[MAX];

    char c,i;            //c为待输入字符,i为循环计数器

    

    srand(time(NULL));

    n = rand()%10;

    switch(n)            //随机选取一个单词

    {

        case 0:p = w0;break;

        case 1:p = w1;break;

        case 2:p = w2;break;

        case 3:p = w3;break;

        case 4:p = w4;break;

        case 5:p = w5;break;

        case 6:p = w6;break;

        case 7:p = w7;break;

        case 8:p = w8;break;

        case 9:p = w9;break;

    }        //switch OVER

    for(n=0;p
!='/0';n++)                                //注意此处!!!!指针亦可以用数组形式表示!!!!!

        word
= p
;                                //注意此处!!!!指针亦可以用数组形式表示!!!!!

        word
= '/0';

    n = rand()%n;             //随机选择一个位置替换为下划线

    word
= '_';         //下划线

    printf(" _________/n");

    printf(" | |/n");

    printf(" |/n");

    printf(" |/n");

    printf(" |/n");

    printf(" |/n");

    printf(" |/n");

    printf(" =========/n");

    

    printf("Input the correct letter you think and press ENTER:/n");

    puts(word);

    

    for(i=7;i>0;i--)

    {

        fflush(stdin);            //清除缓存,不然即使输入正确也会显示错误,需要输入两回才会输出正确提示

        gotoxy(9,n);

        if((c = getchar()) == p
)                                    //注意此处!!!!指针亦可以用数组形式表示!!!!!

        {

            gotoxy(9,0);

        puts(p);

            gotoxy(10,0);

            printf("Hooray! You Win! Why Not Play Again?/n");

            break;

        }

        else

        {

            word
= '_';        //重新赋值为下划线

            gotoxy(9,0);

            puts(word);

            printf("Wrong Answer!/n%d Chance Left...",i-1);

            switch(i)

            {

                case 7:gotoxy(2,9);printf("O");break;

                case 6:gotoxy(3,9);printf("|");break;

                case 5:gotoxy(3,8);printf("/");break;

                case 4:gotoxy(3,10);printf("//");break;

                case 3:gotoxy(4,9);printf("|");break;

                case 2:gotoxy(5,8);printf("/");break;

                case 1:gotoxy(5,10);printf("//");

                     gotoxy(10,0);printf("You Lose...Correct Word: %s Try Again?",p);

                         break;

            }    //switch OVER

        }    //if-else OVER

    }    //for OVER

    return 0;

}

 

 

 

 
//============================================================================================

 

 

 

 
int level2()

{

    char n,n1,n2;                //n为赋值计数器兼单词挖空位置

    char *p,word[MAX];

    char c,i;                //c为待输入字符,i为循环计数器

    

    srand(time(NULL));

    n = rand()%10;

    switch(n)            //随机选取一个单词

    {

        case 0:p = w0;break;        //如果直接定义一个数组,而不是指针,编译器会提出警告,而且程序运行也会出错

        case 1:p = w1;break;        //伟大的经验啊,定义指针,把数组名赋值给它,该指针就可以用作数组啦!爽!

        case 2:p = w2;break;

        case 3:p = w3;break;

        case 4:p = w4;break;

        case 5:p = w5;break;

        case 6:p = w6;break;

        case 7:p = w7;break;

        case 8:p = w8;break;

        case 9:p = w9;break;

    }        //switch OVER

    for(n=0;p
!='/0';n++)            

        word
= p
;    

        word
= '/0';            

    n1 = rand()%n;             //随机选择一个位置替换为下划线 此处不能用%=: n%=i等价于n=n%i

    word[n1] = '_';         //下划线

    do

    {

        n2 = rand()%n;

    }while(n2 == n1);    //确保n2!=n1

    word[n2] = '_';

    if(n2<n1)

    {

        n=n1;n1=n2;n2=n; //确保先输入第一个字母

    }

    

    printf(" _________/n");

    printf(" | |/n");

    printf(" |/n");

    printf(" |/n");

    printf(" |/n");

    printf(" |/n");

    printf(" |/n");

    printf(" =========/n");

    

    printf("Input the correct letter you think and press ENTER:/n");

    puts(word);

    for(i=7;i>0;i--)

    {

        fflush(stdin);            //清除缓存,不然即使输入正确也会显示错误,需要输入两回才会输出正确提示

        gotoxy(9,n1);

        if((c = getchar()) == p[n1])

        {

            word[n1]=p[n1];

            gotoxy(9,0);

            puts(word);

            //gotoxy(10,0);

            printf("Well Done! Try The Other Letter!");

            for(;i>0;i--)

            {

                gotoxy(9,n2);

                fflush(stdin);

                if((c = getchar()) == p[n2])

                {

                    gotoxy(9,0);

                    puts(p);

                    //gotoxy(10,0);

                    printf("Hooray! You Win! Why Not Play Again?/n");

                    break;

                }//2nd if OVER

                else

                {

                    word[n2]='_';

                    gotoxy(9,0);

                 puts(word);

                    printf("Wrong Answer! /n%d Chance Left...",i-1);

                    switch(i)

                    {

                    case 7:gotoxy(2,9);printf("O");break;

                    case 6:gotoxy(3,9);printf("|");break;

                    case 5:gotoxy(3,8);printf("/");break;

                    case 4:gotoxy(3,10);printf("//");break;

                    case 3:gotoxy(4,9);printf("|");break;

                    case 2:gotoxy(5,8);printf("/");break;

                    case 1:gotoxy(5,10);printf("//");

                         gotoxy(10,0);printf("You Lose...Correct Word: %s Try Again?",p);

                             break;

                    }    //switch OVER

                } //2nd else OVER

            }break;//2nd for OVER

        }    //1st if OVER

        else

        {

            word[n1] = '_';        //重新赋值为下划线

            gotoxy(9,0);

            puts(word);

            printf("Wrong Answer! /n%d Chance Left...",i-1);

            switch(i)

            {

                case 7:gotoxy(2,9);printf("O");break;

                case 6:gotoxy(3,9);printf("|");break;

                case 5:gotoxy(3,8);printf("/");break;

                case 4:gotoxy(3,10);printf("//");break;

                case 3:gotoxy(4,9);printf("|");break;

                case 2:gotoxy(5,8);printf("/");break;

                case 1:gotoxy(5,10);printf("//");

                     gotoxy(10,0);printf("You Lose...Correct Word: %s Try Again?",p);

                         break;

            }    //switch OVER

        }    //1st else OVER

    }    //for OVER

    return 0;

}

 

 

 

 
//============================================================================================

 

 

 

 
int level3()

{

    char n,n1,n2,n3;                //n为赋值计数器兼单词挖空位置

    char *p,word[MAX];

    char c,i;                //c为待输入字符,i为循环计数器

    

    srand(time(NULL));

    n = rand()%10;

    switch(n)            //随机选取一个单词

    {

        case 0:p = w0;break;        //如果直接定义一个数组,而不是指针,编译器会提出警告,而且程序运行也会出错

        case 1:p = w1;break;        //伟大的经验啊,定义指针,把数组名赋值给它,该指针就可以用作数组啦!爽!

        case 2:p = w2;break;

        case 3:p = w3;break;

        case 4:p = w4;break;

        case 5:p = w5;break;

        case 6:p = w6;break;

        case 7:p = w7;break;

        case 8:p = w8;break;

        case 9:p = w9;break;

    }        //switch OVER

    for(n=0;p
!='/0';n++)            

    word
= p
;

    word
= '/0';                

    n1 = rand()%n;             //随机选择一个位置替换为下划线 此处不能用%=: n%=i等价于n=n%i

    word[n1] = '_';         //下划线

    do

        n2 = rand()%n;

        while(n2 == n1);    //确保n2!=n1

    word[n2] = '_';

    do

        n3 = rand()%n;

        while(n3 == n1 || n3 == n2);

    word[n3] = '_';

    if(n1>n2)

    {    n=n1;n1=n2;n2=n;} //确保先输入第一个字母

    if(n1>n3)

    {    n=n1;n1=n3;n3=n;}

    if(n2>n3)

    {    n=n2;n2=n3;n3=n;}

    

    printf(" _________/n");

    printf(" | |/n");

    printf(" |/n");

    printf(" |/n");

    printf(" |/n");

    printf(" |/n");

    printf(" |/n");

    printf(" =========/n");//打印原始图案

    

    printf("Input the correct letter you think and press ENTER:/n");

    puts(word);

    for(i=7;i>0;i--)

    {

        fflush(stdin);            //清除缓存,不然即使输入正确也会显示错误,需要输入两回才会输出正确提示

        gotoxy(9,n1);

        if((c = getchar()) == p[n1])

        {

            word[n1]=p[n1];    

            gotoxy(9,0);

            puts(word);

            //gotoxy(10,0);

            printf("Well Done! Try The Other Letter!");

            for(;i>0;i--)

            {

                gotoxy(9,n2);

                fflush(stdin);

                if((c=getchar()) == p[n2])

                {

                    word[n2]=p[n2];

                    gotoxy(9,0);

                    puts(word);

                    //gotoxy(10,0);

                    printf("Well Done! Try The Other Letter!");

                    for(;i>0;i--)

                    {

                        gotoxy(9,n3);

                        fflush(stdin);

                        if((c=getchar()) == p[n3])

                        {

                            gotoxy(9,0);

                            puts(p);

                            //gotoxy(10,0);

                            printf("Hooray! You Win! Why Not Play Again?");

                            break;

                        }//3rd if OVER

                        else

                        {

                            word[n3]='_';

                            gotoxy(9,0);

                            puts(word);

                            printf("Wrong Answer! /n%d Chance Left...",i-1);

                            switch(i)

                            {

                            case 7:gotoxy(2,9);printf("O");break;

                            case 6:gotoxy(3,9);printf("|");break;

                            case 5:gotoxy(3,8);printf("/");break;

                            case 4:gotoxy(3,10);printf("//");break;

                            case 3:gotoxy(4,9);printf("|");break;

                            case 2:gotoxy(5,8);printf("/");break;

                            case 1:gotoxy(5,10);printf("//");

                                  gotoxy(10,0);printf("You Lose...Correct Word: %s Try Again?",p);

                                     break;

                            }    //switch OVER

                        } //3rd else OVER

                    }break;//3rd for OVER

                }//2nd if OVER

                else

                {

                    word[n2]='_';

                    gotoxy(9,0);

                    puts(word);

                    printf("Wrong Answer! /n%d Chance Left...",i-1);

                    switch(i)

                    {

                    case 7:gotoxy(2,9);printf("O");break;

                    case 6:gotoxy(3,9);printf("|");break;

                    case 5:gotoxy(3,8);printf("/");break;

                    case 4:gotoxy(3,10);printf("//");break;

                    case 3:gotoxy(4,9);printf("|");break;

                    case 2:gotoxy(5,8);printf("/");break;

                    case 1:gotoxy(5,10);printf("//");

                         gotoxy(10,0);printf("You Lose...Correct Word: %s Try Again?",p);

                             break;

                    }    //switch OVER

                } //2nd else OVER

            }break;//2nd for OVER

        }    //1st if OVER

        else

        {

            word[n1] = '_';        //重新赋值为下划线

            gotoxy(9,0);

            puts(word);

            printf("Wrong Answer! /n%d Chance Left...",i-1);

            switch(i)

            {

                case 7:gotoxy(2,9);printf("O");break;

                case 6:gotoxy(3,9);printf("|");break;

                case 5:gotoxy(3,8);printf("/");break;

                case 4:gotoxy(3,10);printf("//");break;

                case 3:gotoxy(4,9);printf("|");break;

                case 2:gotoxy(5,8);printf("/");break;

                case 1:gotoxy(5,10);printf("//");

                     gotoxy(10,0);printf("You Lose...Correct Word: %s Try Again?",p);

                         break;

            }    //switch OVER

        }    //1st else OVER

    }    //for OVER

    return 0;

}

截图:
等待用户输入,1~3三个难度等级,按0退出游戏,按4添加单词。





添加新单词。输入单词后回车即添加成功,再按回车返回游戏。



选择难度等级并进行游戏。









单词全部猜错,已经完全输出吊死鬼的图案。



继续进行下一次游戏













游戏成功!嘿嘿嘿嘿~~~~~~~~~~~~~~~~~~
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: