BingWay原创作品,转载请注明作者和出处。

继上次写象棋游戏编程——画棋盘》,经过十一长假的几天休息和调整,这几天终于把各棋子的走法功能完成。
象棋的走法是玩象棋必须知道的,下面的走法是我玩象棋两三天过后总结的。
将或帅 
移动范围:它只能在王宫内移动。 

移动规则:它每一步只可以水平或垂直移动一点。


移动范围:它只能在王宫内移动。
移动规则:它每一步只可以沿对角线方向移动一点。

移动范围:河界的一侧。

移动规则:它每一步只可以沿对角线方向移动两点(象走田),另外,在移动的过程中不能够穿越障碍,如果有,就是俗称的“塞象”。

移动范围:任何位置

移动规则:每一步只可以水平或垂直移动一点(马走日),再按对角线方面向左或者右移动。另外,在移动的过程中不能够穿越障碍,如果有,就是俗称的“撇马脚”。


移动范围:任何位置
移动规则:可以水平或垂直方向移动任意个无阻碍的点。

移动范围:任何位置

移动规则:移动起来和车很相似,但它必须跳过一个棋子来吃掉对方的一个棋子(隔山炮)。

移动范围:任何位置

移动规则:每步只能向前移动一点。小兵过河后,就有了左右移动的能力,兵只能前进,不能后退。


实现各棋子走法的代码:

各子的走法
  1  //判断***马***的走法是否合理
  2 public bool HorseFoot(Point fromPoint,Point toPoint)
  3         {
  4             int fromIndex=this.CountIndex(fromPoint);   //起点信息的一维数组的索引
  5             int toIndex=this.CountIndex(toPoint);       //终点信息的一维数组的索引
  6             if(fromPoint==toPoint)  //如果起点和终点是同一个点,则允许放回旗子,重新选其它路
  7             {                
  8                 return true;
  9             }
 10             
 11             if(who[fromIndex].Equals(who[toIndex]))  //如果起点和终点是同一边的旗子,则不能走
 12             {                
 13                 return false;            
 14             }
 15             double twoPoint_Right_Distance=Math.Sqrt((this.width*this.width)+(width+width)*(width+width));
 16             double twoPoint_True_Distance=Math.Sqrt((fromPoint.XtoPoint.X)*(fromPoint.XtoPoint.X)+(fromPoint.YtoPoint.Y)*(fromPoint.YtoPoint.Y));
 17             if(this.GetNextPoint(fromPoint,2,1)==toPoint||this.GetNextPoint(fromPoint,2,1)==toPoint)  //当马向上跳时有两种跳法(左上日和右上日)
 18                 if(this.have[this.CountIndex(this.GetNextPoint(fromPoint,1,0))]==false)   //起点上面没有旗子,也就是不 “撇马脚” 时可以往上走旗
 19                 {                    
 20                     if(twoPoint_True_Distance<=twoPoint_Right_Distance)
 21                         return true;
 22                 }
 23             if(this.GetNextPoint(fromPoint,2,1)==toPoint||this.GetNextPoint(fromPoint,2,1)==toPoint)   //同上,只是变为向下跳马的情况
 24                 if(this.have[this.CountIndex(this.GetNextPoint(fromPoint,1,0))]==false)
 25                 {                    
 26                     if(twoPoint_True_Distance<=twoPoint_Right_Distance)
 27                         return true;                    
 28                 }
 29             if(this.GetNextPoint(fromPoint,1,2)==toPoint||this.GetNextPoint(fromPoint,1,2)==toPoint)   //同上,只是变为向右跳马的情况
 30                 if(this.have[this.CountIndex(this.GetNextPoint(fromPoint,0,1))]==false)
 31                 {                    
 32                     if(twoPoint_True_Distance<=twoPoint_Right_Distance+5)
 33                         return true;
 34                 }
 35             if(this.GetNextPoint(fromPoint,1,2)==toPoint||this.GetNextPoint(fromPoint,1,2)==toPoint) //同上,只是变为向左跳马的情况
 36                 if(this.have[this.CountIndex(this.GetNextPoint(fromPoint,0,1))]==false)
 37                 {                    
 38                     if(twoPoint_True_Distance<=twoPoint_Right_Distance+5)
 39                         return true;            
 40                 }
 41             
 42             return false;    //除去以上几种情况,其余终点都不能落旗            
 43         }
 44         //判断***兵/卒***的走法是否合理
 45         public bool ObiitFoot(Point fromPoint,Point toPoint)
 46         {            
 47             int fromIndex=this.CountIndex(fromPoint);   //起点信息的一维数组的索引
 48             int toIndex=this.CountIndex(toPoint);       //终点信息的一维数组的索引
 49             string isUpOrDownFromPoint=this.IsUpOrDown(fromPoint); //起点是在旗盘上方,还是下方(“兵/帅” 在旗子上方和下方走法不一样) 
 50             string isUpOrDownToPoint=this.IsUpOrDown(toPoint);     //终点是在旗盘上方,还是下方(“兵/帅” 在旗子上方和下方走法不一样)
 51             
 52             if(fromPoint==toPoint)  //如果起点和终点是同一个点,则允许放回旗子,重新先其它路
 53             {                
 54                 return true;
 55             }
 56             
 57             if(who[fromIndex].Equals(who[toIndex]))  //如果起点和终点是同一边的旗子,则不能走
 58             {                
 59                 return false;            
 60             }
 61 
 62             if(who[fromIndex].Equals(black))  //假如起始点是黑兵
 63             {    
 64                 if(isUpOrDownFromPoint==down&&isUpOrDownToPoint==down||isUpOrDownFromPoint==down&&isUpOrDownToPoint==up)//起点和终点都在下面或起点在下面终点在上面时情况
 65                 {                    
 66                     if(this.GetNextPoint(fromPoint,1,0)==toPoint)  //如果终点是起点的上面一个点,则返回真
 67                     {                        
 68                         return true;
 69                     }
 70                 }
 71                 else
 72                 {
 73                     if(isUpOrDownFromPoint==up&&isUpOrDownToPoint==up)//当起点和终点都在同一点
 74                     {
 75                         if(this.GetNextPoint(fromPoint,1,0)==toPoint) //过河后可以往上走
 76                             return true;
 77                          if(this.GetNextPoint(fromPoint,0,1)==toPoint)  //过河后可以往右走
 78                             return true;
 79                         if(this.GetNextPoint(fromPoint,0,1)==toPoint) //过河后可以往左走
 80                             return true;
 81                     }
 82                 }                
 83             }
 84             if(who[fromIndex].Equals(red))
 85             {                
 86                 if(isUpOrDownFromPoint==up&&isUpOrDownToPoint==up||isUpOrDownFromPoint==up&&isUpOrDownToPoint==down)
 87                 {                    
 88                     if(this.GetNextPoint(fromPoint,1,0)==toPoint)
 89                     {                        
 90                         return true;
 91                     }
 92                 }
 93                 else if(isUpOrDownFromPoint==down&&isUpOrDownToPoint==down)//起点和终点都在同一点
 95                     {
 96                        if(this.GetNextPoint(fromPoint,1,0)==toPoint)   //过河后可以往下走
 97                             return true;
 98                        if(this.GetNextPoint(fromPoint,0,1)==toPoint)   //过河后可以往右走
 99                              return true;
100                        if(this.GetNextPoint(fromPoint,0,1)==toPoint)  //过河后可以往左走
101                             return true;
102                     }                
103             }            
104             
105             return false;            
106         }
107         //判断***車***的走法是否合理
108         public bool JuFoot(Point fromPoint,Point toPoint)    
109         {
110             int fromIndex=this.CountIndex(fromPoint);   //起点信息的一维数组的索引
111             int toIndex=this.CountIndex(toPoint);       //终点信息的一维数组的索引            
112                     
113             if(fromPoint==toPoint)  //如果起点和终点是同一个点,则允许放回旗子,重新先其它路
114             {                
115                 return true;
116             }            
117             if(who[fromIndex].Equals(who[toIndex]))  //如果起点和终点是同一边的旗子,则不能走
118             {                
119                 return false;            
120             }
121             if(fromPoint.X==toPoint.X)   //判断是否在同一条垂直直线上
122             {                
123                 if(fromPoint.Y>toPoint.Y) //起点在终点下面情况
124                     for(int i=-1;this.GetNextPoint(fromPoint,i,0)!=toPoint;i)  //判断起点终点之间有无旗子
125                         if(this.have[this.CountIndex(this.GetNextPoint(fromPoint,i,0))]==true)
126                             return false;                    
127                 
128                 if(fromPoint.Y<toPoint.Y)//起点在终点上面情况
129                     for(int i=1;this.GetNextPoint(fromPoint,i,0)!=toPoint;i++)  //判断起点终点之间有无旗子
130                         if(this.have[this.CountIndex(this.GetNextPoint(fromPoint,i,0))]==true)
131                             return false;    
132                 return true;                    
133             }
134             if(fromPoint.Y==toPoint.Y)  //判断是否在同一条水平直线上
135             {                
136                 if(fromPoint.X<toPoint.X)  //起点在终点左边
137                     for(int j=1;this.GetNextPoint(fromPoint,0,j)!=toPoint;j++)  //判断起点终点之间有无旗子
138                         if(this.have[this.CountIndex(this.GetNextPoint(fromPoint,0,j))]==true)
139                             return false;                                        
140                 
141                 if(fromPoint.X>toPoint.X)  //起点在终点右边
142                     for(int j=-1;this.GetNextPoint(fromPoint,0,j)!=toPoint;j)  //判断起点终点之间有无旗子
143                         if(this.have[this.CountIndex(this.GetNextPoint(fromPoint,0,j))]==true)
144                             return false;    
145                 return true;
146             }            
147             
148             return false;            
149         }
150         //判断***炮***的走法是否合理
151         public bool CannonFoot(Point fromPoint,Point toPoint) 
152         {
153             int fromIndex=this.CountIndex(fromPoint);   //起点信息的一维数组的索引
154             int toIndex=this.CountIndex(toPoint);       //终点信息的一维数组的索引            
155                     
156             if(fromPoint==toPoint)  //起点和终点都在同一点,则允许放回旗子,重新先其它路
157             {                
158                 return true;
159             }            
160             if(who[fromIndex].Equals(who[toIndex]))  //如果起点和终点是同一边的旗子,则不能落旗
161             {                
162                 return false;            
163             }
164             if(fromPoint.X==toPoint.X)    //判断起点和终点在同一垂直线上情况
165             {
166                 int number_QiZi=0;
167                 if(fromPoint.Y>toPoint.Y) //起点在终点下面情况
168                 {
169                     for(int i=-1;this.GetNextPoint(fromPoint,i,0)!=toPoint;i)  //判断起点终点之间旗子数量
170                         if(this.have[this.CountIndex(this.GetNextPoint(fromPoint,i,0))]==true)
171                             number_QiZi++;
172                     if(number_QiZi>1)          //如果起点和终点之间的旗子数大于1,则不能落旗
173                         return false;
174                     if(number_QiZi==0&&this.have[this.CountIndex(toPoint)]==false)  //起点和终点之间无旗子,在终点落旗
175                         return true;
176                     if(number_QiZi==1&&this.have[this.CountIndex(toPoint)]==true)  //起点和终点之间仅有一个旗
177                         return true;
178                 }
179 
180                 number_QiZi=0;
181                 if(fromPoint.Y<toPoint.Y) //起点在终点下面情况
182                 {
183                     for(int i=1;this.GetNextPoint(fromPoint,i,0)!=toPoint;i++)  //判断起点终点之间旗子数量
184                         if(this.have[this.CountIndex(this.GetNextPoint(fromPoint,i,0))]==true)
185                             number_QiZi++;
186                     if(number_QiZi>1)          //如果起点和终点之间的旗子数大于1,则不能落旗
187                         return false;
188                     if(number_QiZi==0&&this.have[this.CountIndex(toPoint)]==false)       //起点和终点之间无旗子,在终点落旗
189                         return true;
190                     if(number_QiZi==1&&this.have[this.CountIndex(toPoint)]==true)  //起点和终点之间仅有一个旗
191                         return true;                
192                 }
193             }
194             if(fromPoint.Y==toPoint.Y)
195             {
196                 int number_QiZi=0;
197                 if(fromPoint.X>toPoint.X) //起点在终点右边情况
198                 {
199                     for(int j=-1;this.GetNextPoint(fromPoint,0,j)!=toPoint;j)  //判断起点终点之间旗子数量
200                         if(this.have[this.CountIndex(this.GetNextPoint(fromPoint,0,j))]==true)
201                             number_QiZi++;
202                     if(number_QiZi>1)          //如果起点和终点之间的旗子数大于1,则不能落旗
203                         return false;
204                     if(number_QiZi==0&&this.have[this.CountIndex(toPoint)]==false)  //起点和终点之间无旗子在终点落旗
205                         return true;
206                     if(number_QiZi==1&&this.have[this.CountIndex(toPoint)]==true)  //起点和终点之间仅有一个旗
207                         return true;
208                 }
209 
210                 number_QiZi=0;
211                 if(fromPoint.X<toPoint.X) //起点在终点左边情况
212                 {
213                     for(int j=1;this.GetNextPoint(fromPoint,0,j)!=toPoint;j++)  //判断起点终点之间旗子数量
214                         if(this.have[this.CountIndex(this.GetNextPoint(fromPoint,0,j))]==true)
215                             number_QiZi++;
216                     if(number_QiZi>1)          //如果起点和终点之间的旗子数大于1,则不能落旗
217                         return false;
218                     if(number_QiZi==0&&this.have[this.CountIndex(toPoint)]==false)       //起点和终点之间无旗子,在终点落旗
219                         return true;
220                     if(number_QiZi==1&&this.have[this.CountIndex(toPoint)]==true)  //起点和终点之间仅有一个旗
221                         return true;                
222                 }
223             }                
224             return false;            
225         }
226         //判断***象***的走法是否合理
227         public bool ElephantFoot(Point fromPoint,Point toPoint)
228         {
229             int fromIndex=this.CountIndex(fromPoint);   //起点信息的一维数组的索引
230             int toIndex=this.CountIndex(toPoint);       //终点信息的一维数组的索引            
231                     
232             if(fromPoint==toPoint)  //如果起点和终点是同一个点,则允许放回旗子,重新先其它路
233             {                
234                 return true;
235             }            
236             if(who[fromIndex].Equals(who[toIndex]))  //如果起点和终点是同一边的旗子,则不能落旗
237             {                
238                 return false;            
239             }
240             if(this.IsUpOrDown(fromPoint)!=this.IsUpOrDown(toPoint))  //如果起点和终点所在边不相同(如一个在河上,一个在河下),则不能落旗(即各边的象不能过河)
241                 return false;
242             
243             double twoPoint_Right_Distance=Math.Sqrt((width+width)*(width+width)+(width+width)*(width+width));
244             double twoPoint_True_Distance=Math.Sqrt((fromPoint.XtoPoint.X)*(fromPoint.XtoPoint.X)+(fromPoint.YtoPoint.Y)*(fromPoint.YtoPoint.Y));
245             
246             //判断象的四种走法
247             if(this.GetNextPoint(fromPoint,2,2)==toPoint)  //当象向右下方跳时情况(“右下田”)
248                 if(this.have[this.CountIndex(this.GetNextPoint(fromPoint,1,1))]==false)   //起点右下一个点上没有旗子,也就是不 “塞象” 时可以往上走旗
249                 {                    
250                     if(twoPoint_True_Distance<=twoPoint_Right_Distance)
251                         return true;
252                 }
253             if(this.GetNextPoint(fromPoint,2,2)==toPoint)  //当象向左下方跳时情况(“左下田”)
254                 if(this.have[this.CountIndex(this.GetNextPoint(fromPoint,1,1))]==false)   //起点左下一个点上没有旗子,也就是不 “塞象” 时可以往上走旗
255                 {                    
256                     if(twoPoint_True_Distance<=twoPoint_Right_Distance)
257                         return true;
258                 }
259             if(this.GetNextPoint(fromPoint,2,2)==toPoint)  //当象向右上方跳时情况(“右上田”)
260                 if(this.have[this.CountIndex(this.GetNextPoint(fromPoint,1,1))]==false)   //起点右上一个点上没有旗子,也就是不 “塞象” 时可以往上走旗
261                 {                    
262                     if(twoPoint_True_Distance<=twoPoint_Right_Distance)
263                         return true;
264                 }
265             if(this.GetNextPoint(fromPoint,2,2)==toPoint)  //当象向左上方跳时情况(“左上田”)
266                 if(this.have[this.CountIndex(this.GetNextPoint(fromPoint,1,1))]==false)   //起点左上一个点上没有旗子,也就是不”塞象” 时可以往上走旗
267                 {                    
268                     if(twoPoint_True_Distance<=twoPoint_Right_Distance)
269                         return true;
270                 }        
271             
272             return false;            
273         }
274         //判断***士***的走法是否合理
275         public bool ScholarFoot(Point fromPoint,Point toPoint) 
276         {  
277             int fromIndex=this.CountIndex(fromPoint);   //起点信息的一维数组的索引
278             int toIndex=this.CountIndex(toPoint);       //终点信息的一维数组的索引            
279                     
280             if(fromPoint==toPoint)  //如果起点和终点是同一个点,则允许放回旗子,重新先其它路
281             {                
282                 return true;
283             }            
284             if(who[fromIndex].Equals(who[toIndex]))  //如果起点和终点是同一边的旗子,则不能落旗
285             {                
286                 return false;            
287             }
288             
289             int index=this.CountIndex(toPoint);
290             if(index!=3&&index!=5&&index!=13&&index!=21&&index!=23&&index!=66)
291                 if(index!=68&&index!=76&&index!=84&&index!=86)
292                     return false;      //控制士的活动范围
293 
294             //判断士的四种走法
295             if(this.GetNextPoint(fromPoint,1,1)==toPoint) //士可以往左上方点移动
296                 return true;        
297             if(this.GetNextPoint(fromPoint,1,1)==toPoint)  //士可以往左下方点移动
298                 return true;    
299             if(this.GetNextPoint(fromPoint,1,+1)==toPoint) //士可以往右上方点移动
300                 return true;    
301             if(this.GetNextPoint(fromPoint,1,1)==toPoint)  //士可以往右下方点移动
302                 return true;
303     
304             return false;            
305         }
306         //判断***将/帅***的走法是否合理
307         public bool AgaFoot(Point fromPoint,Point toPoint)
308         {
309             int fromIndex=this.CountIndex(fromPoint);   //起点信息的一维数组的索引
310             int toIndex=this.CountIndex(toPoint);       //终点信息的一维数组的索引            
311                     
312             if(GenEatGen)  //如果将与帅相望(之间没有旗子),这时老将允许直接跳河吃掉对方老将
313                 if((this.whichPicture[fromIndex]==4&&this.whichPicture[toIndex]==27)||(this.whichPicture[fromIndex]==27&&this.whichPicture[toIndex]==4))
314                     return true;            
315             
316             if(fromPoint==toPoint)  //如果起点和终点是同一个点,则允许放回旗子,重新先其它路
317             {                
318                 return true;
319             }            
320             if(who[fromIndex].Equals(who[toIndex]))  //如果起点和终点是同一边的旗子,则不能落旗
321             {                
322                 return false;            
323             }
324 
325             int index=this.CountIndex(toPoint);
326             if(index!=3&&index!=4&&index!=5&&index!=12&&index!=13&&index!=14&&index!=21&&index!=22&&index!=23)
327                 if(index!=66&&index!=67&&index!=68&&index!=75&&index!=76&&index!=77&&index!=84&&index!=85&&index!=86)
328                     return false;        //控制将帅的活动范围
329             
330             //判断 将/帅 的四种走法
331             if(this.GetNextPoint(fromPoint,0,1)==toPoint)  //将/帅可以往左方一点走
332                 return true;        
333             if(this.GetNextPoint(fromPoint,0,1)==toPoint)   //将/帅可以往右方一点走
334                 return true;    
335             if(this.GetNextPoint(fromPoint,1,0)==toPoint)  //将/帅可以往上方一点走
336                 return true;    
337             if(this.GetNextPoint(fromPoint,1,0)==toPoint)    //将/帅可以往下方一点走
338                 return true;            
339             
340             return false;            
341         }
342         public bool AcceptJudge(Point fromPoint,Point toPoint,bool GenEatGen)
343         {            
344             this.GenEatGen=GenEatGen;
345             int index=this.CountIndex(fromPoint);            
346             switch(this.str[index])
347             {
348                 case 黑马:
349                 case 红马:  return HorseFoot(fromPoint,toPoint); 
350                 case 黑兵:
351                 case 红卒:  return ObiitFoot(fromPoint,toPoint);
352                 case 黑車:
353                 case 红車:  return JuFoot(fromPoint,toPoint);
354                 case 黑炮:
355                 case 红炮:  return CannonFoot(fromPoint,toPoint);
356                 case 黑象:
357                 case 红象:  return ElephantFoot(fromPoint,toPoint);
358                 case 黑士:
359                 case 红士:  return ScholarFoot(fromPoint,toPoint);
360                 case 黑将:
361                 case 红帅:  return AgaFoot(fromPoint,toPoint);                
362             }            
363             MessageBox.Show(没法确定您拿的是什么旗子,因此,不知道其步伐规则);
364             return false;
365         }
366         
367         public Point GetNextPoint(Point point,int x,int y)   //得到移动的点
368         {
369             int index=this.CountIndex(point);                        
370             index=index+(x*9);
371             index=index+y;            
372             if(index>=0&&index<90)
373                 return this.CountPoint(index);
374             return new Point(1,1);
375         }
376         public int ChangeQiZi(Point fromPoint,Point toPoint) 
377               // index表示当前活动的pictureBox;  
378               // fromPoint表示pictureBox起点;  toPoint表示pictureBox的位置点
379         {
380             int fromIndex=this.CountIndex(fromPoint);  //起点对应一维数组的索引
381             int toIndex=this.CountIndex(toPoint);      //终点对应一维数组的索引           
382 
383             if(fromPoint==toPoint)
384             {                    
385                 return 0;        //起点和终点是同一个点,不修改旗盘参数                
386             }            
387             if(!this.have[toIndex])
388             {                
389                 //将旗盘起点对应的参数移到第二个点
390                 this.have[toIndex]=this.have[fromIndex];
391                 this.who[toIndex]=this.who[fromIndex].ToString();
392                 this.str[toIndex]=this.str[fromIndex].ToString();
393                 this.whichPicture[toIndex]=this.whichPicture[fromIndex];
394                                 
395                 //将旗盘起点对应的参数初始化s(即将旗子移动之前位置置为空点)
396                 this.have[fromIndex]=false;
397                 this.who[fromIndex]=“”;
398                 this.str[fromIndex]=“”;
399                 this.whichPicture[fromIndex]=-1;        
400             
401                 return 1;
402             }
403             if(this.have[toIndex])
404             {            
405                 //红方旗子被吃一个
406                 if(this.who[toIndex]==red)  
407                     rednum;           
408 
409                 //黑方旗子被吃一个
410                 if(this.who[toIndex]==black)
411                     blacknum;
412 
413                 //将旗盘起点对应的参数移到第二个点
414                 this.have[toIndex]=this.have[fromIndex];
415                 this.who[toIndex]=this.who[fromIndex].ToString();
416                 this.str[toIndex]=this.str[fromIndex].ToString();
417                 this.whichPicture[toIndex]=this.whichPicture[fromIndex];
418                                 
419                 //将旗盘起点对应的参数初始化s(即将旗子移动之前位置置为空点)
420                 this.have[fromIndex]=false;
421                 this.who[fromIndex]=“”;
422                 this.str[fromIndex]=“”;
423                 this.whichPicture[fromIndex]=-1;            
424                 
425                 return 2;               
426             }
427             return 1;            
428 }}

版权声明:本文为lovexyz123原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/lovexyz123/archive/2004/01/13/1582534.html