当前位置: 移动技术网 > IT编程>开发语言>Java > Java棋类游戏实践之单机版五子棋

Java棋类游戏实践之单机版五子棋

2019年07月22日  | 移动技术网IT编程  | 我要评论

本文实例讲述了java实现的五子棋游戏代码,分享给大家供大家参考,具体代码如下

一、实践目标

       1.掌握javagui界面设计
       2.掌握鼠标事件的监听(mouselistener,mousemotionlistener)

二、实践内容

      设计一个简单的五子棋程序,能够实现五子棋下棋过程。如下图所示

 

1.五子棋棋盘类

package cn.edu.ouc.fivechess; 
 
import java.awt.color; 
import java.awt.cursor; 
import java.awt.dimension; 
import java.awt.graphics; 
import java.awt.graphics2d; 
import java.awt.image; 
import java.awt.radialgradientpaint; 
import java.awt.renderinghints; 
import java.awt.toolkit; 
import java.awt.event.mouseevent; 
import java.awt.event.mouselistener; 
import java.awt.event.mousemotionlistener; 
import java.awt.geom.ellipse2d; 
 
import javax.swing.*; 
/** 
 * 五子棋--棋盘类 
 */ 
 
public class chessboard extends jpanel implements mouselistener { 
 public static final int margin=30;//边距 
 public static final int grid_span=35;//网格间距 
 public static final int rows=15;//棋盘行数 
 public static final int cols=15;//棋盘列数 
 
 point[] chesslist=new point[(rows+1)*(cols+1)];//初始每个数组元素为null 
 boolean isblack=true;//默认开始是黑棋先 
 boolean gameover=false;//游戏是否结束 
 int chesscount;//当前棋盘棋子的个数 
 int xindex,yindex;//当前刚下棋子的索引 
 
 image img; 
 image shadows; 
 color colortemp; 
 public chessboard(){ 
 
 // setbackground(color.blue);//设置背景色为橘黄色 
 img=toolkit.getdefaulttoolkit().getimage("board.jpg"); 
 shadows=toolkit.getdefaulttoolkit().getimage("shadows.jpg"); 
 addmouselistener(this); 
 addmousemotionlistener(new mousemotionlistener(){ 
  public void mousedragged(mouseevent e){ 
   
  } 
  
  public void mousemoved(mouseevent e){ 
  int x1=(e.getx()-margin+grid_span/2)/grid_span; 
  //将鼠标点击的坐标位置转成网格索引 
  int y1=(e.gety()-margin+grid_span/2)/grid_span; 
  //游戏已经结束不能下 
  //落在棋盘外不能下 
  //x,y位置已经有棋子存在,不能下 
  if(x1<0||x1>rows||y1<0||y1>cols||gameover||findchess(x1,y1)) 
   setcursor(new cursor(cursor.default_cursor)); 
  //设置成默认状态 
  else setcursor(new cursor(cursor.hand_cursor)); 
  
  } 
 }); 
 } 
 
 
 
//绘制 
 public void paintcomponent(graphics g){ 
 
 super.paintcomponent(g);//画棋盘 
 
 int imgwidth= img.getwidth(this); 
 int imgheight=img.getheight(this);//获得图片的宽度与高度 
 int fwidth=getwidth(); 
 int fheight=getheight();//获得窗口的宽度与高度 
 int x=(fwidth-imgwidth)/2; 
 int y=(fheight-imgheight)/2; 
 g.drawimage(img, x, y, null); 
 
  
 for(int i=0;i<=rows;i++){//画横线 
  g.drawline(margin, margin+i*grid_span, margin+cols*grid_span, margin+i*grid_span); 
 } 
 for(int i=0;i<=cols;i++){//画竖线 
  g.drawline(margin+i*grid_span, margin, margin+i*grid_span, margin+rows*grid_span); 
  
 } 
  
 //画棋子 
 for(int i=0;i<chesscount;i++){ 
  //网格交叉点x,y坐标 
  int xpos=chesslist[i].getx()*grid_span+margin; 
  int ypos=chesslist[i].gety()*grid_span+margin; 
  g.setcolor(chesslist[i].getcolor());//设置颜色 
  // g.filloval(xpos-point.diameter/2, ypos-point.diameter/2, 
    //point.diameter, point.diameter); 
  //g.drawimage(shadows, xpos-point.diameter/2, ypos-point.diameter/2, point.diameter, point.diameter, null); 
  colortemp=chesslist[i].getcolor(); 
  if(colortemp==color.black){ 
  radialgradientpaint paint = new radialgradientpaint(xpos-point.diameter/2+25, ypos-point.diameter/2+10, 20, new float[]{0f, 1f} 
  , new color[]{color.white, color.black}); 
  ((graphics2d) g).setpaint(paint); 
  ((graphics2d) g).setrenderinghint(renderinghints.key_antialiasing, renderinghints.value_antialias_on); 
  ((graphics2d) g).setrenderinghint(renderinghints.key_alpha_interpolation, renderinghints.value_alpha_interpolation_default); 
 
  } 
  else if(colortemp==color.white){ 
  radialgradientpaint paint = new radialgradientpaint(xpos-point.diameter/2+25, ypos-point.diameter/2+10, 70, new float[]{0f, 1f} 
  , new color[]{color.white, color.black}); 
  ((graphics2d) g).setpaint(paint); 
  ((graphics2d) g).setrenderinghint(renderinghints.key_antialiasing, renderinghints.value_antialias_on); 
  ((graphics2d) g).setrenderinghint(renderinghints.key_alpha_interpolation, renderinghints.value_alpha_interpolation_default); 
 
  } 
  
  ellipse2d e = new ellipse2d.float(xpos-point.diameter/2, ypos-point.diameter/2, 34, 35); 
  ((graphics2d) g).fill(e); 
  //标记最后一个棋子的红矩形框 
  
  if(i==chesscount-1){//如果是最后一个棋子 
  g.setcolor(color.red); 
  g.drawrect(xpos-point.diameter/2, ypos-point.diameter/2, 
    34, 35); 
  } 
 } 
 } 
 
 public void mousepressed(mouseevent e){//鼠标在组件上按下时调用 
  
 //游戏结束时,不再能下 
 if(gameover) return; 
  
 string colorname=isblack?"黑棋":"白棋"; 
  
 //将鼠标点击的坐标位置转换成网格索引 
 xindex=(e.getx()-margin+grid_span/2)/grid_span; 
 yindex=(e.gety()-margin+grid_span/2)/grid_span; 
  
 //落在棋盘外不能下 
 if(xindex<0||xindex>rows||yindex<0||yindex>cols) 
  return; 
  
 //如果x,y位置已经有棋子存在,不能下 
 if(findchess(xindex,yindex))return; 
  
 //可以进行时的处理 
 point ch=new point(xindex,yindex,isblack?color.black:color.white); 
 chesslist[chesscount++]=ch; 
 repaint();//通知系统重新绘制 
 
  
 //如果胜出则给出提示信息,不能继续下棋 
  
 if(iswin()){ 
  string msg=string.format("恭喜,%s赢了!", colorname); 
  joptionpane.showmessagedialog(this, msg); 
  gameover=true; 
 } 
 isblack=!isblack; 
 } 
 //覆盖mouselistener的方法 
 public void mouseclicked(mouseevent e){ 
 //鼠标按键在组件上单击时调用 
 } 
 
 public void mouseentered(mouseevent e){ 
 //鼠标进入到组件上时调用 
 } 
 public void mouseexited(mouseevent e){ 
 //鼠标离开组件时调用 
 } 
 public void mousereleased(mouseevent e){ 
 //鼠标按钮在组件上释放时调用 
 } 
 //在棋子数组中查找是否有索引为x,y的棋子存在 
 private boolean findchess(int x,int y){ 
 for(point c:chesslist){ 
  if(c!=null&&c.getx()==x&&c.gety()==y) 
  return true; 
 } 
 return false; 
 } 
 
 
 private boolean iswin(){ 
 int continuecount=1;//连续棋子的个数 
 
 //横向向西寻找 
 for(int x=xindex-1;x>=0;x--){ 
  color c=isblack?color.black:color.white; 
  if(getchess(x,yindex,c)!=null){ 
  continuecount++; 
  }else 
  break; 
 } 
 //横向向东寻找 
 for(int x=xindex+1;x<=cols;x++){ 
  color c=isblack?color.black:color.white; 
  if(getchess(x,yindex,c)!=null){ 
  continuecount++; 
  }else 
  break; 
 } 
 if(continuecount>=5){ 
  return true; 
 }else 
 continuecount=1; 
  
 //继续另一种搜索纵向 
 //向上搜索 
 for(int y=yindex-1;y>=0;y--){ 
  color c=isblack?color.black:color.white; 
  if(getchess(xindex,y,c)!=null){ 
  continuecount++; 
  }else 
  break; 
 } 
 //纵向向下寻找 
 for(int y=yindex+1;y<=rows;y++){ 
  color c=isblack?color.black:color.white; 
  if(getchess(xindex,y,c)!=null) 
  continuecount++; 
  else 
  break; 
  
 } 
 if(continuecount>=5) 
  return true; 
 else 
  continuecount=1; 
  
  
 //继续另一种情况的搜索:斜向 
 //东北寻找 
 for(int x=xindex+1,y=yindex-1;y>=0&&x<=cols;x++,y--){ 
  color c=isblack?color.black:color.white; 
  if(getchess(x,y,c)!=null){ 
  continuecount++; 
  } 
  else break; 
 } 
 //西南寻找 
 for(int x=xindex-1,y=yindex+1;x>=0&&y<=rows;x--,y++){ 
  color c=isblack?color.black:color.white; 
  if(getchess(x,y,c)!=null){ 
  continuecount++; 
  } 
  else break; 
 } 
 if(continuecount>=5) 
  return true; 
 else continuecount=1; 
  
  
 //继续另一种情况的搜索:斜向 
 //西北寻找 
 for(int x=xindex-1,y=yindex-1;x>=0&&y>=0;x--,y--){ 
  color c=isblack?color.black:color.white; 
  if(getchess(x,y,c)!=null) 
  continuecount++; 
  else break; 
 } 
 //东南寻找 
 for(int x=xindex+1,y=yindex+1;x<=cols&&y<=rows;x++,y++){ 
  color c=isblack?color.black:color.white; 
  if(getchess(x,y,c)!=null) 
  continuecount++; 
  else break; 
 } 
 if(continuecount>=5) 
  return true; 
 else continuecount=1; 
  
 return false; 
 } 
 
 
 private point getchess(int xindex,int yindex,color color){ 
 for(point p:chesslist){ 
  if(p!=null&&p.getx()==xindex&&p.gety()==yindex 
   &&p.getcolor()==color) 
  return p; 
 } 
 return null; 
 } 
 
 
 public void restartgame(){ 
 //清除棋子 
 for(int i=0;i<chesslist.length;i++){ 
  chesslist[i]=null; 
 } 
 //恢复游戏相关的变量值 
 isblack=true; 
 gameover=false; //游戏是否结束 
 chesscount =0; //当前棋盘棋子个数 
 repaint(); 
 } 
 
 //悔棋 
 public void goback(){ 
 if(chesscount==0) 
  return ; 
 chesslist[chesscount-1]=null; 
 chesscount--; 
 if(chesscount>0){ 
  xindex=chesslist[chesscount-1].getx(); 
  yindex=chesslist[chesscount-1].gety(); 
 } 
 isblack=!isblack; 
 repaint(); 
 } 
 
 //矩形dimension 
 
 public dimension getpreferredsize(){ 
 return new dimension(margin*2+grid_span*cols,margin*2 
    +grid_span*rows); 
 } 
 
 
 
} 

2.棋子类

package cn.edu.ouc.fivechess; 
 
import java.awt.color; 
/** 
 * 棋子类 
 */ 
public class point { 
 private int x;//棋盘中的x索引 
 private int y;//棋盘中的y索引 
 private color color;//颜色 
 public static final int diameter=30;//直径 
 
 public point(int x,int y,color color){ 
 this.x=x; 
 this.y=y; 
 this.color=color; 
 } 
 
 public int getx(){//拿到棋盘中x的索引 
 return x; 
 } 
 public int gety(){ 
 return y; 
 } 
 public color getcolor(){//获得棋子的颜色 
 return color; 
 } 
} 

3.五子棋主框架类

package cn.edu.ouc.fivechess; 
import java.awt.event.*; 
import java.awt.*; 
 
import javax.swing.*; 
/* 
 五子棋主框架類,程序啟動類 
 */ 
public class startchessjframe extends jframe { 
 private chessboard chessboard; 
 private jpanel toolbar; 
 private jbutton startbutton,backbutton,exitbutton; 
 
 private jmenubar menubar; 
 private jmenu sysmenu; 
 private jmenuitem startmenuitem,exitmenuitem,backmenuitem; 
 //重新开始,退出,和悔棋菜单项 
 public startchessjframe(){ 
 settitle("单机版五子棋");//设置标题 
 chessboard=new chessboard(); 
 
 
 container contentpane=getcontentpane(); 
 contentpane.add(chessboard); 
 chessboard.setopaque(true); 
 
 
 //创建和添加菜单 
 menubar =new jmenubar();//初始化菜单栏 
 sysmenu=new jmenu("系统");//初始化菜单 
 //初始化菜单项 
 startmenuitem=new jmenuitem("重新开始"); 
 exitmenuitem =new jmenuitem("退出"); 
 backmenuitem =new jmenuitem("悔棋"); 
 //将三个菜单项添加到菜单上 
 sysmenu.add(startmenuitem); 
 sysmenu.add(exitmenuitem); 
 sysmenu.add(backmenuitem); 
 //初始化按钮事件监听器内部类 
 myitemlistener lis=new myitemlistener(); 
 //将三个菜单注册到事件监听器上 
 this.startmenuitem.addactionlistener(lis); 
 backmenuitem.addactionlistener(lis); 
 exitmenuitem.addactionlistener(lis); 
 menubar.add(sysmenu);//将系统菜单添加到菜单栏上 
 setjmenubar(menubar);//将menubar设置为菜单栏 
 
 toolbar=new jpanel();//工具面板实例化 
 //三个按钮初始化 
 startbutton=new jbutton("重新开始"); 
 exitbutton=new jbutton("退出"); 
 backbutton=new jbutton("悔棋"); 
 //将工具面板按钮用flowlayout布局 
 toolbar.setlayout(new flowlayout(flowlayout.left)); 
 //将三个按钮添加到工具面板 
 toolbar.add(startbutton); 
 toolbar.add(exitbutton); 
 toolbar.add(backbutton); 
 //将三个按钮注册监听事件 
 startbutton.addactionlistener(lis); 
 exitbutton.addactionlistener(lis); 
 backbutton.addactionlistener(lis); 
 //将工具面板布局到界面”南方“也就是下方 
 add(toolbar,borderlayout.south); 
 add(chessboard);//将面板对象添加到窗体上 
 //设置界面关闭事件 
 setdefaultcloseoperation(jframe.exit_on_close); 
 //setsize(800,800); 
 pack();//自适应大小 
 
 } 
 
 private class myitemlistener implements actionlistener{ 
 public void actionperformed(actionevent e){ 
  object obj=e.getsource();//获得事件源 
  if(obj==startchessjframe.this.startmenuitem||obj==startbutton){ 
  //重新开始 
  //jfiveframe.this内部类引用外部类 
  system.out.println("重新开始"); 
  chessboard.restartgame(); 
  } 
  else if (obj==exitmenuitem||obj==exitbutton) 
  system.exit(0); 
  else if (obj==backmenuitem||obj==backbutton){ 
  system.out.println("悔棋..."); 
  chessboard.goback(); 
  } 
 } 
 } 
 
 
 
 public static void main(string[] args){ 
 startchessjframe f=new startchessjframe();//创建主框架 
 f.setvisible(true);//显示主框架 
 
 } 
} 

三、总结

1.菜单的设计与实现?
2.鼠标点击棋盘后,如何绘制棋子?如何为刚下的棋子绘制一个红色框?
3.棋谱是如何一个数据结构?

以上就是本文的全部内容,希望对大家学习java程序设计有所帮助。

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网