c#开发技术 中国象棋(单机)

前言

该中国象棋为单机版程序,实现了全部的象棋走棋,并且实现了悔棋,落子标记等功能。唯一不足的是,该程序没有实现联机功能,后续有时间持续跟进的。

界面效果图

在这里插入图片描述

图1

部分代码

 //棋子的行走规则
public bool RulesForChess(int row, int col)
 {
     bool tempCanDrop = false;

     //判断是否落在原处
     if (row == _pickRow && col == _pickCol)
         tempCanDrop = false;

     else
     {
         //象的走棋规则
         if (_pickChess == Piece.蓝象)
         {
             //如果走田子,不绊象脚
             if (Math.Abs(_pickRow - row) == 2 && Math.Abs(_pickCol - col) == 2
                 && _chess[(_pickRow + row) / 2, (_pickCol + col) / 2] == Piece.无子 && row <= 5)
                 tempCanDrop = true;
         }
         //象的走棋规则
         else if (_pickChess == Piece.红相)
         {
             //如果走田子,不绊象脚
             if (Math.Abs(_pickRow - row) == 2 && Math.Abs(_pickCol - col) == 2
                 && _chess[(_pickRow + row) / 2, (_pickCol + col) / 2] == Piece.无子 && row >= 6)
                 tempCanDrop = true;
         }

         //马的走棋规则
         else if (_pickChess == Piece.红马 || _pickChess == Piece.蓝马)
         {
             //如果横着走日字,且不绊马脚
             if (Math.Abs(_pickRow - row) == 1 && Math.Abs(_pickCol - col) == 2 &&
                 _chess[_pickRow, (_pickCol + col) / 2] == Piece.无子)
                 tempCanDrop = true;

             //如果竖着走日字,且不绊马脚
             else if (Math.Abs(_pickRow - row) == 2 && Math.Abs(_pickCol - col) == 1 &&
                 _chess[(_pickRow + row) / 2, _pickCol] == Piece.无子)
                 tempCanDrop = true;
         }

         //车的行走规则
         else if (_pickChess == Piece.红车 || _pickChess == Piece.蓝车)
         {
             //如果车横着走
             if (_pickRow == row)
             {
                 //比较起点列和落点列的大小
                 int max = col > _pickCol ? col : _pickCol;
                 int min = col > _pickCol ? _pickCol : col;

                 //统计移动路径上棋子的数量
                 int chessNum = 0;
                 for (int i = min + 1; i <= max - 1; i++)
                     if (_chess[row, i] != Piece.无子)
                         chessNum++;
                 //当移动路径上棋子数量为0时,才允许落子
                 if (chessNum == 0)
                 { 
                     //落子点为无子或对方棋子
                     if (_chess[row, col] == Piece.无子 || _chess[row, col].ToString().IndexOf(_curPlayer.ToString()) == -1)
                         tempCanDrop = true;
                 }  
             }
             //如果车竖着走
             else if (_pickCol == col)
             {
                 //比较起点行和落点行的大小
                 int max = row > _pickRow ? row : _pickRow;
                 int min = row > _pickRow ? _pickRow : row;

                 //统计移动路径上棋子的数量
                 int chessNum = 0;
                 for (int i = min + 1; i <= max - 1; i++)
                     if (_chess[i, col] != Piece.无子)
                         chessNum++;
                 //当移动路径上棋子数量为0时,才允许落子
                 if (chessNum == 0)
                 {
                     //落子点为无子或对方棋子
                     if (_chess[row, col] == Piece.无子 || _chess[row, col].ToString().IndexOf(_curPlayer.ToString()) == -1)
                         tempCanDrop = true;
                 } 
             }
         }

         //士的行走规则
         else if (_pickChess == Piece.红士)
         { 
             //斜着走
             if(row >= 8 && col <= 6 && col >= 4 && Math.Abs(row - _pickRow) == 1 && Math.Abs(col - _pickCol) == 1)
                 tempCanDrop = true;
         }
         //士的行走规则
         else if (_pickChess == Piece.蓝士)
         {
             //斜着走
             if (row <= 3 && col <= 6 && col >= 4 && Math.Abs(row - _pickRow) == 1 && Math.Abs(col - _pickCol) == 1)
                 tempCanDrop = true;
         }

         //帅或将的行走规则
         else if (_pickChess == Piece.红帅)
         { 
             if(row >= 8 && col >= 4 && col <= 6 && (Math.Abs(row - _pickRow) == 1 && Math.Abs(col - _pickCol) == 0 || 
                 Math.Abs(row - _pickRow) == 0 && Math.Abs(col - _pickCol) == 1))
                 tempCanDrop = true;
         }
         //帅或将的行走规则
         else if (_pickChess == Piece.蓝将)
         {
             if (row <= 3 && col >= 4 && col <= 6 && (Math.Abs(row - _pickRow) == 1 && Math.Abs(col - _pickCol) == 0 ||
                 Math.Abs(row - _pickRow) == 0 && Math.Abs(col - _pickCol) == 1))
                 tempCanDrop = true;
         }

         //炮的行走规则
         else if (_pickChess == Piece.红炮 || _pickChess == Piece.蓝炮)
         { 
             //如果是竖着走
             if (_pickCol == col)
             {
                 //比较起点行和落点行的大小
                 int max = row > _pickRow ? row : _pickRow;
                 int min = row > _pickRow ? _pickRow : row;

                 //统计移动路径上棋子的数量
                 int chessNum = 0;
                 for (int i = min + 1; i <= max - 1; i++)
                     if (_chess[i, col] != Piece.无子)
                         chessNum++;
                 //当移动路径上棋子数量为0时,落子点为无子
                 if (chessNum == 0 && _chess[row, col] == Piece.无子)
                     tempCanDrop = true;

                 //当移动路径上棋子数量为1时,落子点为对方棋子
                 else if(chessNum == 1 && _chess[row, col] != Piece.无子 && _chess[row, col].ToString().IndexOf(_curPlayer.ToString()) == -1)
                     tempCanDrop = true;
             }

             //如果是横着走
             else if (_pickRow == row)
             {
                 //比较起点行和落点行的大小
                 int max = col > _pickCol ? col : _pickCol;
                 int min = col > _pickCol ? _pickCol : col;

                 //统计移动路径上棋子的数量
                 int chessNum = 0;
                 for (int i = min + 1; i <= max - 1; i++)
                     if (_chess[row, i] != Piece.无子)
                         chessNum++;
                 //当移动路径上棋子数量为0时,落子点为无子
                 if (chessNum == 0 && _chess[row, col] == Piece.无子)
                     tempCanDrop = true;

                 //当移动路径上棋子数量为1时,落子点为对方棋子
                 else if (chessNum == 1 && _chess[row, col] != Piece.无子 && _chess[row, col].ToString().IndexOf(_curPlayer.ToString()) == -1)
                     tempCanDrop = true;
             }
         }

         //兵或卒的行走规则
         else if (_pickChess == Piece.红卒)
         {
             //如果过了河界
             if (_pickRow <= 5 && row <= _pickRow && (Math.Abs(row - _pickRow) == 1 && Math.Abs(col - _pickCol) == 0 || Math.Abs(row - _pickRow) == 0 && Math.Abs(col - _pickCol) == 1))
                 tempCanDrop = true;
             //没有过河界
             else if(row < _pickRow && (Math.Abs(row - _pickRow) == 1 && Math.Abs(col - _pickCol) == 0))
                 tempCanDrop = true;

         }
         //兵或卒的行走规则
         else if (_pickChess == Piece.蓝兵)
         {
             //如果过了河界
             if (_pickRow >= 6 && row >= _pickRow && (Math.Abs(row - _pickRow) == 1 && Math.Abs(col - _pickCol) == 0 || Math.Abs(row - _pickRow) == 0 && Math.Abs(col - _pickCol) == 1))
                 tempCanDrop = true;
             //没有过河界
             else if (row > _pickRow && (Math.Abs(row - _pickRow) == 1 && Math.Abs(col - _pickCol) == 0))
                 tempCanDrop = true;
         }
     }

     return tempCanDrop;
 }

完整文件

中国象棋程序

功能介绍:<br/> * 本上传软件仅为爱好编程的同仁C#学习之用. <br/> <br/> a. 支持单人/双人游戏; 在开局中任意时刻可以切换单人/双人状态. <br/> b. 音效支持;有三首背景音乐,前台走棋音乐多样,如果您仔细观察的话,连拖动旗子的声音也有了:).<br/> c. 能够自定义残局; 通过*.ini配置文件增加了多个残局棋局.<br/> d. 保存. 能够实现动态保存功能,在下棋过程中能够保存当前下棋棋盘布局状态; 并在任意时刻恢复您保存的状态.<br/> e. 防止作弊. 程式严格控制了没个旗子的走发,比如:卒在过诃之前只能够进攻,过了诃才能够左右移动以及不能够一方连续走棋. <br/> f. 支持键盘鼠标两种操作方式; 双人下棋是一人使用鼠标,一人使用键盘操作最佳!<br/> g. 比较好的智能提示. 即使对象棋规则不台熟悉的人也可以很好的根据提示走棋,比如:当一方走棋后,它会自动提示另一方再走棋;当拿起旗子后,它回自动提示该位置是否可以落棋, 当落棋后它会提示您走了哪个旗子. 下棋结束会有得分和分析当前旗子损失率等.<br/> h. 有点不足的是电脑走棋比较苯,不过这也无妨影响学习大碍. 程式里面用到了许多C#技术细节方面,比如: Graphics,Sound,Repaint Control(Change picture to round),KeyDownPress,MouseClick/Move/Down/Drag picture,game save(Serialization),operate setting file etc.<br/><br/>扩展功能:<br/> i. 重新设计了所有旗子, 选择新的旗盘背景, 换了一个更清爽的面.(界面配色并不是件很容易的事情, 这样的棋类游戏长时间容易使眼睛疲劳, 首先要做到选择的色彩不刺激眼睛,其实大部分色彩都比较刺激眼睛,尤其是纯三基色(红/黄/蓝), 还要使界面做得漂亮). <br/> j. 增加”回放” 功能. 当下完旗子时,可以重新回味一下, 刚杀完的一盘旗,可以寻找不足和重新感受一下胜利的喜悦! 这个功能比较复杂!<br/> k. 又看了一下电脑走旗, 感觉确实比较难处理, 没有高人指点写这个算法确实比较难, 应该比以前聪明了一些, 但是还是比较笨, 打算有空去找个现在的电脑走旗组件替换上, 自己的电脑走旗算法慢慢研究(当时是因为实在找不到现在的组件, 自己写了个较笨的,如果哪位朋友能够提供组件,在次深表感谢!!!).<br/> l. 扩展走旗的步数容量, 有些网友, 对战的都是高手, 产生数组越界, 这次从 200 扩展到了500, 当然<br/> 您还可以扩展到更大,因为源代码已经开放).<br/> m. 增加图像缓存功能.<br/> (开发语言: C#语言)<br/><br/> * 本上传软件仅为爱好编程的同仁C#学习之用. <br/> <br/><br/>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值