c语言制作一个简单的打字游戏(落下一个字母按相应字母消去,记录分数)

c语言制作一个简单的打字游戏(落下一个字母按相应字母消去,记录分数),第1张

游戏常量参数自行修改(字母的列数,下落最大高度,下落速度等)。

程序功能:(随机生成字母,下落,并检查按键,计分)

多线程按键检查采用新的线程与主线程同步。

独立速度:每个字母下落速度都是随机且不相同。

玩法:按键区分大小写,落到底部或被玩家按中,下落中的字母就会消失,并在该梁粗列顶部创建新的字母下落,按中1次记1分。

注意:由于字母都是随机的,如果同时下落的字母很多,可能会有重复字母出现,如果按键对应了多个同样的字母,这些字母会删掉并新建,也就是说出现按中一次记多分,说明有多个重复字母,不是BUG!

#include <stdio.h>

#include <stdlib.h>

#include <malloc.h>

#include <conio.h>

#include <time.h>

#include <windows.h>

#define W 30//宽度

#define H 20//高度

#define MinSPEED 50//最慢下降速度(周期,数字越小越快)

#define MAXSPEED 5//最快下降速度

int score=0//总分

typedef struct letter

{

     int ascii// 字母ASCII码

     int hIndex//对应打印数组行下标

     int wIndex//对应打印数组列下标

     int cnt//周期计数,当cnt==speed,hIndex++并且cnt重新置0

     int speed//下降速度

     int key//0表示没有橡返镇被按中,1表示被按中

     struct letter *next

}LETR

void meError(void *p)//内存申请失败

LETR *newLETR(LETR *letrHead,LETR*letrTail,int wIndex)//产生一个新的字母,并添加到链表,返回尾节点

LETR* delLETR(LETR *letrHead,LETR*letrTail,int wIndex)//删除列下标的字母节点,返回新的尾节点

LETR *init(LETR *letrHead)//初始化一组字母,返回链表尾节点

LETR *showList(LETR *letrHead,LETR*letrTail)//显示列表并检查,发现到底或被按键按中的字母删除并新建新的字母,返回新的尾节点

void runLetter(LETR *letrHead)//所有字母一周期计数

DWORD WINAPI checkKey(LPVOID lpParameter)//新线程

int main()

{

   世旁 int i

    LETR *letrHead=NULL,*letrTail=NULL

    letrHead=(LETR *)malloc(sizeof(LETR))

    meError(letrHead)

    letrHead->next=NULL

    srand(time(NULL))

    letrTail=init(letrHead)

    CreateThread(NULL,0,checkKey,letrHead,0,NULL)

    letrTail=showList(letrHead,letrTail)

    while(1)

    {

        system("cls")

        printf("总分:%d\n",score)

        for(i=0i<Wi++)

            printf("-")

        printf("\n")

        runLetter(letrHead)

        letrTail=showList(letrHead,letrTail)

        for(i=0i<Wi++)

            printf("-")

        printf("\n")

    }

    return 0

}

DWORD WINAPI checkKey(LPVOID lpParameter)

{

char c

LETR *letrHead=NULL

while(1)

    {

        letrHead=(LETR *)lpParameter

        c=getch()

        while(letrHead->next)

        {

            if(c==letrHead->next->ascii)

                letrHead->next->key=1,score++//按键标识置1,考虑可能有多个相同随机字母,故用标识,在显示函数统一删除并新建

            letrHead=letrHead->next

        }

    }

return 0

}

void runLetter(LETR *letrHead)//所有字母一周期计数

{

    while(letrHead->next)

    {

        if(letrHead->cnt<letrHead->speed)

            letrHead->cnt++

        else

            (letrHead->next->hIndex)++,letrHead->cnt=0

        letrHead=letrHead->next

    }

}

LETR *showList(LETR *letrHead,LETR*letrTail)//显示列表并检查,发现到底或被按键按中的字母删除并新建新的字母,返回新的尾节点

{

    int i,j,wIndex

    char sp[H][W]

    LETR *head=letrHead

    for(i=0i<Hi++)

        for(j=0j<Wj++)

            sp[i][j]=' '

    while(letrHead->next)

    {

        if(letrHead->next->hIndex>H-1 || letrHead->next->key==1)//到底或者被按中就删除并新建,重新循环

        {

            wIndex=letrHead->next->wIndex

            letrTail=delLETR(head,letrTail,wIndex)

            letrTail=newLETR(head,letrTail,wIndex)

            letrHead=head

        }

        else

            sp[letrHead->next->hIndex][letrHead->next->wIndex]=letrHead->next->ascii

        letrHead=letrHead->next

    }

    for(i=0i<Hi++,printf("\n"))

        for(j=0j<Wj++)

            printf("%c",sp[i][j])

    return letrTail

}

LETR *init(LETR *letrHead)//初始化一组字母,返回链表尾节点

{

    int i

    LETR*letrTail=NULL

    for(i=0i<Wi++)

        letrTail=newLETR(letrHead,letrTail,i)

    return letrTail

}

LETR *newLETR(LETR *letrHead,LETR*letrTail,int wIndex)//在列下标wIndex首行,产生一个新的字母,并添加到链表,返回尾节点

{

    int n

    LETR *leterNEW=(LETR *)malloc(sizeof(LETR))

    meError(leterNEW)

    leterNEW->next=NULL

    n=rand()%2

    if(n)//随机大小写

        leterNEW->ascii=rand()%26+65//随机一个大写字母

    else

        leterNEW->ascii=rand()%26+97//随机一个小写字母

    leterNEW->hIndex=0

    leterNEW->wIndex=wIndex

    leterNEW->cnt=0

    leterNEW->speed=rand()%(MinSPEED-MAXSPEED)+1+MAXSPEED

    leterNEW->key=0

    if(letrHead->next==NULL)

        letrHead->next=leterNEW

    else

        letrTail->next=leterNEW

    letrTail=leterNEW

    return letrTail

}

LETR* delLETR(LETR *letrHead,LETR*letrTail,int wIndex)//删除列下标的字母节点,返回新的尾节点

{

    LETR *lhead=letrHead,*letrDel=NULL

    while(letrHead->next)

    {

        if(letrHead->next->wIndex==wIndex)

        {

            letrDel=letrHead->next

            letrHead->next=letrHead->next->next

            free(letrDel)

            break

        }

        letrHead=letrHead->next

    }

    letrHead=lhead

    while(letrHead->next)//重置尾节点

        letrHead=letrHead->next

    return letrHead

}

void meError(void *p)//内存申请失败

{

    if(p==NULL)

    {

        printf("\n异常:内存申请失败!回车结束程序!\n")

        while(getch()!='\r')

        exit(0)

    }

}

程序一:

类似于学习机上猛盯的指法练习程序,简单而实用

#include<time.h>

main()

{

int x,y,i,j

unsigned int Timer

char ch

char key

char *kb[]={"Q W E R T Y U I O P [ ]","A S D F G H J K L '","Z X C V B N M , . /"}

long AllCounter=0,RightCounter=0,FalseCounter=0

time_t t

int fun_Esc()

srand((unsigned)time(&t))

clrscr()

gotoxy(18,1)

printf("%s\n",kb[0])

gotoxy(20,3)

printf("%s\n",kb[1])

gotoxy(22,5)

printf("%s\n",kb[2])

gotoxy(11,25)

for(i=0i<60i++)

{

printf("=")

}

gotoxy(1,1)

printf("AllCh: %ld\nRight: %ld\nFalse: %ld",AllCounter,RightCounter,FalseCounter)

printf("\n\n")

printf("Esc to exit")

printf("\n")

printf("Enter to pause")

gotoxy(26,12)

printf("* * * * * * * * * * * * * * *")

gotoxy(26,13)

printf("* Press any key to start! *")

gotoxy(26,14)

printf("* * * * * * * * * * * * * * *")

gotoxy(51,13)

if(getch()==27)

{

if(fun_Esc()==1)

{

clrscr()

exit(0)

}

}

gotoxy(23,12)

printf(" ")

gotoxy(23,13)

printf(" ")

gotoxy(23,14)

printf(" ")

lab_start:

y = 6

Timer = 100000

i = rand()%3

j = rand()%(12-i)

ch = kb[i][j*4]

x = 18+i*2+j*4

while(y<=24)

{

if(kbhit())

{

key = getch()

if(key==ch key==ch+32)

{

ch = '*'Timer = 1000

}

else if(key==27)

{

if(fun_Esc()==1)

{

clrscr()

exit(0)

}

}

else if(key=='\r'答洞)

{

gotoxy(x,y-1)

printf(" ")

gotoxy(28,13)

printf("Press any key to continue")

getch()

gotoxy(28,13)

printf(" ")

}

else

{

FalseCounter++

}

}

if(y>6)

{

gotoxy(x,y-1)

printf(" ")

}

gotoxy(x,y)

printf("%c",ch)

gotoxy(1,1)

printf("枝举和AllCh: %ld\nRight: %ld\nFalse: %ld",AllCounter,RightCounter,FalseCounter)

delay(Timer)

y++

}

AllCounter++

if(ch == '*')

{

RightCounter++

}

goto lab_start

}

int fun_Esc()

{

int key = '#'

gotoxy(24,12)

printf("* * * * * * * * * * * * * * * * *")

gotoxy(24,13)

printf("* Are you sure to exit? (Y/N) *")

gotoxy(24,14)

printf("* * * * * * * * * * * * * * * * *")

gotoxy(51,13)

while(key!='Y' &&key!='y' &&key!='N' &&key!='n')

{

key = getch()

if(key=='Y' key=='y')

{

return 1

}

if(key=='N' key=='n')

{

gotoxy(24,12)

printf(" ")

gotoxy(24,13)

printf(" ")

gotoxy(24,14)

printf(" ")

return 0

}

}

}

程序二:

大家自己设三个或一个文本文件,内含1000个字符就行了,英文字母或其他字符都可以。谢谢指教!!主函数在下面!介绍一下自定义函数的功能吧

自定义函数名称

函数功能

Background()

设置简单友好界面。

DEMO()

设置菜单供用户选择练习方式及退出。

Get_charater()

实现从用户指定文件随机抽取100个字符并显示在屏幕上供用户参照打字的功能

Typing()

程序的核心,实现了接受输入的字符、判断正误、计算练习成绩和时间等并显示在屏幕

特点:而主函数则非常简单,只包含这四个要调用的函数。这四个函数功能单一,且每个函数不超过50行,较好地满足设计风格。

#include

#include

#include

#include

#include

char string[101]

void Background()

{

int driver=DETECT,mode /*定义变量*/

int x1=20,y1=20,r=10,num

int x2=20,y2=450

int color1=10,color2=10 /*在此设置颜色,一改全改*/

initgraph(&driver,&mode,"a:\\bgi ") /*初始化图形模式*/

setcolor(color1) /*步骤一、设置当前颜色用于绘图*/

for(num=0num<30num++)

{

circle(x1,y1,r) /*步骤二、使用当前颜色绘制一个闭合图形*/

setfillstyle(num%12,color1)/*步骤三、设置填充方式*/

floodfill(x1,y1,color1) /*步骤四、对闭合图形进行填充*/

x1+=20

delay(100)

}

setcolor(color2)

for(num=0num<30num++)

{

circle(x2,y2,r)

setfillstyle(num%12,color2)

floodfill(x2,y2,color2)

x2+=20

delay(100)

}

setcolor(YELLOW) /*改变当前颜色,输出友好话*/

settextstyle(0,0,2)

outtextxy(50,150,"WELCOME TO THE TYPING WORLD!")

setcolor(LIGHTMAGENTA)

outtextxy(200,350,"DESIGED BY HE ZHANG HONG")

sleep(3)/*延时二秒观看结果*/

closegraph() /*关闭图形*/

}

void DEMO() /*设置菜单函数*/

{

printf("_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_**_*\n”

"\t\t\t"

"THE DEMO DISPLAY FOR THE FILE SYSTEM\n"

"\n"

"\t\t"

"1:PRATICE ONLY ENGLISH Characters.\n"

"\t\t"

"2:PRATICE OTHER Charcters.\n"

"\t\t"

"3:PRATICE ALL Charcters.\n"

"\t\t"

"4:QUIT AT ONCE!\n"

"\n")

}

void Get_character(void) /*设置得到字符函数*/

{

void Typing() /*声明typing()函数*/

FILE *in

int i,t,choice

char ch

t=abs(time(0))%700 /*获取随机数来指定下面指针的位*/

printf("\nPLEASE ENTER YOUR CHOICE:")

choice=getch()

clrscr()/*清屏*/

switch(choice) /*选择不同打开文件来打不同的字符*/

{

case ’1’: in=fopen("english.txt","r")

break

case ’2’: in=fopen("others.txt","r")

break

case ’3’: in=fopen("type all.txt","r")

break

case ’4’: exit(1)break

}

fseek(in,t*1l,0)

fgets(string,101,in)

printf("\n")

printf("********************************************************************")

for(i=0i<100i++)

putchar(string[i])

printf("\n")

printf("********************************************************************")

fclose(in)

printf("LET’S BEGIN TYPING,OK?[Y/N]")

printf("\n")

ch=getch()

if(ch==’n’||ch==’N’) /*判断是否练习打字*/

exit(0)

else if(ch==’y’||ch==’Y’)

Typing()

}

void Typing(void) /*设置打字(包括计算其他结果)函数*/

{

int i,j,Right_char=0,Wrong_char=0,Sum_char=0

float Speed,Timeused,Right_rate

char absorb_char,ch_1,ch_2,ch_3

time_t star,stop /*定义time变量,获取系统时间并显示在屏幕上*/

time(&star)

printf("\n")

printf("time begin:%s",ctime(&star))

i=0

absorb_char=getchar()/*接受键盘输入的字符并在下面的while语句判断正错和计算结果*/

while(absorb_char!=’\n’&&i<100)

{

if(absorb_char==string[i])

{

Right_char++

Sum_char++

}

else

{

Wrong_char++

Sum_char++

}

i++

absorb_char=getchar()

}

time(&stop)

Timeused=difftime(stop,star) /*利用difftime()函数输出所用时间*/

Right_rate=(float)Right_char/(float)Sum_char*100

Speed=(Sum_char/Timeused)*60

printf("time end:%s",ctime(&stop))/*下面显示分数*/

printf("****#################~~~~~~~~~~~~~YOUR SCORE!!~~~~~~~~~~~~~~################****")

printf("1: TOTAL TIME USED:%.3f\n",Timeused)

printf("2: YOU HAVE TYPED:%d\n",Sum_char)

printf("3: Typing Right_Characters are:%d\n",Right_char)

printf("4: Typing Wrong_Characters are:%d\n",Wrong_char)

printf("5: YOUR TYPING SPEED IS :%.2f\\min\n",Speed)

printf("6: YOUR TYPING RIGHT_RATE IS :%.2f%%\n",Right_rate)

printf("****#################~~~~~~~~~~~~~YOUR SCORE!!~~~~~~~~~~~~~~################****")

if(Speed<=50||Right_rate<=80) /*询问用户是否重来一遍*/

{

printf("NOT VERY GOOD!\nTRY IT AGAIN,OK?[Y/N]\n")

ch_2=getch()

if(ch_2==’n’||ch_2==’N’) exit(0)

else if(ch_2==’y’||ch_2==’Y’)

{

clrscr()

DEMO() /*分别调用函数重来一遍*/

Get_character()

Typing()

}

exit(0)

}

else printf("WELL DONE!!\nONE MORE TIME?[Y/N]\n") /*询问用户是否重来一遍*/

ch_3=getch()

if(ch_3==’n’||ch_3==’N’) exit(0)

else if(ch_3==’y’||ch_3==’Y’)

{

clrscr()

DEMO() /*分别调用函数重来一遍*/

Get_character()

Typing()

}

exit(0)

}

main(void) /*主函数包含四个要调用的函数*/

{

Background()

DEMO()

Get_character()

Typing()

}

#include <stdio.h>

#include <string.h>

#include <stdlib.h>

#include <time.h>

#define L 100 //定备颤核义最大字符长洞埋度为 100

int main()

{

srand(unsigned(time(NULL)))

char str[L] = {}, teststr[L] = {}

int length, RightCount = 0

float Precision

length = rand() % L + 1 //生成随机的字符串长度

for (int i = 0 i < length i++)

{

str[i] = rand() % 26 + 'a'仿掘 //默认字符为小写字符

putchar(str[i])

}

printf("\nPlease input the above string :\n")

gets(teststr) //保存输入的字符串

for (int i = 0 i < length i++)//计算准确的字符个数

{

if (teststr[i] == str[i]) RightCount++

}

Precision = RightCount * 1.0 / length//计算准确率

printf("Precision : %.2f%\n", Precision * 100) //准确率保留两位小数输出

return 0

}

测试样例:

jvgvmsnpfia

Please input the above string :

jlkjlsnfdas

Precision : 27.27


欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/yw/12496783.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-25
下一篇 2023-05-25

发表评论

登录后才能评论

评论列表(0条)

保存