C语言龟兔赛跑的小游戏(共6篇)
篇1:C语言龟兔赛跑的小游戏
#include 程序: #include#includevoid menu{printf(“***欢迎来挑战猜数字游戏*** ”);printf(“*****请选择开始或退出***** ”);printf(“******1.start 0.exit****** ”);}void game(){int num = 0;srand((unsigned)time(NULL));//随着时间变化生成不同的随机数int ret = rand() % 100 + 1;//是从一个时间点到此时的秒数while (1){printf(“请猜数字:”);scanf(“%d”,&num);if (num == ret){printf(“你真聪明,猜对了! ”);break;}else if(num >ret){printf(“你好笨,猜大了! ”);}else if (num < ret){printf(“你真蠢,猜小了! ”);}}}int main(){int input = 1;while (input){menu();printf(“请选择:”);scanf(“%d”,&input);switch (input){case 0:break;case 1:game();break;default:break;}}return 0;} 结果: ***欢迎来挑战猜数字游戏*** *****请选择开始或退出***** ******1.start 0.exit****** 请选择:1 请猜数字:50 你真蠢,猜小了! 请猜数字:75 你真蠢,猜小了! 请猜数字:100 你好笨,猜大了! 请猜数字:85 你真蠢,猜小了! 请猜数字:93 你好笨,猜大了! 请猜数字:90 你好笨,猜大了! 请猜数字:87 你真蠢,猜小了! 请猜数字:88 你真蠢,猜小了! 请猜数字:89 你真聪明,猜对了! ***欢迎来挑战猜数字游戏*** *****请选择开始或退出***** ******1.start 0.exit****** 请选择:0 1 程序流程设计 2 扫雷游戏程序中的重点难点分析 2.1 Windows XP下鼠标的使用 鼠标是扫雷程序的最主要用户输入设备, 在Windows操作系统下, 系统会自动加载了鼠标驱动程序, 但并不意味着在任何程序下都可以使用;用Turbo C开发的应用程序, 用户要使用鼠标必须在程序中加载鼠标驱动程序。鼠标设备驱动程序的访问通过使用中断0x33访问。本程序中所用中断0x33的功能与参数如表1所示。 但是在Windows XP下, 程序通过调用中断0X33并不能显示鼠标。为了能让程序可以在Windows XP下使用鼠标, 除了要调用中断0X33外, 还必须在程序中增加虚拟画出鼠标的光标并时刻检测鼠标状态的模块以解决Windows XP无法显示鼠标的问题 (具体程序详见函数说明) 。 2.2 空白格的连环显示 在扫雷程序中要求当鼠标左键单击的格子为空白格时, 必须显示其周围的所有空白格, 并继续查找已显示的空白格周围的所有空白格并将其显示出来。这是本程序在设计时的一个重点, 也是一个难点。我们通过分析, 不难发现这是一个典型的递归问题;我们可以通过构造递归函数来实现。递归函数有两个要素, 一个递归边界条件, 另一个递归定义。本程序构造的递归函数我们把当前格子有红旗或者已经显示过数字或空白格子作为递归边界条件, 把递归定义为显示空白格或数字 (周围地雷数) 并向其周围8个方向搜索。具体算法如下: 1) 如果当前格子有红旗或者已经显示过数字或空白格子, 则返回。 2) 空白格子数减1 (统计处理过多少格子) 。 3) 如果周围的地雷数为0, 且它不是地雷, 则将它显示为空白, 同时将它的状态值num置0, 表示处理过;如果周围的地雷数不为0, 显示周围地雷数, 同时将它的状态值num置0, 表示处理过 (即显示过数字) , 返回。 4) 8个方向递归调用函数显示所有的空白格子。 3 扫雷游戏程序主要函数说明 说明:由于篇幅有限, 只列出重点函数代码, 无法将本程序中的所有代码全部列出 (完整代码详见源程序) 。 3.1 main () 主函数 定义使用到的常数、全局变量、函数原型说明。然后初始化图形系统, 调用游戏控制函数, 游戏只接受鼠标操, 作按任意键结束游戏, 关闭图形系统, 程序结束。函数代码如下: void main (void) {int gd=DETECT, g {int gd=DETECT, gm=1;/*初始化*/ initgraph (&gd, &gm, "") ; Mouse Math () ;/*计算鼠标形状, 一开始必须使用, 后面就不用了*/ Mouse Set Y (0, 479) ; Mouse Set X (0, 639) ; Mouse Set XY (100, 100) ; Mouse On (Mouse X, Mouse Y) ;/*第一次显示鼠标*/ Control () ;/*游戏控制函数*/ Close () ;/*结束*/ } 3.2 Mouse On () 鼠标光标显示函数 本函数用一个16×16的点阵画出鼠标光标形状以实现鼠标在Windows XP的显示。函数代码如下: 3.3 Mouse Off () 鼠标光标隐藏函数 本函数通过对鼠标点阵的异或处理将鼠标光标隐藏。函数代码如下: 3.4 Mouse Status () 鼠标状态监测函数 本函数通过计算鼠标当前位置的监测鼠标是否移动, 若发现现在位置与原位置不同说明鼠标已移动, 则将原位置光标隐藏并在当前位置重画光标;通过调用中断0X33获取鼠标按键信息并将其记录下来作为本函数的返回值提供个游戏控制函数使用。 3.5 Game Begin () 游戏初始化函数 这个函数完成初始界面的设计以及随机布雷工作。初始界面的主要工作是确定图的位置和方格显示的位置。外边框的左上角坐标为 (190, 60) , 右下角坐标为 (390, 290) , 显示笑脸和地雷数的区域为 (190, 60) ~ (390, 90) , 每个方格的宽度和高度均为16, 随机布雷10个。读者可以参照修改区域的大小、方格数量、布雷数目等。 3.6 Draw Smile () 画笑脸 利用画椭圆函数fillellipse () 和bar () 画笑脸, 作为游戏重新开始的鼠标点击区域。 3.7 Draw Empty () 显示空白格函数 本函数用两种模式显示空白格:未点开的空白格 (可以点击) 的格子显示为灰色的略大的方格, 已点开的空白格 (不能再点击) 的格子显示为白色的略小的方格。函数的四个参数 (坐标i和j、模式和颜色) 来控制空白格的显示。 3.8 Draw Redflag () 插旗函数 本函数用显示一面小红旗来表示单击鼠标右键的标志地雷操作。 3.9 Mine Statistics () 统计地雷 统计每个格子周围 (周围指上、下、左、右、左上、左下、右上、右下) 的雷数, 分别考虑格子处于四个角、四条边以及中间某个位置的情况。程序中使用的是多个if语句, 而没有使用或运算连接组成复合表达式, 例如: 没有写成if (Mine[0][1].num==1||Mine[1][0].num==1) 是考虑到C语言的逻辑表达式的短路问题。在C语言中, 逻辑或只要前面的表达式为真, 后面就不必判断了, 这样会导致少计算地雷数。 3.1 0 Show White () 显示空白格函数 本函数实现前面重点难点分析的“空白格连环显示”中所述当鼠标左键单击了空白格后用递归算法查找已显示的空白格周围的所有空白格并将其显示出来的功能。本函数代码如下: 3.1 1 Game Over () 游戏失败 本函数为游戏过程中触雷后后游戏失败的处理函数。该函数主要功能为显示游戏失败信息, 显示布雷情况, 做游戏失败标记等。 3.1 2 Game Win () 输出最后的胜利者结果 本函数为游戏过程中顺利完成所有地雷正确标注后游戏胜利的处理函数。该函数主要功能为显示游戏胜利信息, 做游戏胜利标记等。 3.1 3 Control () 游戏控制函数 调用函数Game Begin () 显示游戏初始界面, 调用Game Play () 为具体游戏操作过程, 该函数返回有两种可能:一种是正在游戏, 提前结束游戏;一种是游戏结束, 要么失败, 要么胜利。如果是前者, 则重新开始游戏, 如果是后者, 则等待游戏重新开始或结束3.14Game Play () 游戏过程函数 游戏过程主要是对鼠标和键盘按键操作的处理, 具体过程如下: 1) 统计每个格子周围有多少地雷并随时记录在相应的数组元素中; 2) 如果监测到键盘按键则退出程序否则循环执行如下过程: (1) 单击了鼠标左键则通过鼠标光标位置判断单击的区域, 如果鼠标单击了笑脸则游戏重新开始。如果单击了方格, 判断该格子里是否有红旗或者已显示过数字或空白格, 有则按键无效;否则如果单击的格子是地雷, 显示游戏失败信息并显示地雷分布;如果不是地雷, 则统计该格子周围 (8个方向) 的地雷数, 如果周围地雷数为0, 调用递归函数Show White () 函数处理周围格子的情况, 显示周围地雷数或空白格;如果单击的格子周围地雷数不为0, 则显示周围地雷数, 将处理过的格子作标记。如果所有格子处理完毕, 游戏胜利, 显示胜利信息。 (2) 单击了鼠标右键则通过鼠标光标位置判断单击的区域, 如果鼠标右键区域非格子, 则无效;如果鼠标右键区域为格子, 则判断格子是否有红旗, 有则红旗消失, 如果没有红旗, 则显示红旗。 4 程序设计完成的游戏界面 5 总结 C语言是计算机程序设计的基础;本文通过一个扫雷游戏的设计希望能提供给程序设计初学者一些编程思路和技巧的一些启示。由于本人的水平限制, 文中难免存在一些问题, 欢迎读者批评指正。 参考文献 [1]陈天洲.C语言高级程序设计[M].北京:人民邮电出版社, 2002. [2]Chisholm P S R.C语言编程常见问题解答[M].张芳妮, 吕波, 译.北京:清华大学出版社, 2000. 关键词:C语言;编程技巧;应用 中图分类号:G642 文献标识码:B 文章编号:1002-7661(2014)24-002-01 C语言属于一种程序设计类语言,其使用在数据处理方面有突出作用,在很多的学习工作领域都有大规模的应用,像是软件开发、科研建设等都离不开C语言的利用。C语言编程,就是用C语言进行相应计算机代码的编写,C语言的学习,需要掌握一定的技巧,不然没有头绪的学习是得不到良好学习效果的,掌握了C语言的学习技巧,才能够更好的促进C语言的学习[1]。 一、C语言与C语言的优势 当下世界上使用范围最广,流行度最高的计算机编程语言便是C语言,要想良好的学习和使用C语言,必须加深对C语言的了解。C语言发源于上个世纪60年代,成熟在70年代,最近半个世纪的使用过程中,C语言表现了如下几种优势:第一,C语言简洁紧凑,使用方式灵活方便,且语法运用宽松不受限制,书写方式自由随意,结合了高级编程语言的结构性与实用性的特点,组成了一种全新式的有强大使用功能的编程语言;第二,C语言有广泛的应用层面,且可植性强,C语言在各种系统中都能够被兼容使用;第三,C语言的运算符丰富多样,各种数据结构类型的使用,除了C语言可以将各种复杂的数据运算完成外,还具有强大的图形功能;第四,结构式的语言特点分割了代码和数据,其中的程序表现层次条理清楚,后期的使用和维护工作便利,使用C语言可以访问物理地址[2]。从中可知,C语言具有强大的功能,因此在信息技术的领域中,C语言所占据的地位是非常高的。 二、C语言学习难度大的原因 因为C语言所具备的各种强大功能,因此人们对其的关注程度也越来越高,想要学会并且全面掌握C语言技术的人也越来越多。可是大部分在刚刚接触C语言的时候,觉得C语言过于枯燥乏味,学习了一段时间后都没有掌握到多少知识,也没有一个清楚全面的认识对于C语言,觉得十分的茫然。出现这种情况的原因还是因为C语言是一种高级语言,这种语言和面向对象的语言之间存在较大的差别,在C语言的学习过程中,学习者难以从中看到形象的画面,只能够在编程程序成功后,经过调试才可以看到效果。在编程的过程中,只要出现一点粗心错误,就会让整个编程无法成功调试,出现一些错误的现象,除此之外,C语言的使用过程中,包含了大量的算法与数据组成结构,这些没有任何的技巧,就是要死记硬背,所以很多学习者在遇到这些枯燥晦涩的问题时,就会丧失学习兴趣,降低学习效率和学习质量。 三、C语言编程技巧的应用 1、用空间换时间 例如对字符串进行赋值,方法有以下几种: (1)基础方法: #define LEN 32 Char string I[LEN]; memset(string 1,0,LEN); ctrcpy(string 1,“this is a example”) ; (2)方法2: const char string2[LEN]=“this is a example”; char*cp; cp=string2; 从这个案例中可以发现,方法(1)与方法(2)在电脑上的执行效率是不一样的,第一种方法必须使用两个字符函数才可以完成,而第二种方法直接使用指针就可以完成了。但是第二种方法相比第一种方法灵活性欠缺,如果这个字符串有不断变化的要求,那么第一种方法就有很大的使用优势了,第二种方法要占用较大的内存,但是效率比第一种更高[3]。 2、位运算掌握 在利用位运算的时候,能够让代码变得更加的简洁,提升运算效率,让问题得到顺利解决。在所有的计算机程序之中,最小的数据单位就是位,无特殊情况的话,所有的数据运算和操作都可以使用“位运算”方式完成,从这里就就可以看出,在编程语言之中,“位”有多么重要了。“位”使用在C语言的运算过程中,可以提升工作效率,顺利的将更多难度大的问题解决。 3、C语言特有函数掌握 很多时候进行编程,都需要使用C语言的特有函数,函数不是一种数据,而是一种功能,每一个函数都能够执行一定的功能建设,而相对应的函数名称中也将函数的功能反映了出来。开展函数定义的时候,要求操作者包含名字、参数名、类型和函数返回类型的数据,编译过程中,数据库系统是之前被定义好了的,使用过程中只要通过#include这项指令,把各种相关的头文件包含在本文件当中就可以了。 但是不管在C语言编程过程中使用怎样的技巧,还是需要做到具体问题具体分析,以上各种技巧使用起来因人而异,整体是能够提升编程效率,在学习过程中使用会获得一定的成效,而降低学习的枯燥感,拓宽C语言的使用范围。 C语言的学习过程中,每一位学习者都应该对C语言的特性有充分的了解,学习并且掌握每一种编程技巧,学习好了C语言的编程技巧,可以帮助学生提升C语言的学习兴趣,让学生的学习目的性更强,提升学生的C语言学习效率与学习质量。 参考文献: [1] 余 勍.王 捷.浅谈C语言编程技巧在C语言学习中的应用[J].信息通信,2013,07:108. [2] 赵 黎.范君君.C语言编程技巧在C语言学习中的应用研究[J]. 信息与电脑(理论版),2014,09:252. //自制-拼图游戏 作者:高坤 请标明出处 谢谢www.dnzg.cn //代码笨拙 高手勿笑 欢迎批评指正 #include #include #include #include #include “resource.h” HINSTANCE hInst; HBITMAP pic.ruiwen.compare_pic,pict[8],compare_pict[8],other; //所有图的变量名 HDC hdc,mdc; //DC名 int mouse_x,mouse_y,n=0,line=3,high3=100,high4=200,high5=300; //鼠标X Y 移动步数 难度 记录 char str[10]=“ ”; //字符串,显示步数和记录时用 bool fin=false,new3=true,new4=false,new5=false; //完成 难度三 四 五 的重绘 struct Point { int x; int y; int num; }point[26]; //块 ATOM MyRegisterClass(HINSTANCE hInstance); BOOL InitInstance(HINSTANCE, int); LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); void MyPaint; //显示 void Change_Block(int block1,int block2); //交换两块的属性 void Save(); //保存记录 void GetPos(); //为重绘做的随机排列 int APIENTRY WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow) { MSG msg; MyRegisterClass(hInstance); if (!InitInstance (hInstance, nCmdShow)) //如果实例化失败,退出 { return FALSE; } while (GetMessage(&msg, NULL, 0, 0)) //消息循环,一直获取消息,直到消息返回值为假 { TranslateMessage(&msg); //翻译消息 DispatchMessage(&msg); //将消息发到适当的对象上 } return msg.wParam; } ATOM MyRegisterClass(HINSTANCE hInstance) //注册窗口类,通知你要建的窗口是什么样的.可以有多个,用类名来区分 { WNDCLASSEX wcex; //类名 wcex.cbSize = sizeof(WNDCLASSEX); //类的长度 cb...表示存储空间 wcex.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS; //窗口风格 水平horizontal.垂直vertical.重画redraw wcex.lpfnWndProc = (WNDPROC)WndProc; //指向函数的一个指针 指向WndProc //LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) wcex.cbClsExtra = 0; //类变量占用的存储 (cb表示存储空间的前缀) wcex.cbWndExtra = 0; //实例变量占用的存储 wcex.hInstance = hInstance; //定义该类的应用程序实例的句柄 wcex.hIcon = LoadIcon(hInstance,MAKEINTRESOURCE(IDI_ICON1)); //图标对象的句柄 wcex.hCursor = LoadCursor(NULL, IDC_ARROW); //光标图像的句柄 wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); //用于擦掉用户区的刷子的句柄 wcex.lpszMenuName = (LPCSTR)IDR_MENU1; //标识选单对象的字符串 wcex.lpszClassName = “CAN”; //该类名字的字符串 lpsz长指针,以 结束 wcex.hIconSm = NULL; // return RegisterClassEx(&wcex); //定义完类的各个对象后注册 } BOOL InitInstance(HINSTANCE hInstance, int nCmdShow) { HWND hWnd; hInst = hInstance; char filename[30]=“ ”; hWnd = CreateWindow(“CAN”, “游戏窗口”, WS_OVERLAPPEDWINDOW & ~WS_MAXIMIZEBOX & ~WS_THICKFRAME,CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL); if (!hWnd) //类名,用于标识创建的窗口属于哪个类. { return FALSE; } MoveWindow(hWnd,80,100,1087,526,true); ShowWindow(hWnd, nCmdShow); UpdateWindow(hWnd); hdc=GetDC(hWnd); mdc=CreateCompatibleDC(hdc); //创建缓存 empty=(HBITMAP)LoadImage(hInstance,“Sourcepicempty.bmp”,IMAGE_BITMAP,687,526,LR_LOADFROMFILE); for(int m=0;m<=7;m++) { sprintf(filename,“Sourcepicpic%d.bmp”,m); //读图,没什么好说的 pict[m] = (HBITMAP)LoadImage(hInstance,filename,IMAGE_BITMAP,600,480,LR_LOADFROMFILE); compare_pict[m]=(HBITMAP)LoadImage(hInstance,filename,IMAGE_BITMAP,450,360,LR_LOADFROMFILE); } pic=pict[0]; compare_pic=compare_pict[0]; FILE *fp; //读入record文件中的记录 if((fp=fopen(“Sourcerecord”,“ab+”))==NULL) { MessageBox(NULL,“不能打开record文件,可能被删除,请在Source中重新建立.”,“”,NULL); return false; } else { fread(&high3,sizeof(high3),1,fp); fread(&high4,sizeof(high4),1,fp); fread(&high5,sizeof(high5),1,fp); fclose(fp); } MyPaint(); return TRUE; } LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { PAINTSTRUCT ps; int block_num=0; //用于鼠标所指的块的编号,非NUM号 要区分 switch (message) { case WM_PAINT: //显示 hdc = BeginPaint(hWnd, &ps); hdc=GetDC(hWnd); MyPaint(); EndPaint(hWnd, &ps); break; case WM_COMMAND: //菜单命令 switch(LOWORD(wParam)) { case ID_NEWGAME: fin=0;n=0; switch(line) { case 3: new3=true;break; //读图后要重排图 case 4: new4=true;break; case 5: new5=true;break; default:; } MyPaint(); break; case ID_PIC0: pic=pict[0]; //读入大图 compare_pic=compare_pict[0]; //读入参照图 fin=0;n=0; switch(line) { case 3: new3=true;break; //读图后要重排图 case 4: new4=true;break; case 5: new5=true;break; default:; } MyPaint(); break; case ID_PIC1: pic=pict[1]; compare_pic=compare_pict[1]; fin=0;n=0; switch(line) { case 3: new3=true;break; case 4: new4=true;break; case 5: new5=true;break; default:; } MyPaint(); break; case ID_PIC2: pic=pict[2]; compare_pic=compare_pict[2]; fin=0;n=0; switch(line) { case 3: new3=true;break; case 4: new4=true;break; case 5: new5=true;break; default:; } MyPaint(); break; case ID_PIC3: pic=pict[3]; compare_pic=compare_pict[3]; fin=0;n=0; switch(line) { case 3: new3=true;break; case 4: new4=true;break; case 5: new5=true;break; default:; } MyPaint(); break; case ID_PIC4: pic=pict[4]; compare_pic=compare_pict[4]; fin=0;n=0; switch(line) { case 3: new3=true;break; case 4: new4=true;break; case 5: new5=true;break; default:; } MyPaint(); break; case ID_PIC5: pic=pict[5]; compare_pic=compare_pict[5]; fin=0;n=0; switch(line) { case 3: new3=true;break; case 4: new4=true;break; case 5: new5=true;break; default:; } MyPaint(); break; case ID_PIC6: pic=pict[6]; compare_pic=compare_pict[6]; fin=0;n=0; switch(line) { case 3: new3=true;break; case 4: new4=true;break; case 5: new5=true;break; default:; } MyPaint(); break; case ID_PIC7: pic=pict[7]; compare_pic=compare_pict[7]; fin=0;n=0; switch(line) { case 3: new3=true;break; case 4: new4=true;break; case 5: new5=true;break; default:; } MyPaint(); break; case ID_PIC8: if(LoadImage(NULL,“Sourcepicother.bmp”,IMAGE_BITMAP,600,480,LR_LOADFROMFILE)) //成功载入other.bmp { pic = (HBITMAP)LoadImage(NULL,“Sourcepicother.bmp”,IMAGE_BITMAP,600,480,LR_LOADFROMFILE); compare_pic=(HBITMAP)LoadImage(NULL,“Sourcepicother.bmp”,IMAGE_BITMAP,450,360,LR_LOADFROMFILE); fin=0;n=0; switch(line) { case 3: new3=true;break; case 4: new4=true;break; case 5: new5=true;break; default:; } MyPaint(); } else MessageBox(hWnd,“pic文件夹中无other.bmp文件.”,“说明”,NULL); //未成功载入other.bmp break; case ID_THREE: new3=true;new4=false;new5=false;line=3;fin=0;n=0; //如果选难度三,则要重排图,不许四,五重排.难度设为三,标记未完成,n从0记数. MyPaint(); break; case ID_FOUR: new3=false;new4=true;new5=false;line=4;fin=0;n=0; MyPaint(); break; case ID_FIVE: new3=false;new4=false;new5=true;line=5;fin=0;n=0; MyPaint(); break; case ID_INTRODUCE: MessageBox(hWnd,“鼠标点击移动,拼完整即胜利!如果想自添加图需要用BMP格式,文件名为other.bmp,并放入pic文件夹中.”,“说明”,NULL); break; case ID_ABOUT: MessageBox(hWnd,“如发现BUG或有好的建议。请致信EMAIL:29648634@qq.com。谢谢! Special Thank 老婆--悦 对我的大力支持! 作者:高坤”,“说明”,NULL); break; case ID_EXIT: DestroyWindow(hWnd); break; default: MessageBox(hWnd,“菜单命令错误!”,“”,NULL); } break; case WM_LBUTTONDOWN: //鼠标左键控制块的移动 mouse_x=LOWORD(lParam); //记录鼠标的位置 mouse_y=HIWORD(lParam); block_num=0; switch(line) { case 3: if(mouse_x<600 && mouse_y<480) //鼠标在允许点击的大图上才赋块值 block_num=mouse_x/200+1+(mouse_y/160)*3; if(!fin && block_num>0) { sndPlaySound(“Sourcesoundclick.wav”,SND_ASYNC | SND_FILENAME); switch(block_num) { case 1: if(point[2].num==9) //第一块可以与第二块交换 { Change_Block(1,2); n++; //移动步数加1 } else if(point[4].num==9) //第一块可以与第四块交换 { Change_Block(1,4); n++; //移动步数加1 } break; case 2: if(point[1].num==9) //第二块可以与第一块交换 { Change_Block(2,1); n++; //移动步数加1 } else if(point[5].num==9) //第二块可以与第五块交换 { Change_Block(2,5); n++; //移动步数加1 } else if(point[3].num==9) //第二块可以与第三块交换 { Change_Block(2,3); n++; //移动步数加1 } break; case 3: if(point[2].num==9) //第三块可以与第二块交换 { Change_Block(3,2); n++; //移动步数加1 } else if(point[6].num==9) //第三块可以与第六块交换 { Change_Block(3,6); n++; //移动步数加1 } break; case 4: if(point[1].num==9) //第四块可以与第一块交换 { Change_Block(4,1); n++; //移动步数加1 } else if(point[5].num==9) //第四块可以与第五块交换 { Change_Block(4,5); n++; //移动步数加1 } else if(point[7].num==9) //第四块可以与第七块交换 { Change_Block(4,7); n++; //移动步数加1 } break; case 5: if(point[2].num==9) //第五块可以与第二块交换 { Change_Block(5,2); n++; //移动步数加1 } else if(point[4].num==9) //第五块可以与第四块交换 { Change_Block(5,4); n++; //移动步数加1 } else if(point[6].num==9) //第五块可以与第六块交换 { Change_Block(5,6); n++; //移动步数加1 } else if(point[8].num==9) //第五块可以与第八块交换 { Change_Block(5,8); n++; //移动步数加1 } break; case 6: if(point[3].num==9) //第六块可以与第三块交换 { Change_Block(6,3); n++; //移动步数加1 } else if(point[5].num==9) //第六块可以与第五块交换 { Change_Block(6,5); n++; //移动步数加1 } else if(point[9].num==9) //第六块可以与第九块交换 { Change_Block(6,9); n++; //移动步数加1 } break; case 7: if(point[8].num==9) //第七块可以与第八块交换 { Change_Block(7,8); n++; //移动步数加1 } else if(point[4].num==9) //第七块可以与第四块交换 { Change_Block(7,4); n++; //移动步数加1 } break; case 8: if(point[7].num==9) //第八块可以与第七块交换 { Change_Block(8,7); n++; //移动步数加1 } else if(point[5].num==9) //第八块可以与第五块交换 { Change_Block(8,5); n++; //移动步数加1 } else if(point[9].num==9) //第八块可以与第九块交换 { Change_Block(8,9); n++; //移动步数加1 } break; case 9: if(point[8].num==9) //第九块可以与第八块交换 { Change_Block(9,8); n++; //移动步数加1 } else if(point[6].num==9) //第九块可以与第六块交换 { Change_Block(9,6); n++; //移动步数加1 } break; default:; } } break; case 4: if(mouse_x<600 && mouse_y<480) block_num=mouse_x/150+1+(mouse_y/120)*4; if(!fin && block_num>0) //如果block_num没能从鼠标坐标上获取值则说明点的位置不对, { sndPlaySound(“Sourcesoundclick.wav”,SND_ASYNC | SND_FILENAME); switch(block_num) { case 1: if(point[block_num+1].num==16) { Change_Block(block_num,block_num+1); n++; } else if(point[block_num+4].num==16) { Change_Block(block_num,block_num+4); n++; } break; case 4: if(point[block_num-1].num==16) { Change_Block(block_num,block_num-1); n++; } else if(point[block_num+4].num==16) { Change_Block(block_num,block_num+4); n++; } break; case 13: if(point[block_num-4].num==16) { Change_Block(block_num,block_num-4); n++; } else if(point[block_num+1].num==16) { Change_Block(block_num,block_num+1); n++; } break; case 16: if(point[block_num-1].num==16) { Change_Block(block_num,block_num-1); n++; } else if(point[block_num-4].num==16) { Change_Block(block_num,block_num-4); n++; } break; case 2: case 3: if(point[block_num-1].num==16) { Change_Block(block_num,block_num-1); n++; } else if(point[block_num+4].num==16) { Change_Block(block_num,block_num+4); n++; } else if(point[block_num+1].num==16) { Change_Block(block_num,block_num+1); n++; } break; case 5: case 9: if(point[block_num+4].num==16) { Change_Block(block_num,block_num+4); n++; } else if(point[block_num+1].num==16) { Change_Block(block_num,block_num+1); n++; } else if(point[block_num-4].num==16) { Change_Block(block_num,block_num-4); n++; } break; case 8: case 12: if(point[block_num-1].num==16) { Change_Block(block_num,block_num-1); n++; } else if(point[block_num+4].num==16) { Change_Block(block_num,block_num+4); n++; } else if(point[block_num-4].num==16) { Change_Block(block_num,block_num-4); n++; } break; case 14: case 15: if(point[block_num-1].num==16) { Change_Block(block_num,block_num-1); n++; } else if(point[block_num+1].num==16) { Change_Block(block_num,block_num+1); n++; } else if(point[block_num-4].num==16) { Change_Block(block_num,block_num-4); n++; } break; default: if(point[block_num-1].num==16) { Change_Block(block_num,block_num-1); n++; } else if(point[block_num+4].num==16) { Change_Block(block_num,block_num+4); n++; } else if(point[block_num+1].num==16) { Change_Block(block_num,block_num+1); n++; } else if(point[block_num-4].num==16) { Change_Block(block_num,block_num-4); n++; } } } break; case 5: if(mouse_x<600 && mouse_y<480) block_num=mouse_x/120+1+(mouse_y/96)*5; if(!fin && block_num>0) //如果block_num没能从鼠标坐标上获取值则说明点的位置不对。 { sndPlaySound(“Sourcesoundclick.wav”,SND_ASYNC | SND_FILENAME); switch(block_num) //移动两块 { case 1: if(point[block_num+1].num==25) { Change_Block(block_num,block_num+1); n++; } else if(point[block_num+5].num==25) { Change_Block(block_num,block_num+5); n++; } break; case 5: if(point[block_num-1].num==25) { Change_Block(block_num,block_num-1); n++; } else if(point[block_num+5].num==25) { Change_Block(block_num,block_num+5); n++; } break; case 21: if(point[block_num-5].num==25) { Change_Block(block_num,block_num-5); n++; } else if(point[block_num+1].num==25) { Change_Block(block_num,block_num+1); n++; } break; case 25: if(point[block_num-1].num==25) { Change_Block(block_num,block_num-1); n++; } else if(point[block_num-5].num==25) { Change_Block(block_num,block_num-5); n++; } break; case 2: case 3: case 4: if(point[block_num-1].num==25) { Change_Block(block_num,block_num-1); n++; } else if(point[block_num+5].num==25) { Change_Block(block_num,block_num+5); n++; } else if(point[block_num+1].num==25) { Change_Block(block_num,block_num+1); n++; } break; case 6: case 11: case 16: if(point[block_num+5].num==25) { Change_Block(block_num,block_num+5); n++; } else if(point[block_num+1].num==25) { Change_Block(block_num,block_num+1); n++; } else if(point[block_num-5].num==25) { Change_Block(block_num,block_num-5); n++; } break; case 10: case 15: case 20: if(point[block_num-1].num==25) { Change_Block(block_num,block_num-1); n++; } else if(point[block_num+5].num==25) { Change_Block(block_num,block_num+5); n++; } else if(point[block_num-5].num==25) { Change_Block(block_num,block_num-5); n++; } break; case 22: case 23: case 24: if(point[block_num-1].num==25) { Change_Block(block_num,block_num-1); n++; } else if(point[block_num+1].num==25) { Change_Block(block_num,block_num+1); n++; } else if(point[block_num-5].num==25) { Change_Block(block_num,block_num-5); n++; } break; default: if(point[block_num-1].num==25) { Change_Block(block_num,block_num-1); n++; } else if(point[block_num+5].num==25) { Change_Block(block_num,block_num+5); n++; } else if(point[block_num+1].num==25) { Change_Block(block_num,block_num+1); n++; } else if(point[block_num-5].num==25) { Change_Block(block_num,block_num-5); n++; } } } break; default:; } MyPaint(); break; case WM_CLOSE: if(IDYES==MessageBox(hWnd,“真的不玩了?”,“提示”,MB_YESNO)) { DestroyWindow(hWnd); } break; case WM_DESTROY: int k; for(k=0;k<7;k++) { DeleteObject(pict[k]); DeleteObject(compare_pict[k]); } DeleteObject(compare_pic); DeleteObject(pic); DeleteObject(empty); ReleaseDC(hWnd,hdc); PostQuitMessage(0); break; default: return DefWindowProc(hWnd, message, wParam, lParam); } return 0; } void MyPaint() { SelectObject(mdc,empty); //贴上背景图 BitBlt(hdc,600,0,487,526,mdc,200,0,SRCCOPY); SelectObject(mdc,compare_pic); //贴上参照图 BitBlt(hdc,617,0,450,360,mdc,0,0,SRCCOPY); sprintf(str,“%d”,n); //显示移动步数 TextOut(hdc,817,433,str,strlen(str)); if(3==line) { sprintf(str,“%d”,high3); //在其位置显示最高记录 TextOut(hdc,1007,433,str,strlen(str)); if(new3) //如果要重排 { GetPos(); //重排 new3=false; } SelectObject(mdc,pic); for(int i=1;i<=9;i++) { switch(i) //按属性贴图 { case 1: BitBlt(hdc,0,0,200,160,mdc,point[i].x,point[i].y,SRCCOPY); break; case 2: BitBlt(hdc,200,0,200,160,mdc,point[i].x,point[i].y,SRCCOPY); break; case 3: BitBlt(hdc,400,0,200,160,mdc,point[i].x,point[i].y,SRCCOPY); break; case 4: BitBlt(hdc,0,160,200,160,mdc,point[i].x,point[i].y,SRCCOPY); break; case 5: BitBlt(hdc,200,160,200,160,mdc,point[i].x,point[i].y,SRCCOPY); break; case 6: BitBlt(hdc,400,160,200,160,mdc,point[i].x,point[i].y,SRCCOPY); break; case 7: BitBlt(hdc,0,320,200,160,mdc,point[i].x,point[i].y,SRCCOPY); break; case 8: BitBlt(hdc,200,320,200,160,mdc,point[i].x,point[i].y,SRCCOPY); break; case 9: BitBlt(hdc,400,320,200,160,mdc,point[i].x,point[i].y,SRCCOPY); break; default: MessageBox(NULL,“贴图序列号错误!”,“”,NULL); } 2012年 9 月 1 日 目录 一题目及要求 二项目概述 三项目分析 四程序思路分析 五总结 六答辩记录 七教师意见 一 题目及要求 计算24点游戏 输入四个数,通过加减乘除计算出24,显示计算过程,并提示成功信息。二 项目概述 我设计的是24点游戏,它功能是输出给定4个数运算得出24的算式。大概思路很简单,就是穷举4个数字排列组合后的所算式,选择其中结果为24的,并筛选符合数学法则的输出,难点在于穷举 三项目分析 通过题目这是大家很熟悉的游戏,大家也都知道直接计算很难,想不出具体的算法,但考虑到计算机的特点——运算速度快,不知疲倦,我们可以另辟蹊径,让计算机算出所有与这4个数字相关的算式,选择其中得24的算输出即可。所以确定思路,穷举。大概分几个模块,主函数,转化四则运算的fun函数,for循环,if选择,scanf,printf。四 程序思路分析 程序要求给出4个数字,输出算出等于24的结果的所有算式,所以大体上首先scanf4个数字储存在数组中,然后试用定义的fun函数,fun函数为将4则运算 转化为数字的函数,然后用多个for语句实现数字的排列组合,关于括号的问题,分两种情况,一种是“三一”的,一种是“二二”的。然后写一个报错的语句,关于结果用printf输出,如果结果为-24,-1/24,1/24的,可以改变输出结果的顺序。 下面附上源程序: #include case 0:return(a1+a2); case 1:return(a1-a2); case 2:return(a1*a2); case 3:return(a1/a2);} } void main(){ int g;for(g=0;g<100;){ int i,j,k,l,n,m,r,save[4]; double num[4]={1,1,1,1},tem1,tem2,tem3,abc=1111; char sign[5]=“+-*/”; printf(“请输入4个数,数字与数字之间用空格隔开:”); for(i=0;i<4;i++) { scanf(“%lf”,num+i); save[i]=num[i]; } for(i=0;i<4;i++) for(j=0;j<4;j++) if(j!=i) { for(k=0;k<4;k++) if(k!=i&&k!=j) { for(l=0;l<4;l++) if(l!=i&&l!=j&&l!=k) { for(n=0;n<4;n++) for(m=0;m<4;m++) for(r=0;r<4;r++) { tem1=fun(num[i],num[j],n); tem2=fun(tem1,num[k],m); tem3=fun(tem2,num[l],r); if(tem3==24.0)printf(“{(%d%c%d)%c%d}%c%d=24n”,save[i],sign[n],save[j],sign[m],save[k],sign[r],save[l]); else if(tem3==-24.0)printf(“{%d%c(%d%c%d)}%c%d=24n”,save[k],sign[m],save[i],sign[n],save[j],sign[r],save[l]); else if(tem3==1.0/24.0)printf(“%d%c{(%d%c%d)%c%d}=24n”,save[l],sign[r],save[i],sign[n],save[j],sign[m],save[k]); else if(tem3==-1.0/24.0)printf(“%d%c{%d%c(%d%c%d)}=24n”,save[l],sign[r],save[k],sign[n],save[i],sign[m],save[j]); else { tem1=fun(num[i],num[j],n); tem2=fun(num[k],num[l],r); if(tem2 == 2 && m == 3) printf(“此处省略出现的一个非法运算n”); else { tem3=fun(tem1,tem2,m); if(tem3==24.0) printf(“(%d%c%d)%c(%d%c%d)=24n”,save[i],sign[n],save[j],sign[m],save[k],sign[r],save[l]); } } } } } } g++;} } 下面详细说明: double fun(double a1,double a2,int b)//定义fun函数 { switch(b) { case 0:return(a1+a2); case 1:return(a1-a2); case 2:return(a1*a2); case 3:return(a1/a2);} }用switch语句将四则运算转化。void main()定义主函数 int i,j,k,l,n,m,r,save[4]; double num[4]={1,1,1,1},tem1,tem2,tem3,abc=1111; char sign[5]=“+-*/”; printf(“请输入4个数,数字与数字之间用空格隔开:”); for(i=0;i<4;i++) { scanf(“%lf”,num+i);//输入语句 save[i]=num[i];} 定义参数,有fun函数转化四则运算,但需要将四则运算的符号存入字符数组中以便输出时使用。用for语句循环实现输入。 用两段语句分两种情况计算for(n=0;n<4;n++) for(m=0;m<4;m++) for(r=0;r<4;r++) { tem1=fun(num[i],num[j],n); tem2=fun(tem1,num[k],m); tem3=fun(tem2,num[l],r);for循环实现运算的排列组合,上面是一种情况(不带有括号的),下面是另一种 else { tem1=fun(num[i],num[j],n); tem2=fun(num[k],num[l],r);else 下面是两两组合的情况 {tem3=fun(tem1,tem2,m); if(tem3==24.0)printf(“(%d%c%d)%c(%d%c%d)=24n”,save[i],sign[n],save[j],sign[m],save[k],sign[r],save[l]); 用for和if语句实现数字的排列组合,for(i=0;i<4;i++)for(j=0;j<4;j++)if(j!=i){ for(k=0;k<4;k++)if(k!=i&&k!=j) { for(l=0;l<4;l++) if(l!=i&&l!=j&&l!=k) { 输出语句如下 if(tem3==24.0)printf(“{(%d%c%d)%c%d}%c%d=24n”,save[i],sign[n],save[j],sign[m],save[k],sign[r],save[l]); else if(tem3==-24.0)printf(“{%d%c(%d%c%d)}%c%d=24n”,save[k],sign[m],save[i],sign[n],save[j],sign[r],save[l]); else if(tem3==1.0/24.0)printf(“%d%c{(%d%c%d)%c%d}=24n”,save[l],sign[r],save[i],sign[n],save[j],sign[m],save[k]); else if(tem3==-1.0/24.0)printf(“%d%c{%d%c(%d%c%d)}=24n”,save[l],sign[r],save[k],sign[n],save[i],sign[m],save[j]);对于其他几种结果通过改变输出时变量的顺序即可。五 总结 通过这次学习,我学到了很多,这个程序的难度级别是B,不是很难,但是算法比较繁琐,考虑要细心才行。通过此次程序设计,也让我们把平时学的理论知识用在了实际问题上,有助于我们的理解和运用,而且这个程序设计本身也比较有趣,能激发我们自己去深入研究。 以上就是我对这次程序设计的心得体会,也希望在以后的专业课学习中能够充分利用计算机本身速度快的优势,利用编写程序完成一些用手工计算很难完成的问题。 张博禹 05111112 六 答辩记录 【C语言龟兔赛跑的小游戏】相关文章: c语言相关的小游戏08-01 c语言小游戏范文05-23 关于c语言的论文04-15 c语言中非的符号04-26 C语言的边界问题05-07 C语言课程的教学05-21 C/C++语言内存分配问题的探讨11-08 学习c语言的一些忠告05-15 龟兔赛跑的启示范文06-10篇2:C语言龟兔赛跑的小游戏
篇3:C语言龟兔赛跑的小游戏
篇4:C语言龟兔赛跑的小游戏
篇5:C语言~~自制拼图游戏
篇6:24点游戏 高质量C语言程序