算法源自网络(网络源码连接:http://www.mycodes.net/161/6659.htm)
整体思路:用二维数组构建棋盘每一个数组元素封装为一个picturebox附带若干属性(例如:棋子归属方、棋子的类型),用一个抽象基类规定基本的棋子移动规则(例如:不能选中空白picturebox、该红方走棋时不能选中蓝方棋子),具体的棋子单独从基类棋子类派生 重写派生类的方法规定其走棋规则,和相应填充picturebox的图片(例如: 炮不能斜着走不能直线吃子,翻山炮必须吃子且移动路径上只能有一个棋子)
窗体所用控件:lable、timer、picturebox
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Windows.Forms; 6 using System.Drawing; 7 8 namespace 象棋_封_ 9 { 10 enum chess_type 11 { 12 blank, 13 jiang, 14 che, 15 ma, 16 pao, 17 xiang, 18 zu, 19 shi 20 };//棋类的枚举类型 21 enum player_type 22 { 23 blank, 24 red, 25 blue, 26 };//玩家类别的枚举类型 27 abstract class Chess 28 { 29 private static Chess[] cover_blue =new Chess[16];//被吃区 30 private static int r=0; 31 private static Chess[] cover_red = new Chess[16];//被吃区 32 private static int f=0; 33 protected static int chosenX; 34 protected static int chosenY; 35 public static bool chosen; 36 static int n = 1; 37 public static player_type control_side; 38 public PictureBox PB; 39 public chess_type type; 40 public player_type side; 41 public Chess() 42 { 43 side = player_type.blank; 44 type = chess_type.blank; 45 } 46 public abstract bool Move_judge(object sender, int X, int Y, Chess[][] checkerboard); 47 public abstract void Put_picture(); 48 //public void Assignment(chess_type ct, player_type pt, Image pic) 49 //{ 50 // side = pt; 51 // type = ct; 52 // PB.Image = pic; 53 //}//给棋子赋值 54 public void Bg_Tored() 55 { 56 this.PB.BackColor = Color.Red; 57 }//背景变为红色 58 public void Bg_Toblank() 59 { 60 this.PB.BackColor = Color.Transparent; 61 }//背景变为白色 62 private void Chess_Toblank(ref Chess a, PictureBox PB) 63 { 64 this.Bg_Toblank(); 65 this.PB.Image = null; 66 a = new Chess_blank(PB); 67 }//棋子属性清空 68 public static void Clearground(Main f, ref Chess[][] checkerboard)//布置战场 69 { 70 int i, j; 71 Control[] col_blue=null; 72 Control[] col_red=null; 73 Chess.control_side = player_type.red; 74 Chess.chosen = false; 75 //*********************初始化被吃区**************// 76 for (i = 0; i < 16; i++) 77 { 78 cover_blue[i] = new Chess_blank(); 79 cover_red[i] = new Chess_blank(); 80 } 81 for (i = 1; i <= 16; i++) 82 { 83 col_blue = f.Controls.Find("Cover_PBox_blue" + i, false);//检索控件 84 col_red = f.Controls.Find("Cover_PBox_red" + i, false);//检索控件 85 cover_blue[i - 1].PB = col_blue[0] as PictureBox; 86 cover_red[i - 1].PB = col_red[0] as PictureBox; 87 } 88 //*********************初始话被吃区**************// 89 90 //*****************构建棋盘********************// 91 checkerboard = new Chess[10][]; 92 for (i = 0; i < 10; i++) 93 { 94 checkerboard[i] = new Chess[9];//10行9列 95 } 96 for (i = 0; i < 10; i++) 97 for (j = 0; j < 9; j++) 98 { 99 checkerboard[i][j] = new Chess_blank(); 100 } 101 checkerboard[0][0] = new Chess_che(player_type.blue); 102 checkerboard[0][1] = new Chess_ma(player_type.blue); 103 checkerboard[0][2] = new Chess_xiang(player_type.blue); 104 checkerboard[0][3] = new Chess_shi(player_type.blue); 105 checkerboard[0][4] = new Chess_jiang(player_type.blue); 106 checkerboard[0][5] = new Chess_shi(player_type.blue); 107 checkerboard[0][6] = new Chess_xiang(player_type.blue); 108 checkerboard[0][7] = new Chess_ma(player_type.blue); 109 checkerboard[0][8] = new Chess_che(player_type.blue); 110 checkerboard[2][1] = new Chess_pao(player_type.blue); 111 checkerboard[2][7] = new Chess_pao(player_type.blue); 112 checkerboard[3][0] = new Chess_zu(player_type.blue); 113 checkerboard[3][2] = new Chess_zu(player_type.blue); 114 checkerboard[3][4] = new Chess_zu(player_type.blue); 115 checkerboard[3][6] = new Chess_zu(player_type.blue); 116 checkerboard[3][8] = new Chess_zu(player_type.blue); 117 118 119 checkerboard[6][0] = new Chess_zu(player_type.red); 120 checkerboard[6][2] = new Chess_zu(player_type.red); 121 checkerboard[6][4] = new Chess_zu(player_type.red); 122 checkerboard[6][6] = new Chess_zu(player_type.red); 123 checkerboard[6][8] = new Chess_zu(player_type.red); 124 checkerboard[7][1] = new Chess_pao(player_type.red); 125 checkerboard[7][7] = new Chess_pao(player_type.red); 126 checkerboard[9][0] = new Chess_che(player_type.red); 127 checkerboard[9][1] = new Chess_ma(player_type.red); 128 checkerboard[9][2] = new Chess_xiang(player_type.red); 129 checkerboard[9][3] = new Chess_shi(player_type.red); 130 checkerboard[9][4] = new Chess_jiang(player_type.red); 131 checkerboard[9][5] = new Chess_shi(player_type.red); 132 checkerboard[9][6] = new Chess_xiang(player_type.red); 133 checkerboard[9][7] = new Chess_ma(player_type.red); 134 checkerboard[9][8] = new Chess_che(player_type.red); 135 for (i = 0; i < 10; i++) 136 for (j = 0; j < 9; j++)//control 是一个存放控件类的容器 137 { 138 Control[] col = f.Controls.Find("pictureBox" + (i * 9 + j + 1), false);//检索控件 139 checkerboard[i][j].PB = col[0] as PictureBox;//类型转换 140 checkerboard[i][j].PB.Location = new Point(170 + 60 * j, 57 * i); 141 } 142 for (i = 0; i < 10; i++) 143 for (j = 0; j < 9; j++) 144 { 145 checkerboard[i][j].Put_picture(); 146 } 147 //*****************构建棋盘********************// 148 } 149 protected static int Getx(object sender) 150 { 151 int x; 152 string name = (sender as PictureBox).Name; 153 string number = name.Substring(10);//在字符串中从指定位开始检索(这里是在x后也就是picturebox控件ID不同的尾号) 154 int index = Convert.ToInt32(number); 155 x = (index - 1) / 9;//列 156 return x; 157 } 158 protected static int Gety(object sender) 159 { 160 int y; 161 string name = (sender as PictureBox).Name; 162 string number = name.Substring(10);//在字符串中从指定位开始检索(这里是在x后也就是picturebox控件ID不同的尾号) 163 int index = Convert.ToInt32(number); 164 y = (index - 1) % 9;//行 165 return y; 166 } 167 public static void Nochozen_dispose(object sender, Chess[][] checkerboard) 168 { 169 Chess.chosen = true; 170 chosenX = Chess.Getx(sender); 171 chosenY = Chess.Gety(sender); 172 if (checkerboard[chosenX][chosenY].side != control_side)//选择的不是当前应该走棋的一方 173 { 174 chosen = false; 175 return; 176 } 177 if (checkerboard[chosenX][chosenY].side != player_type.blank)//选择的不是空白 178 checkerboard[chosenX][chosenY].Bg_Tored(); 179 return; 180 } 181 public static bool Chozen_dispose(object sender, Chess[][] checkerboard) 182 { 183 Chess.chosen = false; 184 int x= Getx(sender); 185 int y= Gety(sender); 186 if (checkerboard[chosenX][chosenY].side == checkerboard[x][y].side)//移动位置与选择位是同一阵营 187 { 188 checkerboard[chosenX][chosenY].Bg_Toblank(); 189 return false; 190 } 191 if (checkerboard[chosenX][chosenY].side == player_type.blank)//选中的是空白 192 return false; 193 if (checkerboard[chosenX][chosenY].type == chess_type.ma || checkerboard[chosenX][chosenY].type == chess_type.xiang || checkerboard[chosenX][chosenY].type == chess_type.shi)//马象士的移动不能同y或同x 194 { 195 if (chosenX == x || chosenY == y) 196 { 197 checkerboard[chosenX][chosenY].Bg_Toblank(); 198 return false; 199 } 200 } 201 else 202 { 203 if (chosenX != x && chosenY != y)//其他棋类都必须同x或同y移动 204 { 205 checkerboard[chosenX][chosenY].Bg_Toblank(); 206 return false; 207 } 208 } 209 210 if (!checkerboard[chosenX][chosenY].Move_judge(sender, x, y, checkerboard)) 211 { 212 checkerboard[chosenX][chosenY].Bg_Toblank(); 213 return false; 214 } 215 if (Chess.Setmove(checkerboard, x, y)) 216 return true; 217 else 218 return false; 219 } 220 static bool Setmove(Chess[][] checkerboard,int X,int Y) 221 { 222 n++; 223 bool over = false; 224 player_type z=player_type.blank; 225 if (checkerboard[X][Y].type == chess_type.jiang) 226 { 227 over = true; 228 z = checkerboard[X][Y].side; 229 } 230 if (checkerboard[X][Y].PB.Image!=null) 231 Cover(checkerboard[X][Y]); 232 Chess.Change(ref checkerboard[Chess.chosenX][Chess.chosenY],ref checkerboard[X][Y]); 233 Chess.chosen = false; 234 if (over) 235 { 236 if (z == player_type.blue) 237 MessageBox.Show("红方胜利"); 238 else 239 MessageBox.Show("蓝方胜利"); 240 End f = new End(Time.fen + "分" + Time.miao + "秒"); 241 f.Show(); 242 return true; 243 } 244 if (n % 2 == 0) 245 Chess.control_side = player_type.blue; 246 else 247 Chess.control_side = player_type.red; 248 return false; 249 } 250 private static void Change(ref Chess a,ref Chess b)//a子位移到b子 251 { 252 Chess c = new Chess_blank(); 253 c.PB = b.PB; 254 switch (a.type) 255 { 256 case chess_type.zu: 257 b = new Chess_zu(a.side);break; 258 case chess_type.pao: 259 b = new Chess_pao(a.side);break; 260 case chess_type.che: 261 b = new Chess_che(a.side); break; 262 case chess_type.ma: 263 b = new Chess_ma(a.side); break; 264 case chess_type.xiang: 265 b = new Chess_xiang(a.side); break; 266 case chess_type.shi: 267 b = new Chess_shi(a.side); break; 268 case chess_type.jiang: 269 b = new Chess_jiang(a.side); break; 270 } 271 b.type = a.type; 272 b.side = a.side; 273 b.PB = c.PB; 274 b.PB.Image = a.PB.Image; 275 a.Chess_Toblank(ref a,a.PB); 276 } 277 private static void Cover(Chess a) 278 { 279 if (a.side == player_type.blue) 280 { 281 Change(ref a, ref cover_red[r]); 282 r++; 283 } 284 else 285 { 286 Change(ref a, ref cover_blue[f]); 287 f++; 288 } 289 290 }//棋子被吃后移动到被吃区 291 292 } 293 }