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;
//为悔棋设置临时坐标
int tempx;
int tempy;
//数组保存棋子 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;
tempx=x;
}else {
x=(x-30)/33+1;
tempx=x;
}
if((y-70)%33<16) {
y=(y-70)/33;
tempy=y;
}else {
y=(y-70)/33+1;
tempy=y;
}
//判断该谁下
//只有在无子的时候可以落子
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, "黑方已认输,游戏结束");
t.suspend();
}else {
JOptionPane.showMessageDialog(this, "白方已认输,游戏结束");
t.suspend();
}
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, "请输入非零正整数");
}
}
//悔棋
if(e.getX()>645 && e.getX()<690 && e.getY()>335 && e.getY()<417) {
int result=JOptionPane.showConfirmDialog(this, "是否确认悔棋");
if(result==0) {
if(allchess[tempx][tempy]!=0) {
//保存原来的棋子的颜色
int color= allchess[tempx][tempy];
//将最后一个棋子设为0,即可悔棋
allchess[tempx][tempy]=0;
//继续该谁下
if(color==1) {
isblack=true;
message="该黑棋下";
}
if(color==2) {
isblack=false;
message="该白棋下";
}
}else {JOptionPane.showMessageDialog(this, "无法悔棋");}
}
this.repaint();
}
}
@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