一 .项目简介
本项目主要设计了一款五子棋对战小游戏,主要实现的功能有人机对战,双人同机对战和双人联网对战,其中双人联网对战实现了类似于qq的聊天功能.
二 .工作重点
- 本项目主要运用swing绘图组件进行绘图,采用双缓冲技术使画面流畅.
- 运用多线程实现倒计时和QQ聊天功能,可以在下棋的过程中同时实现倒计时
- 采用五元组赋分法来实现人机对战的功能
- 采用面向对象的方法实现五子棋的功能,如人机对战棋盘和人人对战棋盘均继承自双人同机对战.
- 采用TCP网络通信协议实现人人功能的对战,确保了通信的稳定性和安全性
- 采用缓冲流传输图片实现打印功能,保证了游戏画面的稳定
三 .项目主要结构
五子棋UML类图
初始化棋子时序图
QQChat时序图
PVC时序图
四 .项目功能演示
游戏最初登录页面
游戏棋盘展示
人机功能对战演示
游戏胜利页面展示
创建双人房间 加入房间
双人游戏界面和聊天界面展示
双人聊天功能
五 .部分代码展示
初始登录界面
package FiveChess;import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
public class FirstPage {JFrame jFrame=new JFrame("五子棋");//设计主页面BufferedImage bufferedImage;{try {bufferedImage = ImageIO.read(new File("Resourse\\first.png"));//读取主页面的背景图} catch (IOException e) {e.printStackTrace();}}private class Canvas extends JPanel//自定义画布{@Overridepublic void paint(Graphics g) {g.drawImage(bufferedImage,0,0,600,410,null);}}Canvas canvas=new Canvas();public void init(){jFrame.addMouseListener(new MouseAdapter() {@Overridepublic void mouseClicked(MouseEvent e) {//获取鼠标点击事件int x=e.getX();int y=e.getY();if(x>=220&&x<=472&&y>=75&&y<=150)//判断点击的位置加载函数{jFrame.setVisible(false);new PVCMainBoard().init();}else if(x>=220&&x<=472&&y>150&&y<225){jFrame.setVisible(false);new MainChessBoard().init();}else if(y>=225&&y<=300&&x>=220&&x<=472){jFrame.setVisible(false);new LoadPage().init();}else if(y>=325&&y<=400&&x>=220&&x<=472){System.exit(0);}}});jFrame.add(canvas);canvas.repaint();jFrame.setPreferredSize(new Dimension(600,410));//设置大小jFrame.pack();jFrame.setResizable(false);jFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);jFrame.setVisible(true);}public static void main(String[] args) {new FirstPage().init();}}
棋盘主界面
package FiveChess;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Clip;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.UnsupportedAudioFileException;
import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.io.File;
import java.io.IOException;
import static javax.sound.sampled.AudioSystem.*;
public class MainChessBoard {Clip clip;{try {clip = getClip();//添加背景音乐clip.open(AudioSystem.getAudioInputStream(new File("Resourse\\123_02.wav")));} catch (LineUnavailableException e) {e.printStackTrace();} catch (UnsupportedAudioFileException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}}IsGameOver isGameOver=new IsGameOver();JFrame jFrame=new JFrame("五子棋");//绘制游戏的主页面ChessBoard chessBoard=new ChessBoard();JMenuBar jMenuBar=new JMenuBar();JMenuItem jMenuItem=new JMenuItem("悔棋");Coor[] coors=new Coor[235];int coorstack=-1;public MainChessBoard() {}public void init(){RetimeLimit();//开始倒计时init_Chess(chessBoard.chess);//初始化棋盘jMenuItem.addMouseListener(new MouseAdapter() {@Overridepublic void mouseClicked(MouseEvent e) {//System.out.println("hello");Withdraw();}});jMenuBar.add(jMenuItem);chessBoard.repaint();chessBoard.addMouseListener(new MyMouselistener());chessBoard.addMouseMotionListener(new MyouseMoveListener());jFrame.setPreferredSize(new Dimension(ChessBoard.BOARD_SIZE_X,ChessBoard.BOARD_SIZE_Y+30));clip.start();//开始播放音乐jFrame.add(chessBoard);jFrame.setJMenuBar(jMenuBar);jFrame.pack();jFrame.setResizable(false);jFrame.setVisible(true);jFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);}void init_Chess(Chess[][] chess){int i,j;for(i=0;i<15;i++){for(j=0;j<15;j++){chess[i][j]=new Chess();chess[i][j].setColor(0);//初始将所有棋子的颜色值为0coors[i*15+j]=new Coor(0,0);//初始悔棋栈}}}void Withdraw(){if(coorstack>0){int x=coors[coorstack].getX();int y=coors[coorstack].getY();chessBoard.chess[x][y].setColor(0);x=coors[coorstack-1].getX();y=coors[coorstack-1].getY();chessBoard.chess[x][y].setColor(0);coorstack=coorstack-2;chessBoard.repaint();}}public void RetimeLimit()//设置结束时间的倒计时{new Thread(()->{//多线程处理倒计时while (true){try {Thread.sleep(1000);//休息一秒chessBoard.limit_time--;chessBoard.repaint();//重新绘制页面if(chessBoard.limit_time<0){jFrame.setVisible(false);if(chessBoard.is_white)//判断是否胜利new gameOver("黑棋").init();elsenew gameOver("白棋").init();break;}} catch (InterruptedException e) {e.printStackTrace();}}}).start();}class MyouseMoveListener implements MouseMotionListener{@Overridepublic void mouseDragged(MouseEvent e) {}@Overridepublic void mouseMoved(MouseEvent e) {//获取移动鼠标的位置画蓝色框框int x=e.getX();int y=e.getY();int X=(x-ChessBoard.PLUS_X)/ChessBoard.CHESSBOARD_X;int Y=(y-ChessBoard.PLUS_Y)/ChessBoard.CHESSBOARD_Y;chessBoard.position_X=X;chessBoard.position_Y=Y;chessBoard.repaint();}}class MyMouselistener implements MouseListener{@Overridepublic void mouseClicked(MouseEvent e) {//获取鼠标点击位置int x=e.getX();int y=e.getY();int X=(x-ChessBoard.PLUS_X)/ChessBoard.CHESSBOARD_X;//转换为数组中的相对位置int Y=(y-ChessBoard.PLUS_Y)/ChessBoard.CHESSBOARD_Y;chessBoard.limit_time=30;if(chessBoard.chess[X][Y].getColor()==0){if(ChessBoard.is_white) {chessBoard.chess[X][Y].setColor(1);//更改颜色信息if (isGameOver.whowin(X, Y, chessBoard.chess, 1) == 1) {//判断游戏是否结束jFrame.setVisible(false);clip.stop();new gameOver("白棋").init();}ChessBoard.is_white = !ChessBoard.is_white;}else {chessBoard.chess[X][Y].setColor(2);ChessBoard.is_white = !ChessBoard.is_white;if(isGameOver.whowin(X,Y, chessBoard.chess, 2)==2){jFrame.setVisible(false);clip.stop();new gameOver("黑棋").init();}}coorstack=coorstack+1;coors[coorstack].setX(X);coors[coorstack].setY(Y);}chessBoard.repaint();}@Overridepublic void mousePressed(MouseEvent e) {}@Overridepublic void mouseReleased(MouseEvent e) {}@Overridepublic void mouseEntered(MouseEvent e) {}@Overridepublic void mouseExited(MouseEvent e) {}}public static void main(String[] args) {new MainChessBoard().init();}}
实现人机对战
package FiveChess;public class PVC {int [] scores;public PVC(){scores=new int[11];//初始化五元组scores[0]=7;//五元组为空scores[1]=35;//有一个子scores[2]=800;//有两个子scores[3]=15000;//有三个scores[4]=800000;//有四个scores[5]=0;//不存在scores[6]=0;//混杂scores[7]=15;//有一个其他子scores[8]=400;//有两个其他子scores[9]=1800;//三个scores[10]=100000;//四个}public int addScores(Chess[][] chess,int x,int y)//计算该点的分数之和{int sum=0;for(int i=x-4;i<=x;i++){//计算横向的五元组int num=0;//棋子数量//保存初始位置for(int j=i;j<=i+4;j++){//防止越界if(j<0||j+4>14){num=5;break;}if(chess[j][y].getColor()==2)num++;if(chess[j][y].getColor()==1){num=6;break;}}sum+=scores[num];}for(int i=y-4;i<=y;i++){//计算纵向的五元组int num=0;//棋子数量//保存初始位置for(int j=i;j<=i+4;j++){//防止越界if(j<0||j+4>14){num=5;break;}if(chess[x][j].getColor()==2)num++;if(chess[x][j].getColor()==1){num=6;break;}}sum+=scores[num];}for(int i=-4;i<=0;i++){//计算-x方向的分数;int num=0;for(int j=i;j<=i+4;j++){if(x+j<0||x+j>14||y+j<0||y+j>14){num=5;break;}if(chess[x+j][y+j].getColor()==2)num++;if(chess[x+j][y+j].getColor()==1){num=6;break;}}sum+=scores[num];}for(int i=-4;i<=0;i++){//计算x方向的分数;int num=0;for(int j=i;j<=i+4;j++){if(x-j<0||x-j>14||y+j<0||y+j>14){num=5;break;}if(chess[x-j][y+j].getColor()==2)num++;if(chess[x-j][y+j].getColor()==1){num=6;break;}}sum+=scores[num];}for(int i=x-4;i<=x;i++){//计算白子横向的五元组int num=0;//棋子数量//保存初始位置for(int j=i;j<=i+4;j++){//防止越界if(j<0||j+4>14){num=0;break;}if(chess[j][y].getColor()==1)num++;if(chess[j][y].getColor()==2){num=0;break;}}sum+=scores[num+6];}for(int i=y-4;i<=y;i++){//计算纵向的五元组int num=0;//棋子数量//保存初始位置for(int j=i;j<=i+4;j++){//防止越界if(j<0||j+4>14){num=0;break;}if(chess[x][j].getColor()==1)num++;if(chess[x][j].getColor()==2){num=0;break;}}sum+=scores[num+6];}for(int i=-4;i<=0;i++){//计算-x方向的分数;int num=0;for(int j=i;j<=i+4;j++){if(x+j<0||x+j>14||y+j<0||y+j>14){num=0;break;}if(chess[x+j][y+j].getColor()==1)num++;if(chess[x+j][y+j].getColor()==2){num=0;break;}}sum+=scores[num+6];}for(int i=-4;i<=0;i++){//计算x方向的分数;int num=0;for(int j=i;j<=i+4;j++){if(x-j<0||x-j>14||y+j<0||y+j>14){num=0;break;}if(chess[x-j][y+j].getColor()==1)num++;if(chess[x-j][y+j].getColor()==2){num=0;break;}}sum+=scores[num+6];}return sum;}public Coor getCoor(Chess[][]chess){//获取下一个点的坐标int x=0,y=0;Coor coor=new Coor(0,0);int max=0;for(x=0;x<15;x++){for(y=0;y<15;y++){if(chess[x][y].getColor()==0){if(addScores(chess,x,y)>max) {//选出分数最大的地方coor.setX(x);coor.setY(y);max = addScores(chess, x, y);}}}}return coor;}}
完整压缩版请移步MyFiveChess.rar-其他文档类资源-CSDN下载,0积分下载