Java实现五子棋游戏(人机对弈+人人对弈)
这周有小学期,所以一直在做小学期,我选择的题目是五子棋游戏。
参考博客:https://blog.csdn.net/oldhunter686/article/details/104039536
界面截图如下:
代码如下:
Main.java
1 package wuziqii; 2 3 /** 4 * Main方法创建了ChessFrame类的一个实例对象(chess_frame) 5 * 并启动屏幕显示 6 * 显示该实例对象 7 * @author Administrator 8 * 9 */ 10 public class Main { 11 @SuppressWarnings("deprecation") 12 public static void main(String[] args) { 13 ChessFrame chess_frame = new ChessFrame(); 14 chess_frame.show(); 15 } 16 }
ChessFrame.java
1 package wuziqii; 2 3 import java.awt.Container; 4 import java.awt.event.ActionEvent; 5 import java.awt.event.ActionListener; 6 import java.awt.event.WindowAdapter; 7 import java.awt.event.WindowEvent; 8 9 import javax.swing.ButtonGroup; 10 import javax.swing.JFrame; 11 import javax.swing.JMenu; 12 import javax.swing.JMenuBar; 13 import javax.swing.JMenuItem; 14 import javax.swing.JOptionPane; 15 import javax.swing.JRadioButtonMenuItem; 16 import javax.swing.SwingUtilities; 17 import javax.swing.UIManager; 18 19 /** 20 * 主要功能: 21 * 创建五子棋游戏主窗体和菜单 22 * @author Administrator 23 * 24 */ 25 @SuppressWarnings("serial") 26 public class ChessFrame extends JFrame implements ActionListener { 27 private String[] strsize= {"20x15","30x20","40x30","50x50"};//棋盘 28 private String[] strmode= {"人机对弈","人人对弈"};//模式 29 30 public static boolean iscomputer=true; 31 public static boolean checkcomputer=true; 32 33 private int width; 34 private int height; 35 private ChessModel chessmodel;//ChessModel.java 36 private MainPanel mainpanel;//MainPanel.java 37 38 //构造五子棋游戏的主窗体 39 public ChessFrame() { 40 //菜单标题 41 this.setTitle("五子棋游戏"); 42 //创建棋盘,默认第一种模式 43 chessmodel=new ChessModel(1);//创建棋盘,默认第一种模式 44 mainpanel=new MainPanel(chessmodel);//落子用的画笔,处理鼠标点击事件 45 Container container=this.getContentPane();//获得当前JFramede的内容面板 46 container.add(mainpanel,"Center");//添加面板对象到当前的jframe 47 this.setResizable(false);//设置当前窗口不能自由改变大小 48 this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//关闭窗口就结束程序 49 //匿名内部类 50 this.addWindowListener(new WindowAdapter(){ 51 public void windowClosing(WindowEvent e){ 52 System.exit(0);//表示在窗口添加一个Windows事件消息,用于退出 53 } 54 }); 55 MapSize(20,15);//棋盘大小(默认) 56 JMenuBar mbar=new JMenuBar();//创建菜单栏对象 57 this.setJMenuBar(mbar); 58 JMenu gameMenu=new JMenu("游戏");//创建菜单栏游戏 59 mbar.add(makeMenu(gameMenu,new Object[] { "开局", "棋盘","模式",null,"退出" },this)); 60 JMenu lookMenu=new JMenu("视图"); 61 mbar.add(makeMenu(lookMenu,new Object[] { "Metal","Motif","Windows" },this)); 62 JMenu helpMenu=new JMenu("帮助"); 63 mbar.add(makeMenu(helpMenu,new Object[] { "游戏介绍" },this)); 64 } 65 66 //构造五子棋游戏的主菜单 67 public JMenu makeMenu(Object parent,Object items[],Object target){ 68 JMenu m=null; 69 if(parent instanceof JMenu) 70 m=(JMenu)parent; 71 else if(parent instanceof String) 72 m=new JMenu((String)parent); 73 else 74 return null; 75 for(int i= 0;i<items.length;i++) 76 if(items[i] == null)//如果为空,在菜单项添加分割线 77 m.addSeparator(); 78 else if(items[i] == "棋盘"){ 79 JMenu jm=new JMenu("棋盘"); 80 //每个JRadioButton都是独立的,需要加入到ButtonGroup对象, 81 ButtonGroup group=new ButtonGroup(); 82 //类表示可以包含在菜单中的复选框。选中菜单中的复选框可将控件的状态从打开更改为关闭或从关闭更改为打开。 83 JRadioButtonMenuItem rmenu; 84 for(int j=0;j<strsize.length;j++){ 85 rmenu=makeRadioButtonMenuItem(strsize[j],target); 86 if(j==0) rmenu.setSelected(true); 87 jm.add(rmenu); 88 group.add(rmenu); 89 } 90 m.add(jm); 91 }else if(items[i] == "模式"){ 92 JMenu jmenu=new JMenu("模式"); 93 ButtonGroup buttongroup=new ButtonGroup(); 94 JRadioButtonMenuItem rmenu; 95 for(int h=0;h<strmode.length;h++){//strmode 人机对弈和人人对弈 96 rmenu=makeRadioButtonMenuItem(strmode[h],target); 97 if(h==0) 98 rmenu.setSelected(true);//默认人机对弈 99 jmenu.add(rmenu); 100 buttongroup.add(rmenu); 101 } 102 m.add(jmenu); 103 }else 104 m.add(makeMenuItem(items[i],target)); 105 return m; 106 } 107 108 //构造五子棋游戏的菜单项 109 public JMenuItem makeMenuItem(Object item,Object target){ 110 JMenuItem jmenuitem= null; 111 if(item instanceof String) 112 jmenuitem=new JMenuItem((String)item); 113 else if(item instanceof JMenuItem) 114 jmenuitem=(JMenuItem)item; 115 else 116 return null; 117 if(target instanceof ActionListener) 118 jmenuitem.addActionListener((ActionListener)target); 119 return jmenuitem; 120 } 121 122 //构造五子棋游戏的单选按钮式菜单项 123 public JRadioButtonMenuItem makeRadioButtonMenuItem(Object item,Object target){ 124 JRadioButtonMenuItem jradiobuttonmenuitem= null; 125 if(item instanceof String) 126 jradiobuttonmenuitem=new JRadioButtonMenuItem((String)item); 127 else if(item instanceof JRadioButtonMenuItem) 128 jradiobuttonmenuitem=(JRadioButtonMenuItem)item; 129 else 130 return null; 131 if(target instanceof ActionListener) 132 jradiobuttonmenuitem.addActionListener((ActionListener)target); 133 return jradiobuttonmenuitem; 134 } 135 136 @SuppressWarnings("static-access") 137 public void MapSize(int width,int height){ 138 setSize(width*20+50,height*20+100); 139 if(this.checkcomputer) 140 this.iscomputer=true; 141 else 142 this.iscomputer=false; 143 //设置棋盘大小的方法 144 mainpanel.setModel(chessmodel); 145 //component中己有的图形发生变化后不会立刻显示,须使用repaint方法 146 mainpanel.repaint(); 147 } 148 149 @SuppressWarnings("static-access") 150 public boolean getiscomputer(){ 151 //返回是否为人机对弈模式 152 return this.iscomputer; 153 } 154 155 public void restart(){ 156 //重新开局的方法 157 int modeChess=chessmodel.getModeChess(); 158 if(modeChess<= 4&&modeChess>= 1){ 159 chessmodel=new ChessModel(modeChess); 160 MapSize(chessmodel.getWidth(),chessmodel.getHeight()); 161 System.out.println("重新开局"); 162 }else{ 163 System.out.println("重新开局失败"); 164 } 165 } 166 167 @SuppressWarnings("static-access") 168 public void actionPerformed(ActionEvent actionevent){ 169 String arg=actionevent.getActionCommand(); 170 171 //视图风格 172 try{ 173 if(arg.equals("Windows")) 174 UIManager.setLookAndFeel( 175 "com.sun.java.swing.plaf.windows.WindowsLookAndFeel"); 176 else if(arg.equals("Motif")) 177 UIManager.setLookAndFeel( 178 "com.sun.java.swing.plaf.motif.MotifLookAndFeel"); 179 else UIManager.setLookAndFeel( 180 "javax.swing.plaf.metal.MetalLookAndFeel"); 181 SwingUtilities.updateComponentTreeUI(this); 182 }catch(Exception ee){} 183 184 if(arg.equals("20x15")){ 185 this.width=20; 186 this.height=15; 187 chessmodel=new ChessModel(1); 188 MapSize(this.width,this.height); 189 SwingUtilities.updateComponentTreeUI(this); 190 } 191 if(arg.equals("30x20")){ 192 this.width=30; 193 this.height=20; 194 chessmodel=new ChessModel(2); 195 MapSize(this.width,this.height); 196 SwingUtilities.updateComponentTreeUI(this); 197 } 198 if(arg.equals("40x30")){ 199 this.width=40; 200 this.height=30; 201 chessmodel=new ChessModel(3); 202 MapSize(this.width,this.height); 203 SwingUtilities.updateComponentTreeUI(this); 204 } 205 if(arg.equals("50x50")){ 206 this.width=50; 207 this.height=50; 208 chessmodel=new ChessModel(4); 209 MapSize(this.width,this.height); 210 SwingUtilities.updateComponentTreeUI(this); 211 } 212 if(arg.equals("人机对弈")){ 213 System.out.println("进入人机对弈模式"); 214 this.checkcomputer=true; 215 this.iscomputer=true; 216 chessmodel=new ChessModel(chessmodel.getModeChess()); 217 MapSize(chessmodel.getWidth(),chessmodel.getHeight()); 218 SwingUtilities.updateComponentTreeUI(this); 219 } 220 if(arg.equals("人人对弈")){ 221 System.out.println("进入人人对弈模式"); 222 this.checkcomputer=false; 223 this.iscomputer=false; 224 chessmodel=new ChessModel(chessmodel.getModeChess()); 225 MapSize(chessmodel.getWidth(),chessmodel.getHeight()); 226 SwingUtilities.updateComponentTreeUI(this); 227 } 228 if(arg.equals("开局")){ 229 restart(); 230 } 231 if(arg.equals("游戏介绍")) { 232 System.out.println("打开游戏介绍"); 233 JOptionPane.showMessageDialog(this,"五子棋是一种受大众广泛喜爱的游戏," 234 + "\n其规则简单,非常富有趣味性和消遣性。" 235 + "\n基本规则:" 236 + "\n选定一方先下,之后黑白双方依次落子。棋盘上形成横向、竖向、斜向的连续的相同颜色的五个棋子称为'五连' 。" 237 + "\n黑白双方先在棋盘上形成五连的一方为胜。" 238 + "\n若对局双方均认为不可能形成五连或是剩余棋盘空间已不足以形成五连则为和棋。", "游戏介绍",0); 239 } 240 if(arg.equals("退出")) { 241 System.out.println("成功退出五子棋游戏"); 242 System.exit(0); 243 } 244 } 245 }
ChessModel.java
1 package wuziqii; 2 3 import javax.swing.JOptionPane; 4 import javax.swing.JPanel; 5 6 /** 7 * 实现整个五子棋程序算法的核心 8 * @author Administrator 9 * 10 */ 11 public class ChessModel { 12 /** 13 * 棋盘的宽度 14 * 棋盘的高度 15 * 棋盘的模式(比如:20x15) 16 * 17 */ 18 private int width,height,modeChess;//棋盘方格的横向、纵向坐标 19 private int x = 0;//棋盘方格横向坐标所对应的棋子颜色 20 private int y = 0;//棋盘方格纵向坐标所对应的棋子颜色 21 private int[][]arrMapShow;//交换棋手的标识,棋盘方格上是否有棋子的标识符 22 23 //获取某棋盘方格是否有棋子的标识值 24 public boolean getisExist() { 25 return this.isExist; 26 } 27 28 //获取棋盘宽度 29 public int getWidth() { 30 return this.width; 31 } 32 33 //获取棋盘高度 34 public int getHeight() { 35 return this.height; 36 } 37 38 //获取棋盘模式 39 public int getModeChess() { 40 return this.modeChess; 41 } 42 43 //获取棋盘方格上棋子的信息 44 public int[][]getarrMapShow(){ 45 return arrMapShow; 46 } 47 48 //记录电脑下子后的横向坐标 49 public void setX(int x) { 50 this.x=x; 51 } 52 //获取电脑下子的横向坐标 53 public int getX() { 54 return this.x; 55 } 56 //记录电脑下子后的纵向坐标 57 public void setY(int y) { 58 this.y=y; 59 } 60 //获取电脑下子的纵向坐标 61 public int getY() { 62 return this.y; 63 } 64 65 /** 66 * 数组arrMapShow只有4个值:1,2,3,-5 67 * 1——该棋盘方格上下的棋子为黑子 68 * 2——该棋盘方格上下的棋子为白子 69 * 3——该棋盘方格上没有棋子 70 * -5——该棋盘方格上不能够下棋子 71 * : 72 */ 73 private boolean isOdd; 74 private boolean isExist; 75 76 //获取是否交换棋手的标识符 77 public boolean getisOdd() { 78 return this.isOdd; 79 } 80 //设置交换棋手的标识符 81 public void setisOdd(boolean isOdd) { 82 if(isOdd) 83 this.isOdd = true; 84 else 85 this.isOdd = false; 86 } 87 88 //构造方法 89 public ChessModel() {} 90 public ChessModel(int modeChess) {//此构造方法根据不同的棋盘模式(modeChess)来构建对应大小的棋盘 91 //默认先手——黑子 92 this.isOdd = true; 93 if(modeChess == 1) { 94 Panellnit(20,15,modeChess); 95 } 96 if(modeChess == 2) { 97 Panellnit(30,20,modeChess); 98 } 99 if(modeChess == 3) { 100 Panellnit(40,30,modeChess); 101 } 102 if(modeChess == 4) { 103 Panellnit(50,50,modeChess); 104 } 105 } 106 107 //按照棋盘模式构建棋盘大小 108 private void Panellnit(int width,int height,int modeChess) { 109 this.width = width; 110 this.height = height; 111 this.modeChess = modeChess; 112 113 arrMapShow = new int[width+1][height+1]; 114 for(int i = 0;i <= width;i++) { 115 for(int j = 0;j <= height;j++) { 116 arrMapShow[i][j] = -5; 117 } 118 } 119 } 120 121 //判断下子的横向、纵向是否越界 122 private boolean badxy(int x,int y) { 123 if(x >= width+20 || x<0) 124 return true; 125 return y>=height||y<0; 126 } 127 128 //计算棋盘上某一方格上八个方向棋子的最大值 129 //八个方向分别为:左-右-上-下-左上-左下-右上-右下 130 public int checkMax(int x,int y,int black_or_white) { 131 int num=0; 132 int max_num; 133 int max_temp=0; 134 int x_temp=x; 135 int y_temp=y; 136 int x_temp1=x_temp; 137 int y_temp1=y_temp; 138 139 //右-x+ 140 for(int i=1;i<5;i++) { 141 x_temp1+=1; 142 if(x_temp1>this.width)//如果到达边界,跳出循环 143 break; 144 if(this.arrMapShow[x_temp1][y_temp1]==black_or_white)//如果右边的下一个落子与当前字相同,num+1 145 num++; 146 else 147 break; 148 } 149 //左-x- 150 x_temp1=x_temp; 151 for(int i=1;i<5;i++) { 152 x_temp1-=1; 153 if(x_temp1<0) 154 break; 155 if(this.arrMapShow[x_temp1][y_temp1]==black_or_white) 156 num++; 157 else 158 break; 159 } 160 if(num<5) 161 max_temp=num; 162 //上-x,y- 163 x_temp1=x_temp; 164 y_temp1=y_temp; 165 num=0; 166 for(int i=1;i<5;i++){ 167 y_temp1-=1; 168 if(y_temp1<0) 169 break; 170 if(this.arrMapShow[x_temp1][y_temp1]==black_or_white) 171 num++; 172 else 173 break; 174 } 175 //下-y+ 176 y_temp1=y_temp; 177 for(int i=1;i<5;i++){ 178 y_temp1+=1; 179 if(y_temp1>this.height) 180 break; 181 if(this.arrMapShow[x_temp1][y_temp1]==black_or_white) 182 num++; 183 else 184 break; 185 } 186 if(num>max_temp&&num<5) 187 max_temp=num; 188 //左上-x-,y- 189 x_temp1=x_temp; 190 y_temp1=y_temp; 191 num=0; 192 for(int i=1;i<5;i++){ 193 x_temp1-=1; 194 y_temp1-=1; 195 if(y_temp1<0||x_temp1<0) 196 break; 197 if(this.arrMapShow[x_temp1][y_temp1]==black_or_white) 198 num++; 199 else 200 break; 201 } 202 //右下-x+,y+ 203 x_temp1=x_temp; 204 y_temp1=y_temp; 205 for(int i=1;i<5;i++){ 206 x_temp1+=1; 207 y_temp1+=1; 208 if(y_temp1>this.height || x_temp1>this.width) 209 break; 210 if(this.arrMapShow[x_temp1][y_temp1]==black_or_white) 211 num++; 212 else 213 break; 214 } 215 if(num>max_temp&&num<5) 216 max_temp=num; 217 //左下-x-,y+ 218 x_temp1=x_temp; 219 y_temp1=y_temp; 220 for(int i=1;i<5;i++){ 221 x_temp1-=1; 222 y_temp1+=1; 223 if(y_temp1>this.height || x_temp1<0) 224 break; 225 if(this.arrMapShow[x_temp1][y_temp1]==black_or_white) 226 num++; 227 else 228 break; 229 } 230 if(num>max_temp&&num<5) 231 max_temp=num; 232 max_num=max_temp; 233 //右上-x+,y- 234 x_temp1=x_temp; 235 y_temp1=y_temp; 236 num=0; 237 for(int i=1;i<5;i++){ 238 x_temp1+=1; 239 y_temp1-=1; 240 if(y_temp1<0||x_temp1>this.width) 241 break; 242 if(this.arrMapShow[x_temp1][y_temp1]==black_or_white) 243 num++; 244 else 245 break; 246 } 247 248 return max_num; 249 } 250 //判断位置是否已经落子-chessExist 251 public boolean chessExist(int i,int j) { 252 if(this.arrMapShow[i][j] == 1 || this.arrMapShow[i][j] == 2)//判断位置是否已经落子 253 return true; 254 return false; 255 } 256 //判断该坐标位置是否可下棋子-readyplay 257 public void readyplay(int x,int y) { 258 if(badxy(x,y))//判断是否越界 259 return; 260 if(chessExist(x,y))//判断是否已经落子 261 return; 262 this.arrMapShow[x][y]=3;//设置为3,可以落子 263 } 264 //在该坐标位置下棋子-play 265 public void play(int x,int y) { 266 if(badxy(x,y)) 267 return;//判断是否越界 268 if(chessExist(x,y)) { 269 this.isExist=true; 270 return;//落子位置已经有子 271 }else { 272 this.isExist=false; 273 } 274 if(getisOdd()) { 275 setisOdd(false); 276 this.arrMapShow[x][y]=1;//先设置isOdd再下子 277 }else { 278 setisOdd(true); 279 this.arrMapShow[x][y]=2; 280 } 281 } 282 283 /** 284 * 计算机走棋 285 * 说明: 286 * 用穷举法判断每一个坐标点的四个方向的的最大棋子数 287 * 最后得出棋子数最大值的坐标 288 * 下子 289 * 290 */ 291 public void computerDo(int width,int height) { 292 int max_black; 293 int max_white; 294 int max_temp; 295 int max=0; 296 297 setisOdd(true); 298 for(int i=0;i<=width;i++) { 299 for(int j=0;j<=height;j++) { 300 if(!chessExist(i,j)) { 301 //如果当前位置没有落子 302 max_white=checkMax(i,j,2);//判断白子的最大值 303 max_black=checkMax(i,j,1);//判断黑子的最大值 304 max_temp=Math.max(max_white, max_black); 305 if(max_temp>max) {//最大值的坐标 306 max=max_temp; 307 this.x=i; 308 this.y=j; 309 } 310 } 311 } 312 } 313 314 setX(this.x); 315 setY(this.y); 316 this.arrMapShow[this.x][this.y]=2;//下子 317 } 318 319 //判断胜负 320 public boolean judgeSuccess(int x,int y,boolean isOdd) { 321 int num=1; 322 int arrvalue; 323 int x_temp=x; 324 int y_temp=y; 325 326 if(isOdd)//白子落子后判断胜负 327 arrvalue=2; 328 else//黑子落子后判断胜负 329 arrvalue=1; 330 331 int x_temp1=x_temp; 332 int y_temp1=y_temp; 333 334 //判断右边-x+ 335 for(int i=1;i<6;i++) { 336 x_temp1+=1; 337 if(x_temp1>this.width) 338 break; 339 if(this.arrMapShow[x_temp1][y_temp1]==arrvalue) 340 num++; 341 else 342 break; 343 } 344 //判断左边-x- 345 x_temp1=x_temp; 346 for(int i=1;i<6;i++){ 347 x_temp1-=1; 348 if(x_temp1<0) 349 break; 350 if(this.arrMapShow[x_temp1][y_temp1]==arrvalue) 351 num++; 352 else 353 break; 354 } 355 if(num==5) 356 return true; 357 //判断上方-x,y- 358 x_temp1=x_temp; 359 y_temp1=y_temp; 360 num=1; 361 for(int i=1;i<6;i++){ 362 y_temp1-=1; 363 if(y_temp1<0) 364 break; 365 if(this.arrMapShow[x_temp1][y_temp1]==arrvalue) 366 num++; 367 else 368 break; 369 } 370 //判断下方-y+ 371 y_temp1=y_temp; 372 for(int i=1;i<6;i++){ 373 y_temp1+=1; 374 if(y_temp1>this.height) 375 break; 376 if(this.arrMapShow[x_temp1][y_temp1]==arrvalue) 377 num++; 378 else 379 break; 380 } 381 if(num==5) 382 return true; 383 //判断左上-x-,y- 384 x_temp1=x_temp; 385 y_temp1=y_temp; 386 num=1; 387 for(int i=1;i<6;i++){ 388 x_temp1-=1; 389 y_temp1-=1; 390 if(y_temp1<0||x_temp1<0) 391 break; 392 if(this.arrMapShow[x_temp1][y_temp1]==arrvalue) 393 num++; 394 else 395 break; 396 } 397 //判断右下-x+,y+ 398 x_temp1=x_temp; 399 y_temp1=y_temp; 400 for(int i=1;i<6;i++){ 401 x_temp1+=1; 402 y_temp1+=1; 403 if(y_temp1>this.height || x_temp1>this.width) 404 break; 405 if(this.arrMapShow[x_temp1][y_temp1]==arrvalue) 406 num++; 407 else 408 break; 409 } 410 if(num==5) 411 return true; 412 //判断右上-x+,y- 413 x_temp1=x_temp; 414 y_temp1=y_temp; 415 num=1; 416 for(int i=1;i<6;i++){ 417 x_temp1+=1; 418 y_temp1-=1; 419 if(y_temp1<0||x_temp1>this.width) 420 break; 421 if(this.arrMapShow[x_temp1][y_temp1]==arrvalue) 422 num++; 423 else break; 424 } 425 //判断左下-x-,y+ 426 x_temp1=x_temp; 427 y_temp1=y_temp; 428 for(int i=1;i<6;i++){ 429 x_temp1-=1; 430 y_temp1+=1; 431 if(y_temp1>this.height || x_temp1<0) 432 break; 433 if(this.arrMapShow[x_temp1][y_temp1]==arrvalue) 434 num++; 435 else 436 break; 437 } 438 if(num==5) 439 return true; 440 441 return false; 442 } 443 444 //赢棋后的提示,根据判断是否为人机模式,以及胜负关系,显示不同的消息 445 public void showSuccess(JPanel jpanel) { 446 if(ChessFrame.iscomputer) { 447 JOptionPane.showMessageDialog(jpanel, "你赢啦!","win",JOptionPane.INFORMATION_MESSAGE); 448 System.out.println("win"); 449 }else { 450 if(isOdd) { 451 JOptionPane.showMessageDialog(jpanel, "白棋赢!","win",JOptionPane.INFORMATION_MESSAGE); 452 System.out.println("白棋win"); 453 }else { 454 JOptionPane.showMessageDialog(jpanel, "黑棋赢!","win",JOptionPane.INFORMATION_MESSAGE); 455 System.out.println("黑棋win"); 456 } 457 } 458 } 459 460 //输棋后的提示 461 public void showDefault(JPanel jpanel) { 462 System.out.println("lost"); 463 JOptionPane.showMessageDialog(jpanel, "很遗憾,你输了!请重新开始!","lost",JOptionPane.INFORMATION_MESSAGE); 464 } 465 }
MainPanel.java
1 package wuziqii; 2 3 import java.awt.Color; 4 import java.awt.Graphics; 5 import java.awt.event.MouseEvent; 6 import java.awt.event.MouseListener; 7 import java.awt.event.MouseMotionListener; 8 import javax.swing.JPanel; 9 10 /** 11 * 功能如下: 12 * 1、构建一个面板,在该面板上画上棋盘; 13 * 2、处理在该棋盘上的鼠标事件(如鼠标左键点击、鼠标右键点击、鼠标拖动等) 14 * @author Administrator 15 * 16 */ 17 @SuppressWarnings("serial") 18 public class MainPanel extends JPanel implements MouseListener,MouseMotionListener { 19 private int width;//棋盘的宽度 20 private int height;//棋盘的高度 21 private ChessModel chessmodel; 22 23 //根据棋盘模式设定面板的大小-MainPanel(ChessModel cm) 24 MainPanel(ChessModel cm){ 25 chessmodel=cm; 26 width=chessmodel.getWidth(); 27 height=chessmodel.getHeight(); 28 addMouseListener(this); 29 } 30 31 //根据棋盘模式设定棋盘的宽度和高度-setModel(ChessModel cm) 32 public void setModel(ChessModel cm){ 33 chessmodel=cm; 34 width=chessmodel.getWidth(); 35 height =chessmodel.getHeight(); 36 } 37 38 //根据坐标计算出棋盘方格棋子的信息(如白子还是黑子),然后调用draw方法在棋盘上画出相应的棋子-paintComponent(Graphocs g) 39 public void paintComponent(Graphics graphics){ 40 super.paintComponent(graphics); 41 for(int j= 0;j<=height; j++){ 42 for(int i=0;i <=width; i++){ 43 int v= chessmodel.getarrMapShow()[i][j]; 44 draw(graphics,i,j,v); 45 } 46 } 47 } 48 49 //根据提供的棋子信息(颜色、坐标)画棋子 50 public void draw(Graphics graphics,int i, int j,int v){ 51 int x=20*i+20; 52 int y=20*j+20; 53 //画棋盘 54 if(i!=width&&j!=height){ 55 graphics.setColor(Color.white); 56 graphics.drawRect(x,y,20,20); 57 } 58 //画黑色棋子 59 if(v== 1){ 60 graphics.setColor(Color.gray); 61 graphics.drawOval(x-8,y-8,16,16); 62 graphics.setColor(Color.black); 63 graphics.fillOval(x-8,y-8,16,16); 64 } 65 //画白色棋子 66 if(v== 2){ 67 graphics.setColor(Color.gray); 68 graphics.drawOval(x-8,y-8,16,16); 69 graphics.setColor(Color.white); 70 graphics.fillOval(x-8,y-8,16,16); 71 } 72 if(v==3){ 73 graphics.setColor(Color.cyan); 74 graphics.drawOval(x-8,y-8,16,16); 75 } 76 } 77 78 //响应鼠标的点击事件,根据鼠标的点击来下棋,根据下棋判断胜负等 79 public void mousePressed(MouseEvent mouseevent){ 80 int x=(mouseevent.getX()-10)/20; 81 int y=(mouseevent.getY()-10)/20; 82 System.out.println("----------------------------------"); 83 System.out.println("x="+x+",y="+y); 84 if(mouseevent.getModifiers()==MouseEvent.BUTTON1_MASK){ 85 chessmodel.play(x,y); 86 //true-白棋,false-黑棋,人人对弈模式 87 System.out.println("黑棋(false),白棋(true):"+chessmodel.getisOdd()); 88 //黑棋输出为1,白棋输出为2 89 System.out.println("黑棋(1),白棋(2):"+chessmodel.getarrMapShow()[x][y]); 90 repaint(); 91 //判断是否胜利并显示消息 92 if(chessmodel.judgeSuccess(x,y,chessmodel.getisOdd())){ 93 chessmodel.showSuccess(this); 94 mouseevent.consume(); 95 ChessFrame.iscomputer=false; 96 } 97 //判断是否为人机对弈 98 //当机器获胜,上一个if语句无效 99 if(ChessFrame.iscomputer&&!chessmodel.getisExist()){ 100 //当是人机模式,且棋盘上有子时,计算机走下一步 101 chessmodel.computerDo(chessmodel.getWidth(),chessmodel.getHeight()); 102 repaint(); 103 if(chessmodel.judgeSuccess(chessmodel.getX(),chessmodel.getY(),chessmodel.getisOdd())){ 104 chessmodel.showDefault(this);//调用ChessModel的showDefault()方法 105 mouseevent.consume(); 106 } 107 } 108 } 109 } 110 111 public void mouseClicked(MouseEvent evt){} 112 public void mouseReleased(MouseEvent evt){} 113 public void mouseEntered(MouseEvent mouseevt){} 114 public void mouseExited(MouseEvent mouseevent){} 115 public void mouseDragged(MouseEvent evt){} 116 117 //响应鼠标的拖动事件 118 public void mouseMoved(MouseEvent mouseevent){ 119 int x=(mouseevent.getX()-10)/ 20; 120 int y=(mouseevent.getY()-10)/ 20; 121 chessmodel.readyplay(x,y); 122 repaint(); 123 } 124 }