五子棋小游戏 功能模块图 开始游戏
执棋子颜色
五子棋游戏
黑子先行
判断胜负
游戏结束
图1.功能模块图
设计结果与分析 (1)五子棋游戏的主界面,如图2所示。
图2程序主界面
(2)五子棋游戏的结束界面,如图3所示。
图3游戏结束界面
(3)游戏游戏栏中的各个选项,如图4所示。
图4Game栏中的选项
(4)视图设置栏中的各个选项,如图5所示。
图5Configure栏中的各个选项
(5)Help帮助栏中的选项,如图6所示。
图6Help栏中的选项
(6)点击Help栏中的About选项弹出的界面,如图7所示。
图7About选项弹出时的界面
4.设计体会 通过这次课程设计,我进一步加深对基础理论的理解,扩大专业知识面,对收集资料、查阅文献、方案制定等实践方面得到了很好的锻练,促进对所学知识应用能力的提高。同时我渐渐的复习了Java使用方法和编程语法,之后的编程过程也相对得心应手,基本完成了预期计划的要求。在此感谢我的指导老师—冯云老师,她在课题的研究上不遗余力的给予指导。她严谨的治学态度深深的影响了我,使我受益匪浅! 5.参考文献 [1]耿祥义.JAVA大学实用教程.北京:电子工业出版社.2005.3:85-113 [2]HYPERLINK"http://shop.csai.cn/itbook/booklist.asp?zuoz=%D6%EC%D5%BD%C1%A2"\t"_blank"朱战立,HYPERLINK"http://shop.csai.cn/itbook/booklist.asp?zuoz=%C9%F2%CE%B0"\t"_blank"沈伟.Java程序设计实用指南.北京:HYPERLINK"http://shop.csai.cn/itbook/publisher_dz.asp"\t"_blank"电子工业出版社,2005.1:48-135 [3]HYPERLINK"http://search.book.dangdang.com/search.aspx?category=01&key2=%cc%c6%b4%f3%ca%cb"唐大仕.Java程序设计[M].北京:HYPERLINK"http://search.book.dangdang.com/search.aspx?category=01&key3=%b1%b1%b7%bd%bd%bb%cd%a8%b4%f3%d1%a7%b3%f6%b0%e6%c9%e7"北方交通大学出版社:2007.05:56-92 [4]叶核亚.JAVA2程序设计实用教程[M].北京:电子工业出版社;2008.4:64-98 [5]HYPERLINK"http://search.book.dangdang.com/search.aspx?category=01&key2=%u90A2%u7D20%u840D"\t"_blank"邢素萍.JAVA办公自动化项目方案精解[M].北京:HYPERLINK"http://search.book.dangdang.com/search.aspx?category=01&key3=%u822A%u7A7A%u5DE5%u4E1A%u51FA%u7248%u793E"\t"_blank"航空工业出版社,2006.9:35-120
附录 //Java编程:五子棋游戏源代码 importjava.awt.; importjava.awt.event.; importjava.applet.; importjavax.swing.; importjava.io.PrintStream; importjavax.swing.JComponent; importjavax.swing.JPanel;
/ main方法创建了ChessFrame类的一个实例对象(cf), 并启动屏幕显示显示该实例对象。 / publicclassFiveChessAppletDemo{ publicstaticvoidmain(Stringargs[]){ ChessFramecf=newChessFrame(); cf.show(); } }
/ 类ChessFrame主要功能是创建五子棋游戏主窗体和菜单 / classChessFrameextendsJFrameimplementsActionListener{ privateString[]strsize={"20x20","30x20","40x30"}; privateString[]strmode={"人机对弈","人人对弈"}; publicstaticbooleaniscomputer=true,checkcomputer=true; privateintwidth,height; privateChessModelcm; privateMainPanelmp;
//构造五子棋游戏的主窗体 publicChessFrame(){ this.setTitle("五子棋游戏"); cm=newChessModel(1); mp=newMainPanel(cm); Containercon=this.getContentPane(); con.add(mp,"Center"); this.setResizable(false); this.addWindowListener(newChessWindowEvent()); MapSize(20,20); JMenuBarmbar=newJMenuBar(); this.setJMenuBar(mbar); JMenugameMenu=newJMenu("游戏"); mbar.add(makeMenu(gameMenu,newObject[]{ "开局","棋盘","模式",null,"退出" },this)); JMenulookMenu=newJMenu("视图"); mbar.add(makeMenu(lookMenu,newObject[]{ "Metal","Motif","Windows" },this)); JMenuhelpMenu=newJMenu("帮助"); mbar.add(makeMenu(helpMenu,newObject[]{ "关于" },this)); }
//构造五子棋游戏的主菜单 publicJMenumakeMenu(Objectparent,Objectitems[],Objecttarget){ JMenum=null; if(parentinstanceofJMenu) m=(JMenu)parent; elseif(parentinstanceofString) m=newJMenu((String)parent); else returnnull; for(inti=0;iif(items[i]==null) m.addSeparator(); elseif(items[i]=="棋盘"){ JMenujm=newJMenu("棋盘"); ButtonGroupgroup=newButtonGroup(); JRadioButtonMenuItemrmenu; for(intj=0;jrmenu=makeRadioButtonMenuItem(strsize[j],target); if(j==0) rmenu.setSelected(true); jm.add(rmenu); group.add(rmenu); } m.add(jm); }elseif(items[i]=="模式"){ JMenujm=newJMenu("模式"); ButtonGroupgroup=newButtonGroup(); JRadioButtonMenuItemrmenu; for(inth=0;hrmenu=makeRadioButtonMenuItem(strmode[h],target); if(h==0) rmenu.setSelected(true); jm.add(rmenu); group.add(rmenu); } m.add(jm); }else m.add(makeMenuItem(items[i],target)); returnm; }
//构造五子棋游戏的菜单项 publicJMenuItemmakeMenuItem(Objectitem,Objecttarget){ JMenuItemr=null; if(iteminstanceofString) r=newJMenuItem((String)item); elseif(iteminstanceofJMenuItem) r=(JMenuItem)item; else returnnull; if(targetinstanceofActionListener) r.addActionListener((ActionListener)target); returnr; }
//构造五子棋游戏的单选按钮式菜单项 publicJRadioButtonMenuItemmakeRadioButtonMenuItem( Objectitem,Objecttarget){ JRadioButtonMenuItemr=null; if(iteminstanceofString) r=newJRadioButtonMenuItem((String)item); elseif(iteminstanceofJRadioButtonMenuItem) r=(JRadioButtonMenuItem)item; else returnnull; if(targetinstanceofActionListener) r.addActionListener((ActionListener)target); returnr; }
publicvoidMapSize(intw,inth){ setSize(w20+50,h20+100); if(this.checkcomputer) this.iscomputer=true; else this.iscomputer=false; mp.setModel(cm); mp.repaint(); }
publicbooleangetiscomputer(){ returnthis.iscomputer; }
publicvoidrestart(){ intmodeChess=cm.getModeChess(); if(modeChess<=3&&modeChess>=1){ cm=newChessModel(modeChess); MapSize(cm.getWidth(),cm.getHeight()); }else{ System.out.println("\u81EA\u5B9A\u4E49"); } }
publicvoidactionPerformed(ActionEvente){ Stringarg=e.getActionCommand(); try{ if(arg.equals("Windows")) UIManager.setLookAndFeel( "com.sun.java.swing.plaf.windows.WindowsLookAndFeel"); elseif(arg.equals("Motif")) UIManager.setLookAndFeel( "com.sun.java.swing.plaf.motif.MotifLookAndFeel"); else UIManager.setLookAndFeel( "javax.swing.plaf.metal.MetalLookAndFeel"); SwingUtilities.updateComponentTreeUI(this); }catch(Exceptionee){} if(arg.equals("20x20")){ this.width=20; this.height=20; cm=newChessModel(1); MapSize(this.width,this.height); SwingUtilities.updateComponentTreeUI(this); } if(arg.equals("30x20")){ this.width=30; this.height=20; cm=newChessModel(2); MapSize(this.width,this.height); SwingUtilities.updateComponentTreeUI(this); } if(arg.equals("40x30")){ this.width=40; this.height=30; cm=newChessModel(3); MapSize(this.width,this.height); SwingUtilities.updateComponentTreeUI(this); } if(arg.equals("人机对弈")){ this.checkcomputer=true; this.iscomputer=true; cm=newChessModel(cm.getModeChess()); MapSize(cm.getWidth(),cm.getHeight()); SwingUtilities.updateComponentTreeUI(this); } if(arg.equals("人人对弈")){ this.checkcomputer=false; this.iscomputer=false; cm=newChessModel(cm.getModeChess()); MapSize(cm.getWidth(),cm.getHeight()); SwingUtilities.updateComponentTreeUI(this); } if(arg.equals("开局")){ restart(); } if(arg.equals("关于")) JOptionPane.showMessageDialog(this,"该五子棋游戏测试版本版权仅属魏得龙所有!","关于",1); if(arg.equals("退出")) System.exit(0); } }
/ 类ChessModel实现了整个五子棋程序算法的核心 / classChessModel{ //棋盘的宽度、高度、棋盘的模式(如20×20) privateintwidth,height,modeChess; //棋盘方格的横向、纵向坐标 privateintx=0,y=0; //棋盘方格的横向、纵向坐标所对应的棋子颜色, //数组arrMapShow只有3个值:1,2,3,-5, //其中1代表该棋盘方格上下的棋子为黑子, //2代表该棋盘方格上下的棋子为白子, //3代表为该棋盘方格上没有棋子, //-5代表该棋盘方格不能够下棋子 privateint[][]arrMapShow; //交换棋手的标识,棋盘方格上是否有棋子的标识符 privatebooleanisOdd,isExist;
publicChessModel(){}
//该构造方法根据不同的棋盘模式(modeChess)来构建对应大小的棋盘 publicChessModel(intmodeChess){ this.isOdd=true; if(modeChess==1){ PanelInit(20,20,modeChess); } if(modeChess==2){ PanelInit(30,20,modeChess); } if(modeChess==3){ PanelInit(40,30,modeChess); } }
//按照棋盘模式构建棋盘大小 privatevoidPanelInit(intwidth,intheight,intmodeChess){ this.width=width; this.height=height; this.modeChess=modeChess; arrMapShow=newint[width+1][height+1]; for(inti=0;i<=width;i++){ for(intj=0;j<=height;j++){ arrMapShow[i][j]=-5; } } }
//获取是否交换棋手的标识符 publicbooleangetisOdd(){ returnthis.isOdd; }
//设置交换棋手的标识符 publicvoidsetisOdd(booleanisodd){ if(isodd) this.isOdd=true; else this.isOdd=false; }
//获取某棋盘方格是否有棋子的标识值 publicbooleangetisExist(){ returnthis.isExist; }
//获取棋盘宽度 publicintgetWidth(){ returnthis.width; }
//获取棋盘高度 publicintgetHeight(){ returnthis.height; }
//获取棋盘模式 publicintgetModeChess(){ returnthis.modeChess; }
//获取棋盘方格上棋子的信息 publicint[][]getarrMapShow(){ returnarrMapShow; }
//判断下子的横向、纵向坐标是否越界 privatebooleanbadxy(intx,inty){ if(x>=width+20||x<0) returntrue; returny>=height+20||y<0; }
//计算棋盘上某一方格上八个方向棋子的最大值, //这八个方向分别是:左、右、上、下、左上、左下、右上、右下 publicbooleanchessExist(inti,intj){ if(this.arrMapShow[i][j]==1||this.arrMapShow[i][j]==2) returntrue; returnfalse; }
//判断该坐标位置是否可下棋子 publicvoidreadyplay(intx,inty){ if(badxy(x,y)) return; if(chessExist(x,y)) return; this.arrMapShow[x][y]=3; }
//在该坐标位置下棋子 publicvoidplay(intx,inty){ if(badxy(x,y)) return; if(chessExist(x,y)){ this.isExist=true; return; }else this.isExist=false; if(getisOdd()){ setisOdd(false); this.arrMapShow[x][y]=1; }else{ setisOdd(true); this.arrMapShow[x][y]=2; } }
//计算机走棋 / 说明:用穷举法判断每一个坐标点的四个方向的的最大棋子数, 最后得出棋子数最大值的坐标,下子 / publicvoidcomputerDo(intwidth,intheight){ intmax_black,max_white,max_temp,max=0; setisOdd(true); System.out.println("计算机走棋..."); for(inti=0;i<=width;i++){ for(intj=0;j<=height;j++){ if(!chessExist(i,j)){//算法判断是否下子 max_white=checkMax(i,j,2);//判断白子的最大值 max_black=checkMax(i,j,1);//判断黑子的最大值 max_temp=Math.max(max_white,max_black); if(max_temp>max){ max=max_temp; this.x=i; this.y=j; } } } } setX(this.x); setY(this.y); this.arrMapShow[this.x][this.y]=2; }
//记录电脑下子后的横向坐标 publicvoidsetX(intx){ this.x=x; }
//记录电脑下子后的纵向坐标 publicvoidsetY(inty){ this.y=y; }
//获取电脑下子的横向坐标 publicintgetX(){ returnthis.x; }
//获取电脑下子的纵向坐标 publicintgetY(){ returnthis.y; }
//计算棋盘上某一方格上八个方向棋子的最大值, //这八个方向分别是:左、右、上、下、左上、左下、右上、右下 publicintcheckMax(intx,inty,intblack_or_white){ intnum=0,max_num,max_temp=0; intx_temp=x,y_temp=y; intx_temp1=x_temp,y_temp1=y_temp; //judgeright for(inti=1;i<5;i++){ x_temp1+=1; if(x_temp1>this.width) break; if(this.arrMapShow[x_temp1][y_temp1]==black_or_white) num++; else break; } //judgeleft x_temp1=x_temp; for(inti=1;i<5;i++){ x_temp1-=1; if(x_temp1<0) break; if(this.arrMapShow[x_temp1][y_temp1]==black_or_white) num++; else break; } if(num<5) max_temp=num;
//judgeup x_temp1=x_temp; y_temp1=y_temp; num=0; for(inti=1;i<5;i++){ y_temp1-=1; if(y_temp1<0) break; if(this.arrMapShow[x_temp1][y_temp1]==black_or_white) num++; else break; } //judgedown y_temp1=y_temp; for(inti=1;i<5;i++){ y_temp1+=1; if(y_temp1>this.height) break; if(this.arrMapShow[x_temp1][y_temp1]==black_or_white) num++; else break; } if(num>max_temp&&num<5) max_temp=num;
//judgeleft_up x_temp1=x_temp; y_temp1=y_temp; num=0; for(inti=1;i<5;i++){ x_temp1-=1; y_temp1-=1; if(y_temp1<0||x_temp1<0) break; if(this.arrMapShow[x_temp1][y_temp1]==black_or_white) num++; else break; } //judgeright_down x_temp1=x_temp; y_temp1=y_temp; for(inti=1;i<5;i++){ x_temp1+=1; y_temp1+=1; if(y_temp1>this.height||x_temp1>this.width) break; if(this.arrMapShow[x_temp1][y_temp1]==black_or_white) num++; else break; } if(num>max_temp&&num<5) max_temp=num;
//judgeright_up x_temp1=x_temp; y_temp1=y_temp; num=0; for(inti=1;i<5;i++){ x_temp1+=1; y_temp1-=1; if(y_temp1<0||x_temp1>this.width) break; if(this.arrMapShow[x_temp1][y_temp1]==black_or_white) num++; else break; } //judgeleft_down x_temp1=x_temp; y_temp1=y_temp; for(inti=1;i<5;i++){ x_temp1-=1; y_temp1+=1; if(y_temp1>this.height||x_temp1<0) break; if(this.arrMapShow[x_temp1][y_temp1]==black_or_white) num++; else break; } if(num>max_temp&&num<5) max_temp=num; max_num=max_temp; returnmax_num; }
//判断胜负 publicbooleanjudgeSuccess(intx,inty,booleanisodd){ intnum=1; intarrvalue; intx_temp=x,y_temp=y; if(isodd) arrvalue=2; else arrvalue=1; intx_temp1=x_temp,y_temp1=y_temp; //判断右边 for(inti=1;i<6;i++){ x_temp1+=1; if(x_temp1>this.width) break; if(this.arrMapShow[x_temp1][y_temp1]==arrvalue) num++; else break; } //判断左边 x_temp1=x_temp; for(inti=1;i<6;i++){ x_temp1-=1; if(x_temp1<0) break; if(this.arrMapShow[x_temp1][y_temp1]==arrvalue) num++; else break; } if(num==5) returntrue;
//判断上方 x_temp1=x_temp; y_temp1=y_temp; num=1; for(inti=1;i<6;i++){ y_temp1-=1; if(y_temp1<0) break; if(this.arrMapShow[x_temp1][y_temp1]==arrvalue) num++; else break; } //判断下方 y_temp1=y_temp; for(inti=1;i<6;i++){ y_temp1+=1; if(y_temp1>this.height) break; if(this.arrMapShow[x_temp1][y_temp1]==arrvalue) num++; else break; } if(num==5) returntrue;
//判断左上 x_temp1=x_temp; y_temp1=y_temp; num=1; for(inti=1;i<6;i++){ x_temp1-=1; y_temp1-=1; if(y_temp1<0||x_temp1<0) break; if(this.arrMapShow[x_temp1][y_temp1]==arrvalue) num++; else break; } //判断右下 x_temp1=x_temp; y_temp1=y_temp; for(inti=1;i<6;i++){ x_temp1+=1; y_temp1+=1; if(y_temp1>this.height||x_temp1>this.width) break; if(this.arrMapShow[x_temp1][y_temp1]==arrvalue) num++; else break; } if(num==5) returntrue;
//判断右上 x_temp1=x_temp; y_temp1=y_temp; num=1; for(inti=1;i<6;i++){ x_temp1+=1; y_temp1-=1; if(y_temp1<0||x_temp1>this.width) break; if(this.arrMapShow[x_temp1][y_temp1]==arrvalue) num++; else break; } //判断左下 x_temp1=x_temp; y_temp1=y_temp; for(inti=1;i<6;i++){ x_temp1-=1; y_temp1+=1; if(y_temp1>this.height||x_temp1<0) break; if(this.arrMapShow[x_temp1][y_temp1]==arrvalue) num++; else break; } if(num==5) returntrue; returnfalse; }
//赢棋后的提示 publicvoidshowSuccess(JPaneljp){ JOptionPane.showMessageDialog(jp,"你赢了,好厉害!","win", JOptionPane.INFORMATION_MESSAGE); }
//输棋后的提示 publicvoidshowDefeat(JPaneljp){ JOptionPane.showMessageDialog(jp,"你输了,请重新开始!","lost", JOptionPane.INFORMATION_MESSAGE); } }
/ 类MainPanel主要完成如下功能: 1、构建一个面板,在该面板上画上棋盘; 2、处理在该棋盘上的鼠标事件(如鼠标左键点击、鼠标右键点击、鼠标拖动等) / classMainPanelextendsJPanel implementsMouseListener,MouseMotionListener{ privateintwidth,height;//棋盘的宽度和高度 privateChessModelcm;
//根据棋盘模式设定面板的大小 MainPanel(ChessModelmm){ cm=mm; width=cm.getWidth(); height=cm.getHeight(); addMouseListener(this); }
//根据棋盘模式设定棋盘的宽度和高度 publicvoidsetModel(ChessModelmm){ cm=mm; width=cm.getWidth(); height=cm.getHeight(); }
//根据坐标计算出棋盘方格棋子的信息(如白子还是黑子), //然后调用draw方法在棋盘上画出相应的棋子 publicvoidpaintComponent(Graphicsg){ super.paintComponent(g); for(intj=0;j<=height;j++){ for(inti=0;i<=width;i++){ intv=cm.getarrMapShow()[i][j]; draw(g,i,j,v); } } }
//根据提供的棋子信息(颜色、坐标)画棋子 publicvoiddraw(Graphicsg,inti,intj,intv){ intx=20i+20; inty=20j+20; //画棋盘 if(i!=width&&j!=height){ g.setColor(Color.black); g.drawRect(x,y,20,20); } //画黑色棋子 if(v==1){ g.setColor(Color.gray); g.drawOval(x-8,y-8,16,16); g.setColor(Color.black); g.fillOval(x-8,y-8,16,16); } //画白色棋子 if(v==2){ g.setColor(Color.gray); g.drawOval(x-8,y-8,16,16); g.setColor(Color.white); g.fillOval(x-8,y-8,16,16); } if(v==3){ g.setColor(Color.cyan); g.drawOval(x-8,y-8,16,16); } }
//响应鼠标的点击事件,根据鼠标的点击来下棋, //根据下棋判断胜负等 publicvoidmousePressed(MouseEventevt){ intx=(evt.getX()-10)/20; inty=(evt.getY()-10)/20; System.out.println(x+""+y); if(evt.getModifiers()==MouseEvent.BUTTON1_MASK){ cm.play(x,y); System.out.println(cm.getisOdd()+""+cm.getarrMapShow()[x][y]); repaint(); if(cm.judgeSuccess(x,y,cm.getisOdd())){ cm.showSuccess(this); evt.consume(); ChessFrame.iscomputer=false; } //判断是否为人机对弈 if(ChessFrame.iscomputer&&!cm.getisExist()){ cm.computerDo(cm.getWidth(),cm.getHeight()); repaint(); if(cm.judgeSuccess(cm.getX(),cm.getY(),cm.getisOdd())){ cm.showDefeat(this); evt.consume(); } } } }
publicvoidmouseClicked(MouseEventevt){} publicvoidmouseReleased(MouseEventevt){} publicvoidmouseEntered(MouseEventmouseevt){} publicvoidmouseExited(MouseEventmouseevent){} publicvoidmouseDragged(MouseEventevt){}
//响应鼠标的拖动事件 publicvoidmouseMoved(MouseEventmoveevt){ intx=(moveevt.getX()-10)/20; inty=(moveevt.getY()-10)/20; cm.readyplay(x,y); repaint(); } }
classChessWindowEventextendsWindowAdapter{ publicvoidwindowClosing(WindowEvente){ System.exit(0); }
ChessWindowEvent()
{ } } |
|