中国象棋 军 规则判断

 

这里以.net为例共享给大家,JAVA一样的,运算符功能都一样

这里主要是共享我花了大半天时间想出来的一个算法。在这之前,首先我们要回忆几个知识点,位运算:

.右移运算符 >> ,|逻辑或,~按位取反,

我们要判断的是 “军” 出棋时,从起点到终点,这两点之前是否有别的棋子存在,如果存在就不能那样走。

首先军可以向四个直线方向走,但是我们要知道从起点到终点往哪个方向走的,我们必须做出判断写if(x1-x2<0&&y1-y2==0) ....if(x1-x2==0&&y1-y2<0) .....等等这样去判断方向,然后再用for循环来遍历这两点之前是否有其他棋子存在,这得写4个if加for循环。下面这段代码只需要一个for循环加if就搞定,看段代码:

 

 private Boolean Che(Enum[,] chess, Point[,] point, Point start, Point end)
        {
            //得到两点的位置信息
            int s_x = (start.X-10)/48;
            int s_y = (start.Y-10)/48;
            int e_x = (end.X-10)/48;
            int e_y = (end.Y-10)/48;

            //移动的方向
            int x = s_x-e_x;
            int y = s_y-e_y;

            //是否走的是直线
            if (s_x != e_x && s_y != e_y) 
            {
                return false;//不是直线
            }

            //查看两点之前是否有其他棋子(经典之作呀,花了我半天加一个晚上时间才想出来,从除法想到位移)
            for (int i = 1; i < Math.Abs(x) || i < Math.Abs(y); i++) 
            {
                int xx = s_x + (x >> 31 | 1) * i * (((~(-Math.Abs(x))) >> 31) + 1);
                int yy =  s_y + (y >> 31 | 1) * i * (((~(-Math.Abs(y))) >> 31) + 1);
                Enum e = chess[s_x-xx,s_y-yy];//得到经过的坐标点
                if (e != null) 
                {
                    return false;//中间存在子
                }
            }



                return true;
        }

参数说明,chess里记录了棋子,如果没有则为null,point为对应chess的坐标,start为开始移动坐标,end为要移到的目的地位标

(start.X-10)/48;这个算法是得到当前坐标在point二维数组的序号.s_x-e_x这个算法是得到相对于现在的序号是正移的还是负移的

(x >> 31 | 1)这个算法前篇文单有写是取得符号,(负整数就得到-1,正整数或0得到1)

(((~(-Math.Abs(x))) >> 31) + 1)这个算法的功能主要是把除开0以外的所有数变成1,0则不变

下面来说明一下(((~(-Math.Abs(x))) >> 31) + 1)

Math.Abs(x)这个我们可以得到一个非负数,

-Math.Abs(x)加个负号,全转成负数

~(-Math.Abs(x))取反,0取反就得-1,负整数反就得正整数

然后右移31个位,((~(-Math.Abs(x))) >> 31),-1依然是-1,正整数则会变成0

(((~(-Math.Abs(x))) >> 31) + 1)就能实现上面的"把除开0以外的所有数变成1,0则不变"

得到坐标序号s_x + (x >> 31 | 1) * i * (((~(-Math.Abs(x))) >> 31) + 1)

整个思路就是这样。对移位不是很清楚的童鞋可能会有疑问为什么是移31位而不是移32或其他,这个你得去研究一下位移这个东东了.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值