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

c#开发技术 专栏收录该内容
5 篇文章 0 订阅

前言

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

界面效果图

在这里插入图片描述

图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;
 }

完整文件

中国象棋程序

  • 2
    点赞
  • 0
    评论
  • 9
    收藏
  • 打赏
    打赏
  • 扫一扫,分享海报

扩展功能: a. 首先满足网友的”口味”, 重新设计了所有旗子, 选择新的旗盘背景, 换了一个更清爽的面. (界面配色并不是件很容易的事情, 这样的棋类游戏长时间容易使眼睛疲劳, 首先要做到选择的色彩 不刺激眼睛,其实大部分色彩都比较刺激眼睛,尤其是纯三基色(红/黄/蓝), 还要使界面做得漂亮). b. 增加”回放” 功能. 当下完旗子时,可以重新回味一下, 刚杀完的一盘旗,可以寻找不足和重新感受 一下胜利的喜悦! 这个功能比较复杂! d. 又看了一下电脑走旗, 感觉确实比较难处理, 没有高人指点写这个算法确实比较难, 应该比以前聪明 了一些, 但是还是比较笨, 打算有空去找个现在的电脑走旗组件替换上, 自己的电脑走旗算法慢慢研 究(当时是因为实在找不到现在的组件, 自己写了个较笨的,如果哪位朋友能够提供组件,在次深表感谢!!!). e. 扩展走旗的步数容量, 有些网友, 对战的都是高手, 产生数组越界, 这次从 200 扩展到了500, 当然 您还可以扩展到更大,因为源代码已经开放). f. 增加图像缓存功能. g. 解决 .net 从framework 1.0到framework 2.0升级出现的程式升级逻辑问题及一个小bug. h. 本来我只是想把这个程式放到Blog上, 供爱好c#的网友学习,一起交流一下, 没想到反应那么的强烈! 经常收到网友的反馈邮件, 从下载量看,不到一年仅从我的下载空间(不算网友转载下载次数)就有近 二万五千次. 所以又重新看懂已经基本忘记的代码,修复了bug,并扩展了以上功能. 有可能还会增加一些功能! 另外,在此对给我提交建议和bug的朋友表示感谢!!! (开发语言: C#语言) 来自:http://community.csdn.net/Expert/topic/5237/5237003.xml?temp=.4600031
©️2022 CSDN 皮肤主题:大白 设计师:CSDN官方博客 返回首页

打赏作者

无名风沙

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值