上两节实现了棋子的两种走法,吃子和没移动到线交叉点。不过我们都是没有规则的走,这节为棋子的走法增加规则,棋的规则我就不多说了,基本要找个不会下象棋的很难,就是找到的估计也不会看这文章。

当我们移动棋子的时候,总是要判断一下移动是不是合规则的,合规则的才让下,不合规则的就不能下了,什么马象田马日车炮跑,将军卫士陷九宫,[本人涅造句子]之类的。

好了,原始冲动,新建棋子规则类,也是本棋子裤的最后一个类了:

对着项目内裤右键-》添加类->输入:ChessRule.cs。

///   <summary>
     ///  棋子规则-by 路过秋天
     ///   </summary>
     public   class  ChessRule
    {

}

我们为之新增加一个方法IsCanMove方法,就是棋子要走的时候,用此方法来判断是不是符合规则,返回值就是bool型了。

///   <summary>
     ///  棋子规则-by 路过秋天
     ///   </summary>
     public   class  ChessRule
    {
         ///   <summary>
         ///  移动规则
         ///   </summary>
         ///   <param name="move"> 棋子 </param>
         ///   <param name="eat"> 移动的位置的数组 </param>
         ///   <returns></returns>
         public   bool  IsCanMove(Chessman chessman, Point moveTo)
        {
             // 实现判断
             return   false ;
        }
    }

每种棋子都有各自的规则,因此我们要用Switch来分支,这里我们在类的外面加上个棋子枚举:

public   enum  ChessType
    {
        Bing,
        Pao,
        Che,
        Ma,
        Xiang,
        Shi,
        Jiang
    }

懂点汉语的一看就知道这E文是什么意思了。

好,我们为规则ChessRule类再加个方法,通过棋子的名称来返回ChessType

  public  ChessType GetChessTypeByName( string  name)
        {
             switch  (name)
            {
                 case   " 兵 " :
                 case   " 卒 " :
                     return  ChessType.Bing;
                 case   " 炮 " :
                     return  ChessType.Pao;
                 case   " 车 " :
                     return  ChessType.Che;
                 case   " 马 " :
                     return  ChessType.Ma;
                 case   " 士 " :
                 case   " 仕 " :
                     return  ChessType.Shi;
                 case   " 将 " :
                 case   " 帅 " :
                     return  ChessType.Jiang;
                 case   " 象 " :
                 case   " 相 " :
                     return  ChessType.Xiang;
            }
             throw   new  Exception( " 未知名称: "   +  name);
        }

OK,这时候我们再修改下IsCanMove方法就能改成这样了:

  public   bool  IsCanMove(Chessman chessman, Point moveTo)
        {
             // 实现判断
            ChessType chessType = GetChessTypeByName(chessman.Name);
             switch  (chessType)
            {
                 case  ChessType.Bing:
                     // 待实现
                     break ;
                 case  ChessType.Che:
                     // 待实现
                     break ;
                 case  ChessType.Jiang:
                     // 待实现
                     break ;
                 case  ChessType.Ma:
                     // 待实现
                     break ;
                 case  ChessType.Shi:
                     // 待实现
                     break ;
                 case  ChessType.Xiang:
                     // 待实现
                     break ;
                 case  ChessType.Pao:
                     // 待实现
                     break ;
            }
             return   false ;
        }

这里增加了一个枚举和方法获取来进行分支,要是嫌麻烦了,就用加枚举了,直接在里面

Swith(chessman.Name){

case "兵": case "卒": //待实现

case "将": case "帅": //待现

case "车": case "帅": //待现

case "炮": //待实现

}

这样也是行的。

好了,现在开始步步一个一个的实现规则。

我们先把几个坐标拿出来弄为x1,y1,x2,y2先,然后进行第一步判断,如果移动的位置超出棋盘范围之内,或者原地走就拒绝,于是代码简单的变成:

由于棋盘有九条直线,十条横线,对应到x,y坐标的范围就是x->(0,8) y->(0,9),原地的话就是(x1,y1)点=(x2,y2)点

  public   bool  IsCanMove(Chessman chessman, Point moveTo)
        {
             // 实现判断
             int  x1  =  ( int )chessman.MovePoint.X;
             int  y1  =  ( int )chessman.MovePoint.Y;
             int  x2  =  ( int )moveTo.X;
             int  y2  =  ( int )moveTo.Y;
             if  (x2  >=     &&  x2  <   9   &&  y2  >=     &&  y2  <   10   &&   ! (x1  ==  x2  &&  y1  ==  y2)) // 在棋盘之内,非原步。
            {
                ChessType chessType  =  GetChessTypeByName(chessman.Name);
                 switch  (chessType)
                {
                     case  ChessType.Bing:
                         // 待实现
                         break ;
                     case  ChessType.Che:
                         // 待实现
                         break ;
                     case  ChessType.Jiang:
                         // 待实现
                         break ;
                     case  ChessType.Ma:
                         // 待实现
                         break ;
                     case  ChessType.Shi:
                         // 待实现
                         break ;
                     case  ChessType.Xiang:
                         // 待实现
                         break ;
                     case  ChessType.Pao:
                         // 待实现
                         break ;
                }
            }
             return   false ;
        }

OK,现在来开始实现第一个兵规则。其实一开始我想啊想:

兵:没过河,只能往前走,过了河,只能直走和横着走。而且每次只能走一步

好,一步一步限制。

1.先判断一下是不是走一步

if  (Math.Abs(y2  -  y1)  +  Math.Abs(x2  -  x1)  !=   1 ) // 只能走一步
                        {
                             break ;
                        }

由于我们第一个判断限制只能走一步,接我们来判断一下棋子是不是往前直走。

if (x1  ==  x2  &&  y1  >  y2){ return   true ;}

接下来我们判断一下棋子是横着走,并且过了河。

if (y1  ==  y2  &&  y1  <   5 ){ return   true ;}

由于下棋者,正常都只用位于棋子下方的棋的,所以只要判断下面的棋子的规则就行了。

[备注,当然了,如果你想对上面的棋子也进行潜规则,也是可以的,待讲完发完整代码时再对上面的棋子进行潜规则]

好了,将后面两个合起来,完整的代码就是:

  case  ChessType.Bing:
                         if  (Math.Abs(y2  -  y1)  +  Math.Abs(x2  -  x1)  !=   1 ) // 只能走一步
                        {
                             break ;
                        }
                         if  ((x1  ==  x2  &&  y1  >  y2)  ||  (y1  ==  y2  &&  y1  <   5 ))
                        { // 只能直走 或者 过了河左右走
                             return   true ;
                        }
                         break ;

看,一个兵的规则,咋家用两个if搞定了。看来,规则判断也不是那么难的。

好,下一个是什么呢?车

车:能够直走或横着走,不能越过棋子,吃倒是可以,自家颜色不给吃[这个我们在外面点击棋子就有判断等于切换棋子了]

我想了想,想出一个方法,获取一颗棋子原始点和移动到的点之间在X和Y方向的障碍物[就是有几颗棋子顶着个肺]

一方法又产生了:

  ///   <summary>
         ///  获取障碍物数量
         ///   </summary>
         public   void  OutCount(Point start, Point end,  out   int  xCount,  out   int  yCount)
        {
            xCount  =   ;
            yCount  =   ;
             // 待实现
        }

好,有了这个方法,车子的移动规则就相当的简单了,看下说明就清楚了:

case  ChessType.Che:
                          int  xCount, yCount;
                        OutCount(chessman.MovePoint, moveTo,  out  xCount,  out  yCount);
                         if  (x1  ==  x2  &&  yCount  ==     ||  y1  ==  y2  &&  xCount  ==   )
                        { // 坚走/横走没有障碍别
                             return   true ;
                        }
                         break ;

没想到车子的移动规则也变的这么简单了。

呵呵,那个获取障碍物的方法还没有实现呢

接下来实现一下吧,这里我们要为棋子规则ChessRule类引入一个构造函数,为什么要引入Action呢,因为移动规则只有在移动的时候才现身出来闪一下。其它时候规则是退隐江湖的。

  ///   <summary>
         ///  动作类
         ///   </summary>
         public  ChessAction Action
        {
             get ;
             set ;
        }
         public  ChessRule(ChessAction action)
        {
            Action  =  action;
        }

既然构造里引入ChessAction,同样,在ChessAction里也得实例化下这个ChessRule,不然怎么将自身传过来啊。

回到ChessAction的构造函数,同时加一属性:

public  ChessRule Rule // 新加的属性
        {
             get ;
             set ;
        }
         public  ChessAction(Chess ownChess)
        {
            OwnChess  =  ownChess;
            Rule  =   new  ChessRule( this ); // 新加的实例化
        }

OK,现在可以实现那个获取障碍物棋子数的方法了:

  ///   <summary>
         ///  获取障碍物数量
         ///   </summary>
         public   void  OutCount(Point start, Point end,  out   int  xCount,  out   int  yCount)
        {
            xCount  =  yCount  =   ;
            Point point;
             for  ( int  i  =   ; i  <  Action.Parent.ChessmanList.Count; i ++ )
            {
                point  =  Action.Parent.ChessmanList[i].MovePoint;
                 if  (start.Y  ==  point.Y  &&  Math.Min(start.X, end.X)  <  point.X  &&  point.X  <  Math.Max(start.X, end.X))
                {
                    xCount ++ ;
                }
                 if  (start.X  ==  point.X  &&  Math.Min(start.Y, end.Y)  <  point.Y  &&  point.Y  <  Math.Max(start.Y, end.Y))
                {
                    yCount ++ ;
                }
            }
        }

小小解说一下:

1。遍历所有的棋子的坐标

2。start.Y==point.Y时,说明是Y坐标相同,就是横线上的比较

3。start.X==point.X时,说明是X坐标相同,就是直线上的比较

4。接下来就是 起始点[最小值]<被遍历棋子坐标<终点[最大值],在这里面的棋子数就是障碍物数量了。

最后,把那个返回值默认返回return false;

目前完整代码如下:

public   enum  ChessType
    {
        Bing,
        Pao,
        Che,
        Ma,
        Xiang,
        Shi,
        Jiang
    }
     ///   <summary>
     ///  棋子规则-by 路过秋天
     ///   </summary>
     public   class  ChessRule
    {
         ///   <summary>
         ///  动作类
         ///   </summary>
         public  ChessAction Action
        {
             get ;
             set ;
        }
         public  ChessRule(ChessAction action)
        {
            Action  =  action;
        }
         ///   <summary>
         ///  移动规则
         ///   </summary>
         ///   <param name="move"> 棋子 </param>
         ///   <param name="eat"> 移动的位置的数组 </param>
         ///   <returns></returns>
         public   bool  IsCanMove(Chessman chessman, Point moveTo)
        {
             // 实现判断
             int  x1  =  ( int )chessman.MovePoint.X;
             int  y1  =  ( int )chessman.MovePoint.Y;
             int  x2  =  ( int )moveTo.X;
             int  y2  =  ( int )moveTo.Y;
             if  (x2  >=     &&  x2  <   9   &&  y2  >=     &&  y2  <   10   &&   ! (x1  ==  x2  &&  y1  ==  y2)) // 在棋盘之内,非原步。
            {
                ChessType chessType  =  GetChessTypeByName(chessman.Name);
                 switch  (chessType)
                {
                     case  ChessType.Bing:
                         if  (Math.Abs(y2  -  y1)  +  Math.Abs(x2  -  x1)  !=   1 ) // 只能走一步
                        {
                             break ;
                        }
                         if  ((x1  ==  x2  &&  y1  >  y2)  ||  (y1  ==  y2  &&  y1  <   5 ))
                        { // 只能直走 或者 过了河左右走
                             return   true ;
                        }
                         break ;
                     case  ChessType.Che:
                          int  xCount, yCount;
                        OutCount(chessman.MovePoint, moveTo,  out  xCount,  out  yCount);
                         if  (x1  ==  x2  &&  yCount  ==     ||  y1  ==  y2  &&  xCount  ==   )
                        { // 坚走/横走没有障碍别
                             return   true ;
                        }
                         break ;
                     case  ChessType.Jiang:
                         // 待实现
                         break ;
                     case  ChessType.Ma:
                         // 待实现
                         break ;
                     case  ChessType.Shi:
                         // 待实现
                         break ;
                     case  ChessType.Xiang:
                         // 待实现
                         break ;
                     case  ChessType.Pao:
                         // 待实现
                         break ;
                }
            }
             return   false ;
        }
         public  ChessType GetChessTypeByName( string  name)
        {
             switch  (name)
            {
                 case   " 兵 " :
                 case   " 卒 " :
                     return  ChessType.Bing;
                 case   " 炮 " :
                     return  ChessType.Pao;
                 case   " 车 " :
                     return  ChessType.Che;
                 case   " 马 " :
                     return  ChessType.Ma;
                 case   " 士 " :
                 case   " 仕 " :
                     return  ChessType.Shi;
                 case   " 将 " :
                 case   " 帅 " :
                     return  ChessType.Jiang;
                 case   " 象 " :
                 case   " 相 " :
                     return  ChessType.Xiang;
            }
             throw   new  Exception( " 未知名称: "   +  name);
        }
         ///   <summary>
         ///  获取障碍物数量
         ///   </summary>
         public   void  OutCount(Point start, Point end,  out   int  xCount,  out   int  yCount)
        {
            xCount  =  yCount  =   ;
            Point point;
             for  ( int  i  =   ; i  <  Action.Parent.ChessmanList.Count; i ++ )
            {
                point  =  Action.Parent.ChessmanList[i].MovePoint;
                 if  (start.Y  ==  point.Y  &&  Math.Min(start.X, end.X)  <  point.X  &&  point.X  <  Math.Max(start.X, end.X))
                {
                    xCount ++ ;
                }
                 if  (start.X  ==  point.X  &&  Math.Min(start.Y, end.Y)  <  point.Y  &&  point.Y  <  Math.Max(start.Y, end.Y))
                {
                    yCount ++ ;
                }
            }
        }    }

OK,这节先实现兵和车的规则,下小节再实现其它棋子规则。

打完,收工!

作者博客:http://cyq1162.cnblogs.com/

原文链接: http://www.cnblogs.com/cyq1162/archive/2010/07/09/1774210.html

转载于:https://my.oschina.net/chen106106/blog/43362

Silverlight+WCF 新手实例 象棋 棋子移动-规则[兵、车](七)相关推荐

  1. Silverlight+WCF 新手实例 象棋 棋子移动-规则[附加上半盘限制](十)

    上上一节,我们对棋子的下半盘棋子做了所有的规则限制,因为我们下棋的总是用下半盘的棋子来下,总没人用上半盘棋来下那么高境界的吧. 不过这节简单追加点代码,让那些企图高境界的人士可以临时性的自己和自己下. ...

  2. Silverlight+WCF 新手实例 象棋 棋子移动-规则[将、马、士、相、炮](八)

    这节来完成剩下五个种子的规则. 先来将吧 将:只能走一步,而且只能在九宫内行走 看代码,还是和兵的一个样. if  (Math.Abs(y2  -  y1)  +  Math.Abs(x2  -  x ...

  3. Silverlight+WCF 新手实例 象棋 棋子移动-线交叉点(六)

    上一节,我们给棋子赋于了鼠标点击事件,并通过故事板Storyboard 来移动棋子,同时实现了吃棋子. 现在我们在实现鼠标在棋盘上点击,然后棋子就移动到那去. 好了,鼠标在棋盘上点击,这里要为点击的棋 ...

  4. Silverlight+WCF 新手实例 象棋 棋子(三)

    2019独角兽企业重金招聘Python工程师标准>>> 棋盘上有棋子,棋子应该还有一些属性,按原始冲动新建一个棋子类. 上google翻译下棋子E文叫什么,查到了叫Chessman, ...

  5. Silverlight+WCF 新手实例 象棋 棋子定位与象棋类(四)

    上节创建显示了一颗棋子,由于没有margin属性,所以只能靠边站. 现在,我们创建一个象棋类,让它包括棋盘和棋子,同时附加几个常用函数. 还是对着Silverlight类库项目右键添加类:Chess. ...

  6. Silverlight+WCF 新手实例 象棋 该谁下棋-B下A停(三十)

    2019独角兽企业重金招聘Python工程师标准>>> 在线演示地址:Silverlight+WCF 新手实例 象棋 在线演示 上上一节,就是二十八节:Silverlight+WCF ...

  7. Silverlight+WCF 新手实例 象棋 主界面-棋谱-获取列表(三十八)

    2019独角兽企业重金招聘Python工程师标准>>> 在线演示地址:Silverlight+WCF 新手实例 象棋 在线演示 在Silverlight+WCF 新手实例 象棋 主界 ...

  8. Silverlight+WCF 新手实例 象棋 主界面-棋谱-回放-结局(四十)

    在线演示地址: Silverlight+WCF 新手实例 象棋 在线演示 在Silverlight+WCF 新手实例 象棋 主界面-棋谱-回放(三十九)中,我们实现了用户的棋谱回放,在文章的下面,我们 ...

  9. Silverlight+WCF 新手实例 象棋 主界面-棋谱-回放(三十九)

    在线演示地址:Silverlight+WCF 新手实例 象棋 在线演示 本节完后,同时会更新Silverlight+WCF 新手实例 象棋 专题索引,并顺路提供第八阶段源码 在Silverlight+ ...

最新文章

  1. Android Studio 中修改versionCode跟versionName (更新版本)
  2. java内部类 缺点_Java中的内部类及其优势
  3. 【中间件】消息队列-RabbitMQ
  4. 【深度学习】GPU选型调研!3090依旧是性价比之王
  5. ora-01658 :无法为表空间USERS 中的段创建INITIAL区
  6. 最近想读的书想做的事
  7. JS中变量和函数的使用
  8. 作一个真正合格的飞秋局域网聊天
  9. Python版常见的排序算法
  10. 用PhotoSwipe制作相册,手势可放大
  11. 基于遗传算法(deap库)的一元函数寻优代码详解
  12. 一个大牛写的有关游戏的
  13. 常用服务器管理口IP及账号密码(持续更新)
  14. 解决dll load failed while importing qtgui
  15. c++builder 6.0中OnCliked= fun实现的原理
  16. 计算机文件夹移动的实验原理,怎么移动电脑文件和文件夹
  17. Java基础之Java8中Map的compute的使用
  18. 计算机学报在线阅读,含指针程序的单子切片方法-计算机学报.pdf
  19. Python编写程序,生成包含20个随机数列表,然后将前十个元素升序排列,后十个元素降序排列,并输出结果。
  20. linux快速搜索指定内容-小知识

热门文章

  1. 第十二章、Designer中的menu菜单、toolBar工具栏和Action动作
  2. python_for_hrm:基于腾讯企业邮箱SMTP服务发送员工工资条(竖表)
  3. KSO - .net6项目中使用RabbitMQ实际项目代码和思路讲解,包括各种踩坑
  4. 【观察】锦州这座城高质量发展新动能,成长在华为的“黑土地”之上
  5. Vue 3.0 企业级项目实战
  6. SQL Server如何获取GUID号
  7. 2018服务器 芯片组,再见了14nm 2018主板/CPU行业回顾展望
  8. 中兴新支点加入龙蜥社区,共建操作系统开源新生态
  9. 这样提案,设计比较容易落地
  10. html+css 习题