欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

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

程序员文章站 2024-03-09 10:34:11
本文实例讲述了java实现的五子棋游戏代码,分享给大家供大家参考,具体代码如下 一、实践目标       ...

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

一、实践目标

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

二、实践内容

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

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

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程序设计有所帮助。