五子棋
- 目录结构
1. Test.java
package com.fivechess;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Toolkit;
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;
import javax.swing.JPanel;
public class Test {
public static void main(String[] args) {
FiveChessFrame fi=new FiveChessFrame();
}
}
class FiveChessFrame extends JFrame implements MouseListener,Runnable{
// private static final Image bgImage = null;
int width = Toolkit.getDefaultToolkit().getScreenSize().width;//获取屏幕宽度
int height = Toolkit.getDefaultToolkit().getScreenSize().height;//获取屏幕高度
int x=0;// 鼠标点击的x坐标
int y=0;// 鼠标点击的y坐标
int[][] allChess = new int [19][19]; // 保存棋子的状态 0:无棋子 1:黑子 2:白子
//标识当前是黑棋还是白棋
boolean isBlack=true;
boolean canPlay = true;
String message="黑方先行";//保存要提示的信息;
boolean flag = false; //判断谁落子
/
class Position {
int listx;
int listy;
}
class chessUI extends JPanel {
public Position[] ps = new Position[300];
int i;
}
chessUI ui = new chessUI();
Position p = new Position();
//
int maxTime = 0;//保存最多拥有多少秒
Thread t = new Thread((Runnable) this);//做倒计时的线程类
保存黑方与白方的剩余时间
int blackTime=0;
int whiteTime=0;
String blackMessage="无限制";
String whiteMessage="无限制";
//第一步:窗体设置
public FiveChessFrame(){
this.setTitle("欢乐五子棋"); //标题
this.setSize(500, 530); //窗口大小
this.setResizable(false); //窗口是否可以改变大小=否
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//窗口关闭方式为关闭窗口同时结束程序
// System.out.println("宽度:"+width);//测试
// System.out.println("高度:"+height);//测试
this.setLocation((width - 500) / 2, (height - 500) / 2); //设置窗口默认位置以屏幕居中
this.addMouseListener((MouseListener) this);
this.setVisible(true); //窗口是否显示
//做倒计时的线程类
t.start();
t.suspend(); //将线程挂起
this.repaint();
}
///初始化
public void init() {
现在重新开始游戏
/*
* 1.清空棋盘,即将allChess全部数据归零
* 2.将游戏信息:的显示改回到开始位置
* 3.将下一步下棋的人改为黑方;
*/
for(int i=0;i<19;i++) {
for(int j=0;j<19;j++) {
allChess[i][j]=0;
}
}
message ="黑方先行";
isBlack=true;
blackTime=maxTime;
whiteTime=maxTime;
if(maxTime>0) {
blackMessage = maxTime/3600+ ":" + (maxTime/60-maxTime/3600*60) + ":" + (maxTime-maxTime/60*60);
whiteMessage = maxTime/3600+ ":" + (maxTime/60-maxTime/3600*60) + ":" + (maxTime-maxTime/60*60);
t.resume();
}else {
blackMessage="无限制";
whiteMessage="无限制";
t.suspend();
}
}
/第二步:实现接口///
//鼠标抬起
public void mouseClicked(MouseEvent e) {
}
//鼠标按下
public void mousePressed(MouseEvent e) {
第六步:是否开始游戏 ///
if(canPlay == true) {
x=e.getX();
y=e.getY();
ui.ps[ui.i]=p;//保存坐标
if(x>=11&&x<=371&&y>=81&&y<=440) {
x = Math.round((x-11)/20f);
y= Math.round((y-80)/20f);
if(allChess[x][y]== 0) {
if(isBlack==true) {
allChess[x][y]=1;
isBlack =false;
message="轮到白方";//seven第七步:游戏信息;
}else {
allChess[x][y]=2;
isBlack =true;
message="轮到黑方";//seven第七步:游戏信息;
}
ui.ps[ui.i].listx = x;
ui.ps[ui.i].listy = y;
ui.i++;
this.repaint();
第五步:判断这个棋子是否和其他棋子连成五个,判断是否结束;
boolean winFlag = this.checkWin();
if(winFlag == true) {
t.suspend();
JOptionPane.showMessageDialog(this,"游戏结束!!!"+(allChess[x][y] == 1 ? "黑方" : "白方" )+"获胜!!!");
canPlay=false;
}
}else{
JOptionPane.showMessageDialog(this,"当前已有棋子,请重新落子");
}
// this.repaint();
}
}
/************************************实现按钮功能***********************************************/
///第八步:右边:点击开始游戏按钮!!!!!!!!!!
if(e.getX()>=395&&e.getX()<=467&&e.getY()>=83&&e.getY()<=115) {
int result = JOptionPane.showConfirmDialog(this,"是否重新开始游戏");
if(result == 0) {
this.init();
this.repaint();
canPlay = true;/点击开始游戏可以再开一盘!!!
}
}
///第九步:右边:点击游戏设置按钮!!!!!!!!!!
if(e.getX()>=395&&e.getX()<=467&&e.getY()>=135&&e.getY()<=162) {
// JOptionPane.showMessageDialog(this,"游戏设置");
String input =JOptionPane.showInputDialog("游戏设置:请输入游戏的最大时间(单位:分钟),如果输入0,则表示没有时间设置:");
try {
maxTime = Integer.parseInt(input) * 60;
if(maxTime < 0) {
JOptionPane.showMessageDialog(this,"请输入正确信息,不允许输入负数!😒");
}
if(maxTime == 0) {
int result = JOptionPane.showConfirmDialog(this,"设置成功,是否重新开始游戏!😒");
if(result == 0) {
for(int i=0;i<19;i++) {
for(int j=0;j<19;j++) {
allChess[i][j]=0;
}
}
message ="黑方先行";
isBlack=true;
blackTime=maxTime;
whiteTime=maxTime;
blackMessage="无限制";
whiteMessage="无限制";
this.repaint();
}
}
if(maxTime > 0) {
// JOptionPane.showMessageDialog(this,"请输入正确信息,不允许输入负数!😒");
int result = JOptionPane.showConfirmDialog(this,"设置成功,是否重新开始游戏!😒");
if(result == 0) {
for(int i=0;i<19;i++) {
for(int j=0;j<19;j++) {
allChess[i][j]=0;
}
}
message ="黑方先行";
isBlack=true;
blackTime=maxTime;
whiteTime=maxTime;
blackMessage = maxTime/3600+ ":" + (maxTime/60-maxTime/3600*60) + ":" + (maxTime-maxTime/60*60);
whiteMessage = maxTime/3600+ ":" + (maxTime/60-maxTime/3600*60) + ":" + (maxTime-maxTime/60*60);
t.resume();
this.repaint();
}
}
} catch (NumberFormatException e1) {
// TODO: handle exception
JOptionPane.showMessageDialog(this,"请正确输入信息!😒");
}
}
///第十步:右边:点击游戏说明按钮!!!!!!!!!!
if(e.getX()>=395&&e.getX()<=467&&e.getY()>=183&&e.getY()<=213) {
JOptionPane.showMessageDialog(this,"游戏说明:这是一个五子棋游戏程序,黑白双方轮流下棋,当某一方连到五子时,游戏结束。😉");
}
///第十一步:右边:点击悔棋按钮!!!!!!!!!!
if(e.getX()>=395&&e.getX()<=467&&e.getY()>=233&&e.getY()<=264) {
this.remorseful();
}
///第十二步:右边:点击认输设置按钮!!!!!!!!!!
if(e.getX()>=395&&e.getX()<=467&&e.getY()>=280&&e.getY()<=310) {
int result = JOptionPane.showConfirmDialog(this,"是否确认认输?🤷♂️");
if(result == 0) {
if(isBlack) {
JOptionPane.showMessageDialog(this,"黑方已经认输,游戏结束!!!");
}else {
JOptionPane.showMessageDialog(this,"白方已经认输,游戏结束!!!");
}
canPlay=false;
}
}
///第十三步:右边:点击关于设置按钮!!!!!!!!!!
if(e.getX()>=395&&e.getX()<=467&&e.getY()>=333&&e.getY()<=363) {
JOptionPane.showMessageDialog(this,"关于:本游戏《时光的继承者》制作,有相关问题可以联系QQ582362349😃");
}
///第十四步:右边:点击退出设置按钮!!!!!!!!!!
if(e.getX()>=395&&e.getX()<=467&&e.getY()>=382&&e.getY()<=411) {
JOptionPane.showMessageDialog(this,"退出😜");
System.exit(0);
}
}
//鼠标抬起
public void mouseReleased(MouseEvent e) {
}
//鼠标进入
public void mouseEntered(MouseEvent e) {
}
//鼠标离开
public void mouseExited(MouseEvent e) {
}
///第三步:插入背景图片
public void paint(Graphics g) {
// //双缓冲技术防止屏幕闪烁
// BufferedImage bi = new BufferedImage(500, 550, BufferedImage.TYPE_INT_ARGB);
// Graphics g2 = bi.createGraphics();
//获取图片路径
BufferedImage image = null;
try {
image = ImageIO.read(new File("wuziqi.png"));
} catch (IOException e) {
e.printStackTrace();
}
g.drawImage(image, 0, 30, this);//显示图片
1.添加文字,绘制标题;
g.setFont(new Font("微软雅黑", Font.BOLD, 25));
g.setColor(Color.white);
g.drawString("游戏信息:"+message, 80, 65);
2.输出时间信息
g.setFont(new Font("宋体", Font.BOLD, 20));
g.setColor(Color.black);
g.drawString("黑方时间:"+blackMessage, 45, 480);
g.drawString("白方时间:"+whiteMessage, 260, 480);
/2.绘制棋盘
for(int i=0; i<19; i++) {
// 画横线
g.drawLine(11, 81+20*i, 371, 81+20*i);
// 画竖线
g.drawLine(11+20*i, 81, 11+20*i, 440);
}
/3.标注点位;
g.fillOval(68, 138, 6, 6);
g.fillOval(188, 138, 6, 6);
g.fillOval(308, 138, 6, 6);
g.fillOval(68, 258, 6, 6);
g.fillOval(68, 378, 6, 6);
g.fillOval(68, 498, 6, 6);
g.fillOval(188, 258, 6, 6);
g.fillOval(308, 258, 6, 6);
g.fillOval(68, 378, 6, 6);
g.fillOval(188, 378, 6, 6);
g.fillOval(308, 378, 6, 6);
//第四步:鼠标按下时,在棋盘绘制棋子,并且落在交叉处;
for(int i=0;i<19;i++) {
for(int j=0;j<19;j++) {
if(allChess[i][j] == 1) {
int tempX=i*20+11;
int tempY=j*20+81;
g.setColor(Color.BLACK);
g.fillOval(tempX-8, tempY-8, 16, 16);
}
if(allChess[i][j] == 2) {
int tempX=i*20+11;
int tempY=j*20+82;
g.setColor(Color.white);
g.fillOval(tempX-8, tempY-8, 16, 16);
}
}
}
}//这是paint的
///第四步:判断这个棋子是否和其他棋子连成五个,判断是否结束;
public boolean checkWin(){
flag =false;
int count = 1; //报存共有多少相同棋子
//判断这个棋子在横向是否和其他棋子连成五个,特点是y相同;
int color = allChess[x][y];///判断黑白
// if(color == allChess[x+1][y]) {
// count++;
// if(color == allChess[x+2][y]) {
//
// }
//
// }
/横向向右
int i=1;
while(color == allChess[x+i][y]&&x+i>=0&&x+i<=18&&y>=0&&y<=18) {
count++;
i++;
}
/横向向左
i=1;
while(color == allChess[x-i][y]&&x-i>=0&&x-i<=18&&y>=0&&y<=18) {
count++;
i++;
}
if(count>=5) {
flag = true;
}
///向上
int i2=1;
int count2=1;
while(color == allChess[x][y+i2]&&x>=0&&x<=18&&y+i2>=0&&y+i2<=18) {
count2++;
i2++;
}
/向下
i2=1;
while(color == allChess[x][y-i2]&&x>=0&&x<=18&&y-i2>=0&&y-i2<=18) {
count2++;
i2++;
}
if(count2>=5) {
flag = true;
}
/右上,左下;
int i3=1;
int count3=1;
while(color == allChess[x+i3][y-i3]&&x+i3>=0&&x+i3<=18&&y-i3>=0&&y-i3<=18) {
count3++;
i3++;
}
i3=1;
while(color == allChess[x-i3][y+i3]&&x-i3>=0&&x-i3<=18&&y+i3>=0&&y+i3<=18) {
count3++;
i3++;
}
if(count3>=5) {
flag = true;
}
///左上,右下
int i4=1;
int count4=1;
while(color == allChess[x-i4][y-i4]&&x-i4>=0&&x-i4<=18&&y-i4>=0&&y-i4<=18) {
count4++;
i4++;
}
i4=1;
while(color == allChess[x+i4][y+i4]&&x+i4>=0&&x+i4<=18&&y+i4>=0&&y+i4<=18) {
count4++;
i4++;
}
if(count4>=5) {
flag = true;
}
return flag;
}// checkWin()的
/************************************实现多线程接口***********************************************/
public void run() {
/*
* 判断是否有时间限制
*/
if(maxTime > 0) {
while(true) {
if(isBlack) {
blackTime--;
if(blackTime==0) {
JOptionPane.showMessageDialog(this,"黑方超时,游戏结束!😆😅");
}
}else {
whiteTime--;
if(whiteTime==0) {
JOptionPane.showMessageDialog(this,"白方超时,游戏结束!😆😅");
}
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO: handle exception
e.printStackTrace();
}
blackMessage = blackTime/3600+ ":" + (blackTime/60-blackTime/3600*60) + ":" + (blackTime-blackTime/60*60);
whiteMessage = whiteTime/3600+ ":" + (whiteTime/60-whiteTime/3600*60) + ":" + (whiteTime-whiteTime/60*60);
this.repaint();
System.out.println(blackTime+"---"+whiteTime);
}
}
}
///第十一步:右边:点击悔棋按钮!!!!!!!!!!
public void remorseful() {
if (canPlay) {
//遍历棋盘上是否有棋子
int z = 0;
for (int i = 0; i < 15; i++) {
for (int j = 0; j < 15; j++) {
if (allChess[i][j] != 0) {
z++;
}
}
}
//判断是否有棋子
if (z != 0) {
int result = JOptionPane.showConfirmDialog(this, "确认要悔棋吗?");
if (result == 0) {
int x = ui.ps[ui.i - 1].listx;
int y = ui.ps[ui.i - 1].listy;
if (allChess[x][y] == 0){
JOptionPane.showMessageDialog(this, "已悔过一次棋了!");
}else{
if (isBlack==true) {
allChess[x][y] = 1;
isBlack=false;
message = "轮到白方";
} else if (isBlack==false){
allChess[x][y] =2;
isBlack=true;
message = "轮到黑方";
}
allChess[x][y] = 0;
ui.i--;
this.repaint();
}
}
} else {
JOptionPane.showMessageDialog(this, "棋盘上已无棋子");
}
} else {
JOptionPane.showMessageDialog(this, "请先开始游戏");
}
}
}
2. WzqGame.java
package flyweight;
import java.awt.*;
import java.awt.event.*;
import java.util.ArrayList;
import javax.swing.*;
public class WzqGame {
public static void main(String[] args) {
new Chessboard();
}
}
class Chessboard extends MouseAdapter{
WeiqiFactory wf;
JFrame f;
Graphics g;
JRadioButton wz;
JRadioButton bz;
private final int x=50;
private final int y=50;
private final int w=40; //小方格宽度与高度
private final int rw=400;//棋盘高度与宽度
Chessboard(){
wf=new WeiqiFactory();
f=new JFrame("享元模式在五子棋中的应用");
f.setBounds(100, 100, 500, 550);
f.setVisible(true);
f.setResizable(false);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel SouthJP=new JPanel();
f.add("South",SouthJP);
wz=new JRadioButton("白子");
bz=new JRadioButton("黑子",true);
ButtonGroup group=new ButtonGroup();
group.add(wz);
group.add(bz);
SouthJP.add(wz);
SouthJP.add(bz);
JPanel CenterJP=new JPanel();
CenterJP.setLayout(null);
CenterJP.setSize(500,500);
CenterJP.addMouseListener(this);
f.add("Center",CenterJP);
try {
Thread.sleep(500);
}catch (InterruptedException e) {
// TODO: handle exception
e.printStackTrace();
}
g=CenterJP.getGraphics();
g.setColor(Color.BLUE);
g.drawRect(x, y, rw, rw);
for(int i=1;i<10;i++) {
g.drawLine(x+(i*w), y, x+(i*w), y+rw);
g.drawLine(x, y+(i*w), x+rw, y+(i*w));
}
}
public void mouseClicked(MouseEvent e) {
Point pt=new Point(e.getX()-15,e.getY()-15);
if(wz.isSelected()) {
ChessPieces c1=wf.getChessPieces("w");
c1.DownPieces(g,pt);
}else if(bz.isSelected()) {
ChessPieces c2=wf.getChessPieces("b");
c2.DownPieces(g,pt);
}
}
}
//抽象享元角色:棋子
interface ChessPieces{
public void DownPieces(Graphics g,Point pt);//落子
}
//具体享元角色:白子
class WhitePieces implements ChessPieces{
public void DownPieces(Graphics g, Point pt) {
g.setColor(Color.WHITE);
g.fillOval(pt.x, pt.y, 30, 30);
}
}
//具体享元角色:黑子
class BlackPieces implements ChessPieces{
public void DownPieces(Graphics g, Point pt) {
g.setColor(Color.BLACK);
g.fillOval(pt.x, pt.y, 30, 30);
}
}
//享元工厂
class WeiqiFactory{
private ArrayList<ChessPieces> qz;
public WeiqiFactory() {
qz=new ArrayList<ChessPieces>();
ChessPieces w=new WhitePieces();
qz.add(w);
ChessPieces b=new BlackPieces();
qz.add(b);
}
public ChessPieces getChessPieces(String type) {
if(type.equalsIgnoreCase("w")) {
return (ChessPieces)qz.get(0);
}else if(type.equalsIgnoreCase("b")) {
return (ChessPieces)qz.get(1);
}else {
return null;
}
}
}
3. 图片资源
总结
运行Test.java即可