结构
代码:
Test:
package gobang2; public class Test { public static void main(String[] args) { // TODO Auto-generated method stub FiveChessFrame f=new FiveChessFrame(); } }
FiveChessFrame:
package gobang2; import java.awt.Color; import java.awt.Font; import java.awt.Graphics; import java.awt.Image; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; import javax.imageio.ImageIO; import javax.swing.JFrame; import javax.swing.JOptionPane; public class FiveChessFrame extends JFrame implements MouseListener,Runnable{ //棋子坐标 int x; int y; //数组保存棋子 19*19的二维数组 当数组的元素值为0表示无子 1表示黑子 2表示白子 int allchess[][]=new int[19][19]; //标识该黑棋下还是白棋下 默认黑先 boolean isblack=true; //标识是否能下子 boolean canplay=true; //提示信息,该谁下 String message="黑先"; //设置的最大游戏时间 默认600秒 int maxtime=600; //黑方剩余时间 int blacktime=0; //白方剩余时间 int whitetime=0; //黑方剩余时间提示信息 String blackstring="无限制"; //黑方剩余时间提示信息 String whitestring="无限制"; //创建线程 Thread t=new Thread(this); public FiveChessFrame() { //窗口名字 this.setTitle("五子棋"); //大小 this.setSize(700,700); //关闭时退出 this.setDefaultCloseOperation(EXIT_ON_CLOSE); //限制窗口变大 this.setResizable(false); //窗体显示出来居中对齐 this.setLocationRelativeTo(null); //窗口显示出来 this.setVisible(true); //添加鼠标监听器 this.addMouseListener(this); //启动线程 t.start(); //挂起 t.suspend(); } public void paint(Graphics g) { //双缓冲器解决闪烁问题 BufferedImage bi=new BufferedImage(700,700,BufferedImage.TYPE_INT_ARGB); Graphics g2=bi.getGraphics(); //画背景图片 BufferedImage img=null; try { img=ImageIO.read(new File("C:\\Users\\86189\\Desktop\\记录图片\\bj1.jpg")); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } g2.drawImage(img, 0, 0, this); //提示信息 g2.setFont(new Font("黑体",Font.BOLD,20)); g2.setColor(Color.red); g2.drawString("提示:"+message, 50, 50); g2.setColor(Color.black); g2.drawString("黑:"+blackstring, 50,680); g2.drawString("白:"+whitestring, 450, 680); //画棋盘 g2.setColor(Color.black); for(int i=0;i<19;i++) { g2.drawLine(i*33+30, 70, i*33+30, 670); g2.drawLine(30, 70+i*33, 630, 70+i*33); } //画棋子 for(int i=0;i<19;i++) { for(int j=0;j<19;j++) { //画黑子 if(allchess[i][j]==1) { g2.setColor(Color.black); g2.fillOval((i*33-16)+30, (j*33-16)+70, 30, 30); } //画白子 if(allchess[i][j]==2) { g2.setColor(Color.white); g2.fillOval((i*33-16)+30, (j*33-16)+70, 30, 30); } } } g.drawImage(bi, 0, 0, this); } @Override public void mouseClicked(MouseEvent e) { // TODO Auto-generated method stub } @Override public void mousePressed(MouseEvent e) { // 得到坐标 x=e.getX(); y=e.getY(); //判断能否下子 if(canplay==true) { //判断是否在棋盘内 if(x>=30 && x<=630 && y>=70 && y<=670) { //将x,y点击的坐标变为最近的交叉点的棋盘坐标 if((x-30)%33<16) { x=(x-30)/33; }else { x=(x-30)/33+1; } if((y-70)%33<16) { y=(y-70)/33; }else { y=(y-70)/33+1; } //判断该谁下 //只有在无子的时候可以落子 if(allchess[x][y]==0) { if(isblack) { allchess[x][y]=1; //换子下 isblack=false; //改变提示信息 message="该白棋下"; }else { allchess[x][y]=2; isblack=true; message="该黑棋下"; } }else { JOptionPane.showMessageDialog(this, "此处已经下过棋子了,请重新下"); } //判断胜负 if(this.checkwin()==true) { JOptionPane.showMessageDialog(this, "游戏结束,"+ (allchess[x][y]==1?"黑棋":"白棋")+"获胜"); canplay=false; } //重写执行一遍paint()方法,画出棋子 this.repaint(); } } //开始游戏 if(e.getX()>644 && e.getX()<690 && e.getY()>125 && e.getY()<282){ int result=JOptionPane.showConfirmDialog(this, "是否重新开始游戏"); if(result==0) { JOptionPane.showMessageDialog(this, "重新开始"); //清空数组 allchess=new int[19][19]; //全部设为初始的状态 isblack=true; message="黑先"; canplay=true; maxtime=600; blacktime=maxtime; whitetime=maxtime; blackstring=maxtime/3600+":"+(maxtime/60-maxtime/3600*60)+":"+(maxtime-maxtime/60*60); whitestring=maxtime/3600+":"+(maxtime/60-maxtime/3600*60)+":"+(maxtime-maxtime/60*60); this.repaint(); t.resume(); } } //认输 if(e.getX()>644 && e.getX()<690 && e.getY()>467 && e.getY()<540) { int result=JOptionPane.showConfirmDialog(this, "是否认输"); if(result==0) { if(isblack) { JOptionPane.showMessageDialog(this, "黑方已认输,游戏结束"); }else { JOptionPane.showMessageDialog(this, "白方已认输,游戏结束"); } canplay=false; } } //设置 if(e.getX()>645 && e.getX()<690 && e.getY()>572 && e.getY()<655) { String input=JOptionPane.showInputDialog(this,"设置游戏实时间(分钟)"); //抛出输入的并非数字的异常,并提醒 try { maxtime=Integer.parseInt(input)*60; if(maxtime<=0) { JOptionPane.showMessageDialog(this, "设置的时间不允许小于等于0"); }else { int result=JOptionPane.showConfirmDialog(this, "设置成功,是否开始新游戏"); if(result==0) { JOptionPane.showMessageDialog(this, "重新开始"); //清空数组 allchess=new int[19][19]; //全部设为初始的状态 isblack=true; message="黑先"; canplay=true; blacktime=maxtime; whitetime=maxtime; blackstring=maxtime/3600+":"+(maxtime/60-maxtime/3600*60)+":"+(maxtime-maxtime/60*60); whitestring=maxtime/3600+":"+(maxtime/60-maxtime/3600*60)+":"+(maxtime-maxtime/60*60); this.repaint(); t.resume(); } } } catch (Exception e2) { JOptionPane.showMessageDialog(this, "请输入非零正整数"); } } } @Override public void mouseReleased(MouseEvent e) { // TODO Auto-generated method stub } @Override public void mouseEntered(MouseEvent e) { // TODO Auto-generated method stub } @Override public void mouseExited(MouseEvent e) { // TODO Auto-generated method stub } //判断胜负 public boolean checkwin() { boolean flag=false; int i=1; int color=allchess[x][y]; int count=1; //横向 while(x+i<19 && color==allchess[x+i][y]) { count++; i++; } i=1; while(x-i>=0 && color==allchess[x-i][y]) { count++; i++; } if(count>=5) { flag=true; } //纵向 int count2 = 1; int i2=1; while(y+i2<=18 && color==allchess[x][y+i2]) { count2++; i2++; } i2=1; while(y-i2>=0 && color==allchess[x][y-i2]) { count2++; i2++; } if(count2>=5) { flag=true; } //正斜 int count3 = 1; int i3=1; while(y-i3>=0 && x+i3<=18 && color==allchess[x+i3][y-i3]) { count3++; i3++; } i3=1; while(x-i3>=0 && y+i3<=18 && color==allchess[x-i3][y+i3]) { count3++; i3++; } if(count3>=5) { flag=true; } //反斜 int count4 = 1; int i4=1; while(x+i4<=18 && y+i4<=18 && color==allchess[x+i4][y+i4]) { count4++; i4++; } i4=1; while(x-i4>=0 && y-i4>=0 && color==allchess[x-i4][y-i4]) { count4++; i4++; } if(count4>=5) { flag=true; } return flag; } @Override public void run() { if(maxtime>0) { while(true) { if(isblack) { blacktime--; if(blacktime<=0) { JOptionPane.showMessageDialog(this, "黑方超时,白棋获胜!!!"); canplay=false; t.suspend(); } }else { whitetime--; if(whitetime<=0) { JOptionPane.showMessageDialog(this, "黑方超时,白棋获胜!!!"); canplay=false; t.suspend(); } } blackstring=blacktime/3600+":"+(blacktime/60-blacktime/3600*60)+":"+(blacktime-blacktime/60*60); whitestring=whitetime/3600+":"+(whitetime/60-whitetime/3600*60)+":"+(whitetime-whitetime/60*60); this.repaint(); try { Thread.sleep(1000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } } }
具体分析见博客:https://blog.csdn.net/qq_49639550/article/details/120321103