C#中国象棋网络版源代码(二)-棋子类

1.棋子基类

抽象类,是所有棋子的基类, 注意几个重要的方法:如CanMoveTo移动算法及MoveTo移动棋子。

using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using www.vjsdn.com.ChineseChess.Library;

namespace www.vjsdn.com.ChineseChess.Library
{
    /// <summary>
    /// 棋子类
    /// </summary>
    public abstract class Chess
   {
       protected ChessColor _color;
       protected ChessPoint _currentPoint;
       protected ChessBoard _chessboard;
      
       /// <summary>
       /// 构造函数
       /// </summary>
       public Chess(ChessColor color, ChessPoint tragpoint, ChessBoard board)
      {
          this._color = color;
          this._currentPoint = tragpoint;
          this._chessboard = board;
      }
      
       /// <summary>
       /// 棋子颜色
       /// </summary>
       public ChessColor Color
      {
          get { return _color; }
          set { _color = value; }
      }
      
       /// <summary>
       /// 当前坐标
       /// </summary>
       public ChessPoint CurrentPoint
      {
          get { return _currentPoint; }
          set { _currentPoint = value; }
      }
      
       /// <summary>
       /// 棋盘
       /// </summary>
       public ChessBoard Chessboard
      {
          get { return _chessboard; }
          set { _chessboard = value; }
      }
      
       /// <summary>
       /// 棋子图片:抽象的属性
       /// </summary>
       public abstract Image ChessImage { get;}
      
       /// <summary>
       /// 是否能够移动
       /// </summary>
       protected abstract bool CanMoveTo(ChessPoint p);
      
       /// <summary>
       /// 移动方法
       /// </summary>
       public void MoveTo(ChessPoint targetPoint)
      {
          //目标棋子和当前棋子颜色不能一致
         Chess targetChess = _chessboard[targetPoint];
         
          if (targetChess != null && targetChess.Color == this._color) return;
         
          //是否满足规则
          if (!CanMoveTo(targetPoint)) return;
         
          //吃掉对方老王
          if (_chessboard[targetPoint] is King)
          throw new GameLoseException( this.Color == ChessColor.Red ? "红方胜" : "黑方胜");
         
          //移动
         _chessboard[_currentPoint] = null; //吃掉棋子或移动棋子
         _chessboard[targetPoint] = this;
         
          this._currentPoint = targetPoint;
      }
      
       /// <summary>
       /// 获取两点之间的棋子数
       /// </summary>
       public int GetChessCount(ChessPoint start, ChessPoint end)
      {
          //如果Y相同
          if (start.Y == end.Y)
         {
             //获取最大X和最小X值
             int min = Math.Min(start.X, end.X);
             int max = Math.Max(start.X, end.X);
            
             //棋子计数器
             int count = 0;
             for ( int i = min + 1; i < max; i++)
            {
                if (_chessboard[i, start.Y] != null)
               count++;
            }
             return count;
         }
          else
         {
             int min = Math.Min(start.Y, end.Y);
             int max = Math.Max(start.Y, end.Y);
            
             int count = 0;
             for ( int i = min + 1; i < max; i++)
            {
                if (_chessboard[start.X, i] != null)
               count++;
            }
             return count;
         }
      }
      
   }
}


2.车(Rooks)

学习车移动算法CanMoveTo. 移动规则: 1.两点在一条直线上 ,2.中间不能有棋子

using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;

namespace www.vjsdn.com.ChineseChess.Library
{
    /// <summary>
    ///
    /// </summary>
    public class Rooks : Chess
   {
       /// <summary>
       /// 构造函数
       /// </summary>
       public Rooks(ChessColor color, ChessPoint tragPoint, ChessBoard board)
      : base(color, tragPoint, board)
      {
          //
      }
      
       /// <summary>
       /// 重写图片的属性
       /// </summary>
       public override Image ChessImage
      {
          get
         {
             //红车
             if (_color == ChessColor.Red)
             return ImageHelper.GetImageByAverageIndex(ChineseChess.Res.Properties.Resources.xchess, 14, 1);
             else //黑车
             return ImageHelper.GetImageByAverageIndex(ChineseChess.Res.Properties.Resources.xchess, 14, 8);
         }
      }
      
       /// <summary>
       /// 棋子是否能够移动到目标点
       /// </summary>
       protected override bool CanMoveTo(ChessPoint targetPoint)
      {
          //两点在一条直线上
          if (targetPoint.X != _currentPoint.X && targetPoint.Y != _currentPoint.Y)
          return false;
         
          //中间不能有棋子
          if (GetChessCount(_currentPoint, targetPoint) > 0)
          return false;
         
          return true;
      }
      
   }
}



3.马(Knights)

学习马移动算法
移动规则:蹩脚算法,直线一侧不能有棋子

using System;
using System.Collections.Generic;
using System.Text;

namespace www.vjsdn.com.ChineseChess.Library
{
    /// <summary>
    ///
    /// </summary>
    public class Knights : Chess
   {
      
       /// <summary>
       /// 构造函数
       /// </summary>
       public Knights(ChessColor color, ChessPoint tragPoint, ChessBoard board)
      : base(color, tragPoint, board)
      {
          //
      }
      
       /// <summary>
       /// 象棋图片
       /// </summary>
       public override System.Drawing.Image ChessImage
      {
          get
         {
             //红马
             if ( this._color == ChessColor.Red)
             return ImageHelper.GetImageByAverageIndex(ChineseChess.Res.Properties.Resources.xchess, 14, 2);
             //黑马
             return ImageHelper.GetImageByAverageIndex(ChineseChess.Res.Properties.Resources.xchess, 14, 9);
         }
      }
      
       /// <summary>
       /// 马移动算法
       /// </summary>
       protected override bool CanMoveTo(ChessPoint p)
      {
          //蹩脚算法
          //横向移动
          if (Math.Abs(_currentPoint.X - p.X) == 2 && Math.Abs(_currentPoint.Y - p.Y) == 1)
         {
             if (_chessboard[(_currentPoint.X + p.X) / 2, _currentPoint.Y] == null)
             return true;
         }
          if (Math.Abs(_currentPoint.X - p.X) == 1 && Math.Abs(_currentPoint.Y - p.Y) == 2)
         {
             if (_chessboard[_currentPoint.X, (_currentPoint.Y + p.Y) / 2] == null)
             return true;
         }
          return false;
      }
   }
}


4.象/相(Elephants) 学习移动算法

移动规则:1.田子中间不能有棋子 2.不能过河

using System;
using System.Collections.Generic;
using System.Text;

namespace www.vjsdn.com.ChineseChess.Library
{
    /// <summary>
    /// 象--相
    /// </summary>
    public class Elephants : Chess
   {
       /// <summary>
       /// 构造函数
       /// </summary>
       public Elephants(ChessColor color, ChessPoint p, ChessBoard board)
      : base(color, p, board)
      {
          //
      }
      
       /// <summary>
       /// 象棋图片
       /// </summary>
       public override System.Drawing.Image ChessImage
      {
          get
         {
             //红相
             if ( this._color == ChessColor.Red)
             return ImageHelper.GetImageByAverageIndex(ChineseChess.Res.Properties.Resources.xchess, 14, 6);
             //黑象
             return ImageHelper.GetImageByAverageIndex(ChineseChess.Res.Properties.Resources.xchess, 14, 13);
         }
      }
      
       /// <summary>
       /// 象移动算法
       /// </summary>
       protected override bool CanMoveTo(ChessPoint p)
      {
          //绝对值法
          if (Math.Abs(_currentPoint.X - p.X) != 2 || Math.Abs(_currentPoint.Y - p.Y) != 2)
          return false;
         
          //中间不能有棋子
          if (_chessboard[(_currentPoint.X + p.X) / 2, (_currentPoint.Y + p.Y) / 2] != null)
          return false;
         
          //越界算法
          if (_currentPoint.Y <= 4 && p.Y > 4) return false;
          if (_currentPoint.Y >= 5 && p.Y < 5) return false;
         
          return true;
      }
   }
}


5.士/仕(Mandarins)

移动规则:1.“士”不能出城 2.“士”每次只能走一步且只能是斜线

using System;
using System.Collections.Generic;
using System.Text;
using www.vjsdn.com.ChineseChess.Library;

namespace www.vjsdn.com.ChineseChess.Library
{
    /// <summary>
    ///
    /// </summary>
    public class Mandarins : Chess
   {
       /// <summary>
       /// 构造函数
       /// </summary>
       public Mandarins(ChessColor color, ChessPoint tragPoint, ChessBoard board)
      : base(color, tragPoint, board)
      {
          //
      }
      
       /// <summary>
       /// 象棋图片
       /// </summary>
       public override System.Drawing.Image ChessImage
      {
          get
         {
             //红士
             if ( this._color == ChessColor.Red)
             return ImageHelper.GetImageByAverageIndex(ChineseChess.Res.Properties.Resources.xchess, 14, 5);
             //黑士
             return ImageHelper.GetImageByAverageIndex(ChineseChess.Res.Properties.Resources.xchess, 14, 12);
         }
      }
      
       /// <summary>
       /// 兵移动算法
       /// </summary>
       protected override bool CanMoveTo(ChessPoint tragPoint)
      {
          //“士”不能出城
          if (!((tragPoint.X >= 3 && tragPoint.X <= 5) && (tragPoint.Y <= 2 || tragPoint.Y >= 7)))
          return false;
         
          //“士”每次只能走一步且只能是斜线
          if (!(Math.Abs(tragPoint.X - this._currentPoint.X) == 1 && Math.Abs(tragPoint.Y - this._currentPoint.Y) == 1))
          return false;
         
          return true;
      }
   }
}



6.将/帅(King)

移动规则: 1.“将”不能出城 2.“将”每次只能走一步

using System;
using System.Collections.Generic;
using System.Text;
using www.vjsdn.com.ChineseChess.Library;

namespace www.vjsdn.com.ChineseChess.Library
{
    /// <summary>
    /// 将/帅
    /// </summary>
    public class King : Chess
   {
       /// <summary>
       /// 构造函数
       /// </summary>
       public King(ChessColor color, ChessPoint tragPoint, ChessBoard board)
      : base(color, tragPoint, board)
      {
          //
      }
      
       /// <summary>
       /// 象棋图片
       /// </summary>
       public override System.Drawing.Image ChessImage
      {
          get
         {
             //红将
             if ( this._color == ChessColor.Red)
             return ImageHelper.GetImageByAverageIndex(ChineseChess.Res.Properties.Resources.xchess, 14, 4);
             //黑将
             return ImageHelper.GetImageByAverageIndex(ChineseChess.Res.Properties.Resources.xchess, 14, 11);
         }
      }
      
       /// <summary>
       /// 将移动算法
       /// </summary>
       protected override bool CanMoveTo(ChessPoint tragPoint)
      {
          //“将”不能出城
          if (!((tragPoint.X >= 3 && tragPoint.X <= 5) && (tragPoint.Y <= 2 || tragPoint.Y >= 7)))
          return false;
         
          //“将”每次只能走一步
          if ((Math.Abs(tragPoint.X - this._currentPoint.X) + Math.Abs(tragPoint.Y - this._currentPoint.Y)) != 1)
          return false;
         
          return true;
      }
      
   }
}


7.炮/砲(Connons)

移动规则: 1.两点在一条直线上 2.目标点不为空,中间只能由一个棋子  3.目标点为空,中间不能有棋子

using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;

namespace www.vjsdn.com.ChineseChess.Library
{
    /// <summary>
    ///
    /// </summary>
    public class Cannons : Chess
   {
       /// <summary>
       /// 构造函数
       /// </summary>
       public Cannons(ChessColor color, ChessPoint tragPoint, ChessBoard board)
      : base(color, tragPoint, board)
      {
          //
      }
      
       /// <summary>
       /// 重写图片的属性
       /// </summary>
       public override Image ChessImage
      {
          get
         {
             //红炮
             if (_color == ChessColor.Red)
             return ImageHelper.GetImageByAverageIndex(ChineseChess.Res.Properties.Resources.xchess, 14, 3);
             //黑炮
             return ImageHelper.GetImageByAverageIndex(ChineseChess.Res.Properties.Resources.xchess, 14, 10);
         }
      }
      
       /// <summary>
       /// 棋子是否能够移动到目标点
       /// </summary>
       protected override bool CanMoveTo(ChessPoint targPoint)
      {
          //两点在一条直线上
          if (targPoint.X != _currentPoint.X && targPoint.Y != _currentPoint.Y)
          return false;
         
          //目标点不为空,中间只能由一个棋子
          if (_chessboard[targPoint] != null && GetChessCount(_currentPoint, targPoint) != 1)
          return false;
         
          //目标点为空,中间不能有棋子
          if (_chessboard[targPoint] == null && GetChessCount(_currentPoint, targPoint) > 0)
          return false;
         
          return true;
         
      }
      
   }
}



8.兵/卒 (Pawns)

移动规则:1.兵不能往后走 2.兵一步一步走 3.过河前只能向前走

using System;
using System.Collections.Generic;
using System.Text;
using www.vjsdn.com.ChineseChess.Library;

namespace www.vjsdn.com.ChineseChess.Library
{
    /// <summary>
    ///
    /// </summary>
    public class Pawns : Chess
   {
       //是否过河
       private bool _isRiverd = false;
       private int _step = 0; //记录步数
      
       /// <summary>
       /// 构造函数
       /// </summary>
       public Pawns(ChessColor color, ChessPoint tragPoint, ChessBoard board)
      : base(color, tragPoint, board)
      {
          if (_currentPoint.Y > 4)
         _step = -1;
          else
         _step = 1;
      }
      
       /// <summary>
       /// 象棋图片
       /// </summary>
       public override System.Drawing.Image ChessImage
      {
          get
         {
             //红兵
             if ( this._color == ChessColor.Red)
             return ImageHelper.GetImageByAverageIndex(ChineseChess.Res.Properties.Resources.xchess, 14, 7);
             //黑卒
             return ImageHelper.GetImageByAverageIndex(ChineseChess.Res.Properties.Resources.xchess, 14, 14);
         }
      }
      
       /// <summary>
       /// 兵移动算法
       /// </summary>
       protected override bool CanMoveTo(ChessPoint p)
      {
          //兵不能往后走
          if (p.Y - _currentPoint.Y == -_step)
          return false;
         
          //兵一步一步走
          if (Math.Abs(_currentPoint.X - p.X) + Math.Abs(_currentPoint.Y - p.Y) != 1)
          return false;
         
          //过河
          if (!_isRiverd)
         {
             if (_currentPoint.Y == 4 && p.Y == 5) _isRiverd = true;
             if (_currentPoint.Y == 5 && p.Y == 4) _isRiverd = true;
         }
         
          //过河前只能向前走
          if (!_isRiverd)
         {
             if (p.Y - _currentPoint.Y != _step)
             return false;
         }
         
          return true;
      }
   }
}
  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
功能介绍:<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/>
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值