搜索
查看: 381|回复: 0
打印 上一主题 下一主题

为什么不能正常运行

[复制链接]
跳转到指定楼层
楼主
 楼主| 发表于 2021-1-16 17:54:25 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
5啊哈币

  1.     #include <stdlib.h>

  2. #include <stdio.h>
  3. #include <conio.h>
  4. #include <string.h>




  5. #define MAXIMUS 15 //定义棋盘大小




  6. int p[MAXIMUS][MAXIMUS];//存储对局信息
  7. char buff[MAXIMUS*2+1][MAXIMUS*4+3];//输出缓冲器
  8. int Cx,Cy;//当前光标位置
  9. int Now;//当前走子的玩家,1代表黑,2代表白
  10. int wl,wp;//当前写入缓冲器的列数和行数位置
  11. char* showText;//在棋盘中央显示的文字信息
  12. int count;//回合数




  13. char* Copy(char* strDest,const char* strSrc)//修改过的字符串复制函数,会忽略末端的
  14. {
  15. char* strDestCopy = strDest;
  16. while (*strSrc!='')
  17. {
  18. *strDest++=*strSrc++;
  19. }
  20. return strDestCopy;
  21. }
  22. void Initialize()//初始化一个对局函数
  23. {
  24. int i,j;//循环变量
  25. showText="";//重置显示信息
  26. count=0;//回合数归零
  27. for(i=0;i<MAXIMUS;i++)//重置对局数据
  28. {
  29. for(j=0;j<MAXIMUS;j++)
  30. {
  31. p[i][j]=0;
  32. }
  33. }
  34. Cx=Cy=MAXIMUS/2;//重置光标到中央
  35. Now=1;//重置当前为黑方
  36. }
  37. char* getStyle(int i,int j)//获得棋盘中指定坐标交点位置的字符,通过制表符拼成棋盘
  38. {
  39. if(p[i][j]==1)//1为黑子
  40. return "●";
  41. else if(p[i][j]==2)//2为白子
  42. return "○";
  43. else if(i==0&&j==0)//以下为边缘棋盘样式
  44. return "┏";
  45. else if(i==MAXIMUS-1&&j==0)
  46. return "┓";
  47. else if(i==MAXIMUS-1&&j==MAXIMUS-1)
  48. return "┛";
  49. else if(i==0&&j==MAXIMUS-1)
  50. return "┗";
  51. else if(i==0)
  52. return "┠";
  53. else if(i==MAXIMUS-1)
  54. return "┨";
  55. else if(j==0)
  56. return "┯";
  57. else if(j==MAXIMUS-1)
  58. return "┷";
  59. return "┼";//中间的空位
  60. }
  61. char* getCurse(int i,int j){//获得指定坐标交点位置左上格的样式,通过制表符来模拟光标的显示
  62. if(i==Cx){
  63. if(j==Cy)
  64. return "┏";
  65. else if (j==Cy+1)
  66. return "┗";
  67. }
  68. else if(i==Cx+1)
  69. {
  70. if(j==Cy)
  71. return "┓";
  72. else if (j==Cy+1)
  73. return "┛";
  74. }
  75. return " ";//如果不在光标附近则为空
  76. }
  77. void write(char* c)//向缓冲器写入字符串
  78. {
  79. Copy(buff[wl]+wp,c);
  80. wp+=strlen(c);
  81. }
  82. void ln()//缓冲器写入位置提行
  83. {
  84. wl+=1;
  85. wp=0;
  86. }
  87. void Display()//将缓冲器内容输出到屏幕
  88. {
  89. int i,l=strlen(showText);//循环变量,中间文字信息的长度
  90. int Offset=MAXIMUS*2+2-l/2;//算出中间文字信息居中显示所在的横坐标位置
  91. if(Offset%2==1)//如果位置为奇数,则移动到偶数,避免混乱
  92. {
  93. Offset--;
  94. }
  95. Copy(buff[MAXIMUS]+Offset,showText);//讲中间文字信息复制到缓冲器
  96. if(l%2==1)//如果中间文字长度为半角奇数,则补上空格,避免混乱
  97. {
  98. *(buff[MAXIMUS]+Offset+l)=0x20;
  99. }
  100. system("cls");//清理屏幕,准备写入
  101. for(i=0;i<MAXIMUS*2+1;i++){//循环写入每一行
  102. printf("%s",buff[i]);
  103. if(i<MAXIMUS*2)//写入完每一行需要换行
  104. printf("");
  105. }
  106. }
  107. void Print()//将整个棋盘算出并储存到缓冲器,然后调用Display函数显示出来
  108. {
  109. int i,j;//循环变量
  110. wl=0;
  111. wp=0;
  112. for(j=0;j<=MAXIMUS;j++)//写入出交点左上角的字符,因为需要打印棋盘右下角,所以很以横纵各多一次循环
  113. {
  114. for(i=0;i<=MAXIMUS;i++)
  115. {
  116. write(getCurse(i,j));//写入左上角字符
  117. if(j==0||j==MAXIMUS)//如果是棋上下盘边缘则没有连接的竖线,用空格填充位置
  118. {
  119. if(i!=MAXIMUS)
  120. write(" ");
  121. }
  122. else//如果在棋盘中间则用竖线承接上下
  123. {
  124. if(i==0||i==MAXIMUS-1)//左右边缘的竖线更粗
  125. write("┃");
  126. else if(i!=MAXIMUS)//中间的竖线
  127. write("│");
  128. }
  129. }
  130. if(j==MAXIMUS)//如果是最后一次循环,则只需要处理边侧字符,交点要少一排
  131. {
  132. break;
  133. }
  134. ln();//提行开始打印交点内容
  135. write(" ");//用空位补齐位置
  136. for(i=0;i<MAXIMUS;i++)//按横坐标循环正常的次数
  137. {
  138. write(getStyle(i,j));//写入交点字符
  139. if(i!=MAXIMUS-1)//如果不在最右侧则补充一个横线承接左右
  140. {
  141. if(j==0||j==MAXIMUS-1)
  142. {
  143. write("━");//上下边缘的横线更粗
  144. }
  145. else
  146. {
  147. write("—");//中间的横线
  148. }
  149. }
  150. }
  151. ln();//写完一行后提行
  152. }
  153. Display();//将缓冲器内容输出到屏幕
  154. }
  155. int Put(){//在当前光标位置走子,如果非空,则返回0表示失败
  156. if(p[Cx][Cy]==0)
  157. {
  158. p[Cx][Cy]=Now;//改变该位置数据
  159. return 1;//返回1表示成功
  160. }
  161. else
  162. {
  163. return 0;
  164. }
  165. }
  166. int Check()//胜负检查,即判断当前走子位置有没有造成五连珠的情况
  167. {
  168. int w=1,x=1,y=1,z=1,i;//累计横竖正斜反邪四个方向的连续相同棋子数目
  169. for(i=1;i<5;i++)if(Cy+i<MAXIMUS&&p[Cx][Cy+i]==Now)w++;else break;//向下检查
  170. for(i=1;i<5;i++)if(Cy-i>0&&p[Cx][Cy-i]==Now)w++;else break;//向上检查
  171. if(w>=5)return Now;//若果达到5个则判断当前走子玩家为赢家
  172. for(i=1;i<5;i++)if(Cx+i<MAXIMUS&&p[Cx+i][Cy]==Now)x++;else break;//向右检查
  173. for(i=1;i<5;i++)if(Cx-i>0&&p[Cx-i][Cy]==Now)x++;else break;//向左检查
  174. if(x>=5)return Now;//若果达到5个则判断当前走子玩家为赢家
  175. for(i=1;i<5;i++)if(Cx+i<MAXIMUS&&Cy+i<MAXIMUS&&p[Cx+i][Cy+i]==Now)y++;else break;//向右下检查
  176. for(i=1;i<5;i++)if(Cx-i>0&&Cy-i>0&&p[Cx-i][Cy-i]==Now)y++;else break;//向左上检查
  177. if(y>=5)return Now;//若果达到5个则判断当前走子玩家为赢家
  178. for(i=1;i<5;i++)if(Cx+i<MAXIMUS&&Cy-i>0&&p[Cx+i][Cy-i]==Now)z++;else break;//向右上检查
  179. for(i=1;i<5;i++)if(Cx-i>0&&Cy+i<MAXIMUS&&p[Cx-i][Cy+i]==Now)z++;else break;//向左下检查
  180. if(z>=5)return Now;//若果达到5个则判断当前走子玩家为赢家
  181. return 0;//若没有检查到五连珠,则返回0表示还没有玩家达成胜利
  182. }
  183. int RunGame()//进行整个对局,返回赢家信息(虽然有用上)
  184. {
  185. int input;//输入变量
  186. int victor;//赢家信息
  187. Initialize();//初始化对局
  188. while(1){//开始无限回合的死循环,直到出现胜利跳出
  189. Print();//打印棋盘
  190. input=getch();//等待键盘按下一个字符
  191. if(input==27)//如果是ESC则退出程序
  192. {
  193. exit(0);
  194. }
  195. else if(input==0x20)//如果是空格则开始走子
  196. {
  197. if(Put())//如果走子成功则判断胜负
  198. {
  199. victor=Check();
  200. Now=3-Now;//轮换当前走子玩家
  201. count++;
  202. if(victor==1)//如果黑方达到胜利,显示提示文字并等待一次按键,返回胜利信息
  203. {
  204. showText="黑方获得了胜利!";
  205. Print();
  206. if(getch()==0xE0)
  207. {
  208. getch();
  209. }
  210. return Now;
  211. }
  212. else if(victor==2)//如果白方达到胜利,显示提示文字并等待一次按键,返回胜利信息
  213. {
  214. showText="白方获得了胜利!";
  215. Display();
  216. if(getch()==0xE0)
  217. {
  218. getch();
  219. }
  220. return Now;
  221. }else if(count==MAXIMUS*MAXIMUS)//如果回合数达到了棋盘总量,即棋盘充满,即为平局
  222. {
  223. showText="平局!";
  224. Display();
  225. if(getch()==0xE0)
  226. {
  227. getch();
  228. }
  229. return 0;
  230. }
  231. }
  232. }
  233. else if(input==0xE0)//如果按下的是方向键,会填充两次输入,第一次为0xE0表示按下的是控制键
  234. {
  235. input=getch();//获得第二次输入信息
  236. switch(input)//判断方向键方向并移动光标位置
  237. {
  238. case 0x4B://
  239. Cx--;
  240. break;
  241. case 0x48:
  242. Cy--;
  243. break;
  244. case 0x4D:
  245. Cx++;
  246. break;
  247. case 0x50:
  248. Cy++;
  249. break;
  250. }
  251. if(Cx<0)Cx=MAXIMUS-1;//如果光标位置越界则移动到对侧
  252. if(Cy<0)Cy=MAXIMUS-1;
  253. if(Cx>MAXIMUS-1)Cx=0;
  254. if(Cy>MAXIMUS-1)Cy=0;
  255. }
  256. }
  257. }
  258. int main()//主函数
  259. {
  260. system("title 简易五子棋 ——Etsnarl制作");//设置标题
  261. system("mode con cols=63 lines=32");//设置窗口大小
  262. system("color A1");//设置颜色
  263. while(1){//循环执行游戏
  264. RunGame();
  265. }
  266. }
复制代码

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

广播台
特别关注
快速回复 返回顶部 返回列表