1、C语言制作五子棋五子棋游戏是一个深受人们喜爱的游戏,通常是人机对弈,本程序设计为人与人对弈,一方执黑棋,一方执白棋,轮流走棋,每方都试图在游戏结束前让自己的棋子五子相连。按键盘上的方向键可以移动光标,回车键可以摆放棋子。一、设计目的这个程序是对编程基本功的一个训练,将分支、循环、数组、函数综合应用,而不仅限于编制独立的小程序,通过游戏过程增加编程的兴趣,提高编程水平。编制该程序我对以下的知识点进行的巩固和掌握:1.数组元素为结构体的数组应用。2.全局变量应用。3.按键的处理。4.数组元素与蛇、食物的对应关系。5.图形方式等等。虽然该程序是一个普通而又简单的程序,但是对于一C语言初级阶段的学生来
2、说,是一个很好的锻炼甚至可以说是一个很好的提高。二、设计思路棋盘设计为1919格,初始状态光标在棋盘的中央,白棋先走,轮流落子,当一方连成五子或下满棋盘时,游戏结束(连成五子的一方获胜,下满棋盘为和棋)。当游戏一方胜利后显示胜利信息,提示信息利用汉字点阵输出。从程序表面看,这是一个二维平面图,所以数据用二维数组来表示,数组两个下标可以表示棋盘上的位置,数组元素的值代表棋格上的状态,共有三种情况,分别是0代表空格,1代表白棋,2代表黑棋。这样程序的主要工作是接收棋手按键操作,棋手1用Up、Down、Left、Right控制光标移动,回车键表示落子。棋手2用W、S、A、D控制光标移动,空格键表示落
3、子。一旦接收到回车键或空格键,说明棋手落子,先判断是否是有效位置,也就是说已经有棋子的位置不能重叠落子。落子成功后,马上判断以该位置为中心的八个方向:上、下、左、右、左上、左下、右上、右下是否有相同颜色的棋子连成五子,如果连成五子,则游戏结束,输出相应的信息。如果想退出游戏,可以按Esc键。三、程序设计1定义全局变量1. intgamespeed=5000; 2. inti,j,key; 3. structSor 4. 5. intx; 6. inty;/*x,y表示当前光标的位置*/7. intyesNN;/*0表示无棋子,1表示白色棋子,2表示黑色棋子*/8. intkao;/*1表示白棋
4、准备落子,2表示黑棋落子*/9. intok;/*1表示白棋胜出,2表示黑棋胜出*/10. sor;2Main()主函数按照语法规则,首先定义使用到的常数、全局变量、函数原型说明。棋盘状态用数组yes2020,初值为0,表示空格。函数的实体比较简单,调用图形驱动、画棋盘、人人对弈等自定义函数,一旦游戏结束后,关闭图形驱动,程序结束。3drawqp()画棋盘函数背景颜色设为黑色,从坐标(100,100)开始每隔20个单位用绿色画一条水平直线,一条垂直线,构成棋盘,用循环语句实现。画线函数line()的参数为线的起点和终点坐标,注意要计算正确。函数setfillstyle()可以设置填充模式和填充
5、颜色,fillellipse(int x,int xradius,int yradius)以x和y为圆心,xradius和yradius为水平和垂直轴画一填充椭圆,当xradius和yradius相等时,则画出的是圆,用它表示棋子。4win()判断是否胜出函数本函数根据每次落子的位置,分别向上、下、左、右、左上、左下、右上、右下八个方向判断是否有相同颜色的棋子连成五子,如果成立,游戏就结束,并显示提示信息(如:红方获胜),否则继续落子。5Gameplay()双人对战函数这是游戏进行的函数,主要是接收棋手的按键消息,其处理过程如下:(1)按Esc键程序可以随时结束。(2)按上下左右光标键,则改变
6、棋子移动的坐标值。(3)按回车键后判断:1) 如落子的位置已经有棋则无效,继续按键。2) 如落子位置是空格,可以将棋子落入格内,调用win()函数。3) 如果棋子变化后,棋盘已下满了棋子,则游戏结束。显示平局信息。(4)重复上述步骤,直到游戏结束。6Xandy()显示光标纵横坐标函数该函数的作用是在每次移动光标后,在屏幕左下角显示出光标的纵横坐标。7图形功能函数以下函数原形都在graphics.h中。(1)registerbgidriver():(2)initgraph(int *driver, int *mode, char *path):用于初始化图形系统,并装入相应的图形驱动器。该函数把
7、由driver所指向的图形驱动器代码装入内存。如果图形驱动器未装入内存,图形函数将不能操作。图形函数所用的屏显模式由mode所指向的整数值确定。最后,图形驱动器的路径是由path所指向的字符串给出。如果没有指定路径,就在当前工作路径上寻找。(3)rectangle(int left,int top,int right,int bottom):函数rectangle()用当前画出由坐标left,top及right,bottom所定义的矩形。(4)setcolor(int color):把当前画线颜色设置为color所指定的颜色。每个图形显示卡的有效颜色由setpalette()提供。(5)clo
8、segraph():该函数使图形状态失效,并且释放用于保存图形驱动器和字体的系统内存。当你的程序既用到图形输出又用到非图形输出时,应该用此函数。该函数还把系统屏显模式返回到调用initgragh()前的状态。通过编制该程序我对以下的知识点进行的巩固和掌握:1.数组元素为结构体的数组应用。2.全局变量应用。3.按键的处理。4.图形方式等等。虽然该程序是一个普通而又简单的程序,但是对于一C语言初级阶段的学生来说,是一个很好的锻炼甚至可以说是一个很好的提高。由于个人能力的限制该程序还有许多的缺陷,若要进一步的完善还需要对C语言更深一步的学习。程序运行部分截图:1. #include 2. #defi
9、neN20 3. /*定义键盘*/4. #defineup0x4800 5. #definedown0x5000 6. #defineleft0x4b00 7. #defineright0x4d00 8. #defineesc0x011b 9. #defineenter0x1c0d 10. #defineA0x1e61 11. #defineS0x1f73 12. #defineD0x2064 13. #defineW0x1177 14. #definespace0x3920 15. #defineY0x1579 16. #definen0x316e 17. intgamespeed=5000
10、; 18. inti,j,key; 19. structSor 20. 21. intx; 22. inty;/*x,y表示当前光标的位置*/23. intyesNN;/*0表示无棋子,1表示白色棋子,2表示黑色棋子*/24. intkao;/*1表示白棋准备落子,2表示黑棋落子*/25. intok;/*1表示白棋胜出,2表示黑棋胜出*/26. sor; 27. 28. voidinit(void)/*graphdrive*/29. 30. intdriver=DETECT,mode=0; 31. registerbgidriver(EGAVGA_driver); 32. initgraph
11、(&driver,&mode,); 33. 34. 35. voiddrawmat(char*mat,intmatsize,intx,inty,intcolor) 36. 37. inti,j,k,m; 38. m=(matsize-1)/8+1; 39. for(j=0;jmatsize;j+) 40. for(i=0;im;i+) 41. for(k=0;kk) 43. putpixel(x+i*8+k,y+j,color); 44. 45. 46. voidshow(void)/*inputword*/47. 48. drawmat(wu64H,64,438,49,0); 49. dra
12、wmat(zi64H,64,488,49,0); 50. drawmat(qi64H,64,538,49,0); 51. 52. drawmat(wu64H,64,440,50,13); 53. drawmat(zi64H,64,490,50,13); 54. drawmat(qi64H,64,540,50,13); 55. 56. drawmat(zuo16H,16,480,450,8); 57. drawmat(zhe16H,16,498,450,8); 58. drawmat(tian16H,16,518,450,8); 59. drawmat(xue16H,16,536,450,8);
13、 60. drawmat(ke16H,16,554,450,8); 61. 62. 63. voiddrawqp(void)/*drawqipan*/64. 65. setcolor(3); 66. for(i=50;i=(N-1)*20+30;i+=20) 67. 68. line(50,i,(N-1)*20+30,i); 69. line(i,50,i,(N-1)*20+30); 70. 71. setcolor(11); 72. for(i=1;i3;i+) 73. 74. circle(N-1)*10+40,(N-1)*10+40,i); 75. circle(130,130,i);
14、76. circle(130,330,i); 77. circle(330,130,i); 78. circle(330,330,i); 79. 80. 81. 82. voidclew(void)/*inputmessage*/83. 84. setcolor(15); 85. settextstyle(0,0,1); 86. outtextxy(50,20,1P:UpDownLeftRightEnter2P:WSADSpace); 87. 88. 89. voidplace(void)/*画出光标的位置*/90. 91. line(sor.x-10,sor.y-10,sor.x-7,sor
15、.y-10); 92. line(sor.x-10,sor.y-10,sor.x-10,sor.y-7); 93. 94. line(sor.x-10,sor.y+10,sor.x-10,sor.y+7); 95. line(sor.x-10,sor.y+10,sor.x-7,sor.y+10); 96. 97. line(sor.x+10,sor.y-10,sor.x+10,sor.y-7); 98. line(sor.x+10,sor.y-10,sor.x+7,sor.y-10); 99. 100. line(sor.x+10,sor.y+10,sor.x+7,sor.y+10); 101
16、. line(sor.x+10,sor.y+10,sor.x+10,sor.y+7); 102. 103. 104. 105. voidwin(void)/*判断是否胜出*/106. 107. for(i=1;iN;i+) 108. 109. for(j=1;jN;j+) 110. 111. if(j+4)N&sor.yesij!=0& 112. sor.yesij=sor.yesij+1& 113. sor.yesij+1=sor.yesij+2& 114. sor.yesij+2=sor.yesij+3& 115. sor.yesij+3=sor.yesij+4)| 116. 117. (
17、i+4)N&sor.yesij!=0& 118. sor.yesij=sor.yesi+1j& 119. sor.yesi+1j=sor.yesi+2j& 120. sor.yesi+2j=sor.yesi+3j& 121. sor.yesi+3j=sor.yesi+4j)| 122. 123. (i+4)N&(j+4)N&sor.yesij!=0& 124. sor.yesij=sor.yesi+1j+1& 125. sor.yesi+1j+1=sor.yesi+2j+2& 126. sor.yesi+2j+2=sor.yesi+3j+3& 127. sor.yesi+3j+3=sor.ye
18、si+4j+4)| 128. 129. (i+4)4&sor.yesij!=0& 130. sor.yesij=sor.yesi+1j-1& 131. sor.yesi+1j-1=sor.yesi+2j-2& 132. sor.yesi+2j-2=sor.yesi+3j-3& 133. sor.yesi+3j-3=sor.yesi+4j-4) 134. 135. if(sor.yesij=1) 136. sor.ok=1; 137. else138. sor.ok=2; 139. break; 140. 141. 142. if(sor.ok!=0) 143. break; 144. 145.
19、 146. 147. voidgameover(void) 148. 149. if(sor.ok=1) 150. 151. drawmat(bai64H,64,488,119,0); 152. drawmat(bai64H,64,490,120,4); 153. 154. else155. 156. drawmat(hong64H,64,488,119,0); 157. drawmat(hong64H,64,490,120,4); 158. 159. 160. drawmat(fang64H,64,488,189,0); 161. drawmat(huo64H,64,488,259,0);
20、162. drawmat(sheng64H,64,488,329,0); 163. 164. drawmat(fang64H,64,490,190,4); 165. drawmat(huo64H,64,490,260,4); 166. drawmat(sheng64H,64,490,330,4); 167. 168. 169. voidxandy(void)/*显示光标的横纵坐标*/170. 171. charstr110,str210; 172. setfillstyle(SOLID_FILL,7); 173. bar(50,440,205,470); 174. setcolor(14);
21、175. settextstyle(0,0,2); 176. sprintf(str1,X:%d,(sor.x-30)/20); 177. sprintf(str2,Y:%d,(sor.y-30)/20); 178. outtextxy(60,450,str1); 179. outtextxy(135,450,str2); 180. 181. 182. voidgameplay(void) 183. 184. for(i=1;iN;i+)/*棋盘初始化*/185. for(j=1;j50&sor.kao=1) 203. 204. setcolor(0);place(); 205. sor.y-
22、=20; 206. 207. elseif(key=down&sor.y50&sor.kao=1) 213. 214. setcolor(0);place(); 215. sor.x-=20; 216. 217. elseif(key=right&sor.x50&sor.kao=2) 225. 226. setcolor(0);place(); 227. sor.y-=20; 228. 229. elseif(key=S&sor.y50&sor.kao=2) 235. 236. setcolor(0);place(); 237. sor.x-=20; 238. 239. elseif(key=
23、D&sor.x(N-1)*20+30&sor.kao=2) 240. 241. setcolor(0);place(); 242. sor.x+=20; 243. 244. elseif(key=space&sor.yes(sor.x-30)/20(sor.y-30)/20=0&sor.kao=2) 245. 246. setcolor(13); 247. for(i=1;i=9;i+) 248. 249. circle(sor.x,sor.y,i); 250. delay(10000); 251. 252. sor.yes(sor.x-30)/20(sor.y-30)/20=2; 253.
24、sor.kao=1; 254. win(); 255. if(sor.ok!=0) 256. 257. gameover(); 258. break; 259. 260. 261. elseif(key=enter&sor.yes(sor.x-30)/20(sor.y-30)/20=0&sor.kao=1) 262. 263. setcolor(15); 264. for(i=1;i=9;i+) 265. 266. circle(sor.x,sor.y,i); 267. delay(10000); 268. 269. sor.yes(sor.x-30)/20(sor.y-30)/20=1; 2
25、70. &贪食蛇(1)1. /* 2. /Project:RedSnake(贪吃蛇) 3. /Author:RedOC 4. /Email:RedOC 5. /Date:2009.06.2723.42.02 6. */7. 8. #include 9. #include 10. #include 11. #includepcc32.h 12. 13. /定义地图的尺寸及坐标(均使用双字符长度) 14. #defineMAP_WIDTH24 15. #defineMAP_HEIGHT16 16. #defineMAP_BASE_X1 17. #defineMAP_BASE_Y1 18. 19.
26、/定义蛇的相关参数 20. #defineSNAKE_MIN_LEN5 21. 22. /定义地图块的状态,分别为空格|蛇头|蛇身|食物 23. #defineBS_SPACE0 24. #defineBS_SHEAD1 25. #defineBS_SBODY2 26. #defineBS_STAIL3 27. #defineBS_FOOD4 28. 29. /定义各对象的颜色,颜色定义详见pcc32.h,顺序同上. 30. PCCOLORmyColors=ORANGE,RED_ORANGE,RED,LIGHT_GREEN,YELLOW; 31. 32. /定义各对象的形状,注意是宽字符,顺序
27、同上. 33. charmySharps3=,; 34. 35. /定义蛇的运动方向上|下|左|右 36. #defineDIR_UP1 37. #defineDIR_DOWN2 38. #defineDIR_LEFT3 39. #defineDIR_RIGHT4 40. 41. typedefstruct_SnakeBody 42. 43. uint8x,y; 44. POINT2D,*PPOINT2D; 45. 46. POINT2DmySnakeMAP_WIDTH*MAP_HEIGHT=0; 47. POINT2DmyFood=0; 48. intsnakeLength=0; 49. i
28、ntsnakeDir=DIR_RIGHT; 50. intisFood=0; 51. intisOver=0; 52. 53. voiddrawMap(void); 54. voidinitSnake(intlen); 55. voiddrawSnake(void); 56. voidmoveSnake(void); 57. voiddrawBlock(intx,inty,intbs); 58. intisInSnake(intx,inty); 59. voiddrawFood(void); 60. 61. intmain() 62. 63. intisPause=1; 64. fixCons
29、oleSize(MAP_WIDTH+2)*2,MAP_HEIGHT+2); 65. setCursorVisible(0); 66. setConsoleTitle(SnakebyRedOC.2009.06.27); 67. initSnake(SNAKE_MIN_LEN); 68. drawMap(); 69. drawSnake(); 70. while(!isOver) 71. 72. if(!isPause) 73. 74. moveSnake(); 75. if(!isFood) 76. drawFood(); 77. 78. delayMS(200-snakeLength*2);
30、79. if(jkHasKey() 80. 81. switch(jkGetKey() 82. 83. caseJK_UP: 84. if(snakeDir!=DIR_DOWN) 85. snakeDir=DIR_UP; 86. break; 87. caseJK_DOWN: 88. if(snakeDir!=DIR_UP) 89. snakeDir=DIR_DOWN; 90. break; 91. caseJK_LEFT: 92. if(snakeDir!=DIR_RIGHT) 93. snakeDir=DIR_LEFT; 94. break; 95. caseJK_RIGHT: 96. i
31、f(snakeDir!=DIR_LEFT) 97. snakeDir=DIR_RIGHT; 98. break; 99. caseJK_ESC: 100. caseJK_ENTER: 101. caseJK_SPACE: 102. isPause=!isPause; 103. break; 104. default: 105. break; 106. 107. 108. 109. gotoTextPos(MAP_BASE_X+MAP_WIDTH/2+2,MAP_BASE_Y+MAP_HEIGHT/2); 110. printf(GameOver!Score:%d.,snakeLength-SNAKE_MIN_LEN); 111. getch(); 112. return0; 113. 114. 115. voiddrawMap(void) 116. 117. inti,j; 118. setTextColor(myColorsBS_SPACE); 119. for(i=0;iMAP_HEIGHT;i+) 120.