用C语言实现中国象棋


基于五子棋框架上的 象棋 小游戏

本游戏是上各种水课无聊时的产物。。。不参考现有游戏从零开始实现各项功能。

游戏配置:二维数组,循环系统,wasd基本移动,调整窗台的函数,以及富足的发呆时间。。

完整代码

代码已和五子棋整合在此链接中https://paste.ubuntu.com/p/HZBWXMWT8K/

github链接:https://github.com/404name/C-game

主体进展: (全部实现)

  1. o 搭建框架中

  2. o 实现全局指标移动

  3. o 实现中文(2个字符)同时移动

  4. o 实现象棋棋子取子与放回

  5. o 实现判断回合

  6. o 实现后台判断每一个棋子

  7. o 定义全局规则

  8. o 定义每一个棋子的规则

  9. o 调bug

用C语言实现中国象棋

<!--more-->

前言: 走迷宫 - 五子棋 -象棋

本游戏基于我之前做的   基于走迷宫的五子棋的游戏   之上,本质上都是靠基础的知识点穿插而成的。

五子棋是只下棋,象棋是先取后下,并且取棋子后台要能识别它是哪方的哪个棋,并根据规

则能正确下落在合法的点上。并且下落后判断游戏是否继续。

解决问题过程

1.凭空搭建一个一模一样的象棋棋盘模型

一步一步慢慢的敲与改进最后终于符合棋盘原样。(一开始''\' 就是打不出本来要放弃这个布局,后来记起书上说过转义符   )

2.实现取棋子和下棋

当我布置好棋盘,按好棋子,设置好移动距离调适时,一个惊人的现实摆在了我的面前——汉字占两个字节。这个时候,愁苦之时,发现我实现五子棋单个字符移动的原理(设置temp储存指针所在坐标状态,不改变情况下显示指针状态,指针移开恢复temp原坐标原状)只要设置两个temp和2个指针状态就能同时实现2个坐标的改变!!

ch = getch();
   if ( ch == 's')                     //下移
  {
       if( map[x+1][y]!= '-')
      {                                 //将要移动
           map[x][y] =temp;             //恢复移动前坐标状态
           map[x][y+1] = temp1;
           x = x + 2;                 //移动
           temp = map[x][y];         //储存新坐标状态  
           temp1 = map[x][y+1];
           map[x][y] = turn;    //turn即鼠标指针(拿起棋子)的状态
           map[x][y+1] = turn1;   //把鼠标指针状态打印在新的坐标上    
      }      
  }                            //后续选择移动   原坐标恢复,循环。
//后续选择下棋   将turn给temp 下一次移动时map则存储棋子并显现。
3.实现后台判断双方次序,与下棋;

按下 “L” 则num++

第一次按下  先手方取棋    num = 1;第二次按下   先手方下棋  num = 2;

第三次按下  后手方取棋    num = 3; 第四次按下  后手方下棋 num = 4;

设置规律4次一循环即可判断;

要是取了棋又放回呢?

  • printf 就是不允许悔棋。一开始我是这么想的,给自己找个理由偷懒。马上就想到了这样会某些特殊群体(马,相)容易卡死导致棋局作废。。

  • *改进 取临时坐标 与 新坐标比较,判断放回则还是提醒下少悔棋,并num--回到上一步变成空鼠标状态继续选其他棋子。其实也蛮简单实现。。

4.实现取棋子的识别与判断是否可下棋(第一次没考虑,直接拿我的士吃了我的将军。。)

暴力循环判断法。。

char check—1【8】【3】={"车","马","象","士","将","炮","卒","+-"};    //这里的+-是棋盘上的空位
char check_—2【8】【3】={"俥","馬","相","仕","帥","軳","兵","+-"};

鼠标指针所在坐标的临时temp(原坐标棋子)循环比较一波就知道了,并且提示“这不是你的棋子喔” ,使取对方棋子的举动无效。再与后续规则合并可实现许多其他规则。

定义check函数判断是下棋点位是空位与对方棋子在符合棋子规则走法情况下则可下吃。

这里说下这里的妙处

  • 定义函数可在14种棋子规则移动后调用判断,缩短代码量。

  • 二维数组储存信息量是8,这里取棋时循环判断是否为己方7位(即棋子),下棋时判断是否是对方8位(即对方的棋子与空位)

5.定义每一个棋子的规则(伤脑筋的地方)(易到难)

每个棋子都是3个依次的判断:

o 是否改变坐标(比较)

o 是否符合该棋子规则(下面介绍)

o 终点是否可下棋(调用上面说的check函数)

  • 车:保证走直线, x,y仅能改变一个值,并且for循环新坐标到原坐标中间是否全是空格,是则终点进入check函数,判断可否执行。

  • 象:不能过河,那就简单设定7个可移动坐标点位,且保证每次只移动一个田字。且两次坐标中间坐标要为空格。

  • 士:同理“象”设定;

  • 将:同理“士”的设定;

  • 兵:河后只能向前,过河可前可左右

  • 马:走日字,判断走了2个单位的方向的正前方是否为空格。(判断卡马脚)

  • 炮:同理车的直线走法,若不跳跃则仅能走空格,若跳跃判断中间仅一个棋子,且落点必须是对方棋子。

其实实现起来会发现你怎样思考,都能用计算机取模拟出来,做出这个棋局规定很简单,但能不能让它高效的运行起来才是最困难的。最痛苦的还是debug过程,,因为这时候已经800多行了qwq。。。

还好思路没错,几乎没啥bug。

定义胜利规则

把 将 卡死在9个点位上,每次下棋后循环判断它是否在,

不存在:   对方胜利

存在: 判断是否对将

对将: 记录其坐标与对方的 帥的坐标对比,若x方向对上了,且这条直线上是否都为空格,则上把谁下的棋则谁输。

后续

不足之处

1.代码不够简洁

2.不能简单明了的区分双方棋子。(尝试了各种方法最后还是用简体字与繁体字区分)

3.ing

收获

1.看几百行的代码再也不头晕了。

2.灵活运用c语言可以实现好多实例。

3.还要提升c语言的准确表达做到更精简的写代码。

上一篇:C/C++编程笔记:C语言打造中国象棋游戏,项目源代码分享!


下一篇:POJ1064