文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

java如何实现联机五子棋

2023-06-30 12:20

关注

这篇文章主要介绍“java如何实现联机五子棋”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“java如何实现联机五子棋”文章能帮助大家解决问题。

下面是客户端运行的效果:

java如何实现联机五子棋

这里是代码包的结构:

java如何实现联机五子棋

接着我来依次说下这些类所完成的功能

Media包

Media包:主要是放了五子棋的背景图片和播放音乐的类以及音乐内容

播放音乐这个类是我从室友那拿的,所以我也不是很懂,瞄了一眼是用Applet完成的,只能处理.wav后缀的音乐

Net包

Net包:包含两个类,细心的小伙伴应该注意到客户端是没有主方法的。客户端中其实是包含与服务端进行通信的socket的,其中包含一些读和写的方法。服务端我采用的是线程池的方法来处理客户端的请求(线程池这部分我也不是特别了解,用起来和多线程感觉差不多)。

View包

View包:包含四个类,分别是ChessBoard,ChessPanel,Pieces和WhoWin 类

ChessBoard是一个包含Main方法的JFrame,命令面板和棋盘面板都是添加到这个JFrame中的。

ChessPanel是一个棋盘面板,里面完成了如:画19*19的棋盘线条,加载背景图片,不停的接收来自服务端的消息并处理(把棋子加到面板),处理每次点击后添加棋子到面板并发送棋子到服务器,判断胜负并且给出提示消息。

Pieces是一个棋子,其中有包含如颜色,棋子半径,棋子位置和命令(和前面的命令面板配合使用,默认是发送)等属性。

WhoWin就是五子棋中判断谁输谁赢的部分。每下一步就需要判断。

播放音乐的类:

package Media.Music;import java.io.File;import java.io.IOException;import javax.sound.sampled.AudioInputStream;import javax.sound.sampled.AudioSystem;import javax.sound.sampled.Clip;import javax.sound.sampled.LineUnavailableException;import javax.sound.sampled.UnsupportedAudioFileException;public class PlayMusic {    private Clip clip;    public PlayMusic(String filePath) throws LineUnavailableException, UnsupportedAudioFileException, IOException {        File file = new File(filePath);        AudioInputStream audioInputStream = AudioSystem.getAudioInputStream(file);        clip = AudioSystem.getClip();        clip.open(audioInputStream);    }     public void play() {        clip.setFramePosition(1);        clip.start();    }     public void loop() {        clip.loop(Clip.LOOP_CONTINUOUSLY);    }    public void stop() {        clip.stop();    }}

TcpClient:

package net;import view.Pieces;import java.io.*;import java.net.Socket;public class TcpClient{    private Socket socket;    private ObjectInputStream ois;    private ObjectOutputStream oos;    public TcpClient(Socket socket,ObjectInputStream ois,ObjectOutputStream oos){        this.socket= socket;        this.ois = ois;        this.oos = oos;    }    public Socket getSocket() {        return socket;    }     public void setSocket(Socket socket) {        this.socket = socket;    }     public ObjectInputStream getOis() {        return ois;    }     public void setOis(ObjectInputStream ois) {        this.ois = ois;    }     public ObjectOutputStream getOos() {        return oos;    }     public void setOos(ObjectOutputStream oos) {        this.oos = oos;    }     public void send(Pieces pieces) throws IOException {        oos.writeObject(pieces);        System.out.println(socket+"向服务器发送消息");    }    public Pieces accept() throws IOException, ClassNotFoundException {        Pieces pieces = (Pieces) ois.readObject();        System.out.println(socket+"从服务器读取消息");        return pieces;    }    public void close(){        ;    }}

TcpServer:

package net;import view.Pieces;import java.io.*;import java.net.ServerSocket;import java.net.Socket;import java.net.SocketException;import java.util.ArrayList;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;public class TcpServer {    public static void main(String[] args) {        // 保存客户端处理的线程        ArrayList<UserThread> userList = new ArrayList<>();        // 固定大小的线程池只支持两个线程,用来处理客户端        ExecutorService es = Executors.newFixedThreadPool(2);        try {            ServerSocket server = new ServerSocket(10086);            System.out.println("服务器已经启动,正在等待客户端连接......");            while (true) {                //接收客户端的Socket,如果没有客户端连接就一直卡在这里                Socket socket = server.accept();                // 每来一个用户就创建一个线程                UserThread user = new UserThread(socket, userList);                // 开启线程                es.execute(user);            }        } catch (IOException e) {            e.printStackTrace();        }    }} class UserThread implements Runnable {    private Socket socket = null;    private static ArrayList<UserThread> list; // 客户端线程集合    private ObjectOutputStream oos;    private ObjectInputStream ois;    private boolean flag = true;// 标记     public UserThread(Socket socket, ArrayList<UserThread> list) {        this.socket = socket;        this.list = list;        list.add(this); // 把当前线程加入list中    }     @Override    public void run() {        UserThread user = null;        try {            System.out.println("客户端:" + socket.getInetAddress().getHostAddress() + "已经连接");            ois = new ObjectInputStream(socket.getInputStream());            oos = new ObjectOutputStream(socket.getOutputStream());            while(true){                Pieces pieces = (Pieces) ois.readObject(); // 客户端发给服务端的消息,把他写到其它套接字中去                int size = list.size();                for (int i = 0; i < size; i++) {                    user = list.get(i);                    if (user.socket != socket) {                        user.oos.writeObject(pieces);                        System.out.println("从"+socket+"向"+user.socket+"发送消息");                    }                }            }        } catch(SocketException e){ //  todo 客户端掉线后,移除客户端。没想好{1.从客户端列表移除当前元素,关闭当前:socket,通知另一方:这一方已经掉线,然后关闭这一方的socket}            try {                int i = list.size();                if (i ==2){                    list.remove(user);                    System.out.println("已经删除了一个客户端");                    list.get(0).oos.writeObject(new Pieces("对方掉线"));                }else if (i==1){                    list.remove(0);                    System.out.println("又移除了另一个客户端");                }            } catch (IOException ex) {                ex.printStackTrace();            }        } catch (IOException e) {            e.printStackTrace();        } catch (ClassNotFoundException e) {            e.printStackTrace();        }    }}

ChessBoard:

// todo 一个提示框package view;import Media.Music.PlayMusic;import javax.sound.sampled.LineUnavailableException;import javax.sound.sampled.UnsupportedAudioFileException;import javax.swing.*;import java.awt.*;import java.awt.event.ActionEvent;import java.awt.event.ActionListener;import java.io.IOException;public class ChessBoard extends JFrame implements ActionListener {    private JButton PlayMusic = new JButton("播放音乐");    private ChessPanel chessPanel;    private Panel CommandPanel = new Panel();    private JButton reStart = new JButton("重新开始");    private JButton fail = new JButton("认输");    private JButton Regret = new JButton("悔棋");    private String command=null; // 触发按钮后发送的命令    private PlayMusic music = null;    private int count = 1;    //  todo 静态语句块    {        try {            music = new PlayMusic("./src/Media/Music/bg3.wav");        } catch (LineUnavailableException e) {            e.printStackTrace();        } catch (UnsupportedAudioFileException e) {            e.printStackTrace();        } catch (IOException e) {            e.printStackTrace();        }    }     public ChessBoard() {        this.setTitle("欢乐五子棋");        chessPanel = new ChessPanel();        this.add(chessPanel,BorderLayout.CENTER);        reStart.addActionListener(this);        fail .addActionListener(this);        Regret.addActionListener(this);        PlayMusic.addActionListener(this);        CommandPanel.add(reStart);        CommandPanel.add(fail);        CommandPanel.add(Regret);        CommandPanel.add(PlayMusic);        this.add(CommandPanel,BorderLayout.SOUTH);        this.setBounds(10, 10, 800, 800);        this.setVisible(true);        this.setResizable(false);        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);    }    public static void main(String[] args) {        ChessBoard Board = new ChessBoard();     }    @Override    public void actionPerformed(ActionEvent e) {        if(e.getSource()==reStart){            command ="重新开始";            chessPanel.canPlay = true;        }else if(e.getSource()==fail){            command ="认输";            JOptionPane.showMessageDialog(chessPanel,"It's a pity,you have fail the game!");            chessPanel.canPlay = false;        }else if (e.getSource()==Regret){            command ="悔棋";        }else if (e.getSource()==PlayMusic){            // todo 播放音乐,单数次播放;            if (count%2==1){                music.play();            }else {                music.stop();            }            count++;            command = null;        }        if(command!=null){            Pieces pieces = new Pieces(command);            try {                this.chessPanel.client.send(pieces);            } catch (IOException ex) {                ex.printStackTrace();            }        }     }}

ChessPanel:

package view;// 五子棋面板,就是在这里面画图。// todo 背景图片 ,也许一个背景音乐import net.TcpClient;import javax.swing.*;import java.awt.*;import java.awt.event.MouseEvent;import java.awt.event.MouseListener;import java.io.IOException;import java.io.ObjectInputStream;import java.io.ObjectOutputStream;import java.net.ConnectException;import java.net.Socket;import java.util.ArrayList;import java.util.Iterator;public class ChessPanel extends JPanel implements MouseListener{    // TODO 从服务器接收来的棋子 ,值不变有问题//   Pieces accept_pieces = new Pieces();//   Pieces send_pieces = new Pieces();    whoWin ifWin =new whoWin() ; // 是否胜利    TcpClient client = null; // 客户端    boolean canPlay = true; // 是否能继续玩    boolean isBlack = true; // 是否黑子,黑1,白2    ArrayList<Pieces> allPieces = new ArrayList<>(); // 存储棋子对象,就是通过这个画图的    int [][] allChess = new int[19][19];    int PanelWidth;    int PanelHeight;    int width = 600;    int height = 600;    int temp = width / 18;    int xbase,ybase;    Image image = Toolkit.getDefaultToolkit().getImage("./src/Media/bg.jpeg"); // "./"表示当前项目下    public ChessPanel(){        this.addMouseListener(this);        try {            Socket socket = new Socket("172.27.29.190", 10086);            //TODO 构建输出输入流,输入输出流问题,先输出后输入            ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());            ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());            client = new TcpClient(socket,ois,oos);            new Thread(new getMessage()).start(); // 开启读取的线程        } catch (ConnectException e){            System.out.println("服务器拒绝连接!");        } catch (IOException e) {            e.printStackTrace();        }catch(Exception e ){            e.printStackTrace();        }    }    // 画图部分    public void paintComponent(Graphics g) {        super.paintComponent(g);        PanelWidth = this.getSize().width; // 这两步骤        PanelHeight = this.getSize().height;        xbase = (PanelWidth - width) / 2;        ybase = (PanelHeight - height) / 2;        Graphics2D g2d = (Graphics2D) g;//        this.setBackground(new Color(246, 186, 114));        g2d.drawImage(image,0,0,this.getWidth(),this.getHeight(),this);        int x1, y1, x2, y2;        // 画线        for (int i = 0; i < 19; i++) {            if (i == 0 || i == 18) {                g2d.setStroke(new BasicStroke(3.0f));            } else g2d.setStroke(new BasicStroke(1.0f));            x1 = xbase + temp * i;            y1 = ybase;            y2 = ybase + 18 * temp;            g2d.drawLine(x1, y1, x1, y2);            x1 = xbase;            y1 = ybase + temp * i;            x2 = xbase + temp * 18;            g2d.drawLine(x1, y1, x2, y1);        }        // 开始画棋子        int radius ;        int xPos,yPos;        Iterator it = allPieces.iterator(); // 迭代器遍历arraylist        while(it.hasNext()){            Pieces pieces = (Pieces) it.next();            radius  = pieces.getRadius();            xPos = pieces.getxPos();            yPos = pieces.getyPos();            System.out.println(pieces.getColor()+","+pieces.getxPos()+","+pieces.getyPos());            if (pieces.getColor() == 1){                g2d.setColor(Color.black);                g2d.fillOval(xPos*temp+xbase-radius/2,yPos*temp+ybase-radius/2,radius,radius);            }            else if (pieces.getColor() == 2) {                g2d.setColor(Color.white);                g2d.fillOval(xPos * temp + xbase - radius / 2, yPos * temp + ybase - radius / 2, radius, radius);            }        }     }     @Override    public void mousePressed(MouseEvent e) {        int x ,y ;        if (canPlay) {            x = e.getX();            y = e.getY();            //  判断鼠标点击位置            if (x >= xbase & x <= (xbase + 18 * temp) & y >= ybase & y < (ybase + 18 * temp)) {                // 判断是不是下在空的位置                int tempX = (x - xbase) / temp, tempY = (y - ybase) / temp;                // todo 这里是关键判断这点坐标的数组下标是什么                if ((x - xbase) % temp > temp / 2) {                    x = tempX + 1;                } else                    x = tempX;                if ((y - ybase) % temp > temp / 2)                    y = tempY + 1;                else                    y = tempY;                // 先判断有没有棋子,处理没有棋子的情况                if (allChess[x][y] != 0) {                       JOptionPane.showMessageDialog(this, "这里有棋子了");                } else {                    Pieces send_pieces = new Pieces();                    send_pieces.setxPos(x);                    send_pieces.setyPos(y);                    if (isBlack){                        send_pieces.setColor(1);                        allChess[x][y] = 1;                        isBlack = false;                    }                    else{                        send_pieces.setColor(2);                        allChess[x][y]=2;                        isBlack = true;                    }                    allPieces.add(send_pieces); // 向棋子队列加入当前棋子                    canPlay = false;// canPlay在true情况下, 点击一次后不能点击了                    this.repaint();                    ifWin = new whoWin(allChess,x,y);                    // 如果赢了,就不能玩了,并且给出提示消息,你赢了;                    if(ifWin.isWin()){                        canPlay = false;                        JOptionPane.showMessageDialog(this,"Congratulations you have won tha game !");                    }                    try {                        if (client!=null){                            client.send(send_pieces);                        }                    } catch (IOException ex) {                        ex.printStackTrace();                    }                }            }         }    }     // 读取来自服务器端的信息    class getMessage implements Runnable{        private boolean flag = true;        public void setFlag(boolean flag) {            this.flag = flag;        }         @Override        public void run() {            // 循环读            while(flag){                if(client!=null){                    try {                        Pieces accept_pieces = client.accept();                        String command = accept_pieces.getCommand();                        int color = accept_pieces.getColor();                        switch (command){                            case "发送":{                                canPlay = true;                                if (color == 1){                                    isBlack = false;//对方为黑我为白                                }else{                                    isBlack = true;                                }                                allPieces.add(accept_pieces);                                allChess[accept_pieces.getxPos()][accept_pieces.getyPos()]= accept_pieces.getColor();                                ChessPanel.this.repaint();                                ifWin.setY(accept_pieces.getyPos());                                ifWin.setX(accept_pieces.getxPos());                                ifWin.setAllChess(allChess);                                if(ifWin.isWin()){                                    canPlay = false;                                    JOptionPane.showMessageDialog(ChessPanel.this,"It's a pity you have fail the game!");                                }                                break;                            }                            case "悔棋":{                                int i = JOptionPane.showConfirmDialog(ChessPanel.this,"对方请求悔棋,是否同意!");                                // yes 0,no 1,cancel 2,closed -1                                Pieces pieces = new Pieces();                                if (i == 0){                                    // 同意悔棋:1.同意对方悔棋                                    pieces.setCommand("同意悔棋");                                    // arraylist 去除末尾的两个值,对应allChess置0                                    int size = allPieces.size();                                    for (int j = 1;j<=2;j++){                                        allChess[allPieces.get(size-j).getxPos()][allPieces.get(size-j).getyPos()]=0;                                        allPieces.remove(size-j);                                    }                                    ChessPanel.this.repaint();                                }else if(i==1){                                    pieces.setCommand("不同意悔棋");                                }                                client.send(pieces);                                break;                            }                            case "认输":{ // 不能继续玩下去,你已经胜利                                JOptionPane.showMessageDialog(ChessPanel.this,"对方认输");                                canPlay = false;                                JOptionPane.showMessageDialog(ChessPanel.this,"Congratulations you have won tha game !");                                break;                            }                            case "重新开始":{ // 是否同意重新开始                               int i = JOptionPane.showConfirmDialog(ChessPanel.this,"对方请求重新开始,是否同意");                                Pieces pieces = new Pieces();                                if(i == 0){// allChess 和 allPieces全部置0;                                    pieces.setCommand("同意重新开始");                                    int size = allPieces.size();                                    System.out.println("arraylist 长度:"+size);                                    for (int j = 0;j<size;j++){// 移除队首元素                                        allChess[allPieces.get(0).getxPos()][allPieces.get(0).getyPos()] = 0;                                        allPieces.remove(0);                                    }                                    canPlay = true;                                    ChessPanel.this.repaint();                                }else if (i ==1){                                    pieces.setCommand("不同意重新开始");                                }                                client.send(pieces);                                break;                            }                            case "同意悔棋":{// allpieces 和 allchess 回退                                JOptionPane.showMessageDialog(ChessPanel.this,"对方同意悔棋");                                int size = allPieces.size();                                for (int j = 1;j<=2;j++){                                    allChess[allPieces.get(size-j).getxPos()][allPieces.get(size-j).getyPos()]=0;                                    allPieces.remove(size-j);                                }                                ChessPanel.this.repaint();                                break;                            }                            case "不同意悔棋":{                                JOptionPane.showMessageDialog(ChessPanel.this,"对方不同意悔棋");                                break;                            }                             case "同意重新开始":{ // 全部置0,调用repaint 方法                                JOptionPane.showMessageDialog(ChessPanel.this,"对方同意重新开始");                                int size = allPieces.size();                                for (int j = 0;j<size;j++){ //  todo 移除队首元素arraylist 长度改变;序列也发生改变                                    allChess[allPieces.get(0).getxPos()][allPieces.get(0).getyPos()] = 0;                                    allPieces.remove(0);                                }                                canPlay = true;                                ChessPanel.this.repaint();                                break;                            }                            case "不同意重新开始":{                                JOptionPane.showMessageDialog(ChessPanel.this,"对方不同意重新开始");                                break;                            }                            case "对方掉线":{ // 对方已经掉线                                JOptionPane.showMessageDialog(ChessPanel.this,"不好意思,对方已经掉线!");                                canPlay = false;                                break;                            }                        }                    } catch (IOException e) {                        e.printStackTrace();                    } catch (ClassNotFoundException e) {                        e.printStackTrace();                    }                }            }        }    }     @Override    public void mouseClicked(MouseEvent e) {     }    @Override    public void mouseReleased(MouseEvent e) {     }     @Override    public void mouseEntered(MouseEvent e) {     }     @Override    public void mouseExited(MouseEvent e) {     } }

Pieces:

package view; import java.io.Serializable;// 存储棋子的相关信息public class Pieces implements Serializable {    private int radius = 16;    private int color = 0;    private int xPos ;    private int yPos;    private String command = "发送";    public String getCommand() {        return command;    }     public void setCommand(String command) {        this.command = command;    }     public Pieces(int color, int xPos, int yPos){        this.color = color;        this.xPos = xPos;        this.yPos = yPos;    }    public Pieces(){     }    public Pieces(String command){        this.command = command;    }    public int getRadius() {        return radius;    }     public void setRadius(int radius) {        this.radius = radius;    }     public int getColor() {        return color;    }     public void setColor(int color) {        this.color = color;    }     public int getxPos() {        return xPos;    }     public void setxPos(int xPos) {        this.xPos = xPos;    }     public int getyPos() {        return yPos;    }     public void setyPos(int yPos) {        this.yPos = yPos;    }}

WhoWin:

package view;public class whoWin { // 判断是谁赢了    private int allChess[][] = new int[19][19];    private int x = 0;    private int y = 0;    public whoWin(){     }    public whoWin(int allChess[][],int x,int y){        this.allChess = allChess;        this.x = x;        this.y = y;    }     public void setAllChess(int allChess[][]){        this.allChess = allChess;    }    public void setX(int x){        this.x = x;    }    public void setY(int y ){        this.y = y;    }    public boolean isWin() {        int color = allChess[x][y];        int count;        count = this.Count(1, 0, color); // 对横方向的判断        if (count >= 5) {            return true;        } else {            count = this.Count(0, 1, color); // 对竖方向的判断            if (count >= 5) {                return true;            } else {                count = this.Count(1, 1, color); // 对左上方向的判断                if (count >= 5)                    return true;                else {                    count = this.Count(1, -1, color); // 对右上方向的判断                    if (count >= 5)                        return true;                }            }        }        return false;    }    private int Count(int xChange, int yChange, int color) {        int count = 1;        int tempX = xChange, tempY = yChange;        while (color == allChess[x + xChange][y + yChange]) {            count++;            if (xChange != 0) {                xChange++;            }            if (yChange != 0) {                if (yChange > 0)                    yChange++;                else                    yChange--;            }        }        xChange = tempX;        yChange = tempY;        while (color == allChess[x - xChange][y - yChange]) {            count++;            if (xChange != 0)                xChange++;            if (yChange != 0) {                if (yChange > 0)                    yChange++;                else                    yChange--;            }        }        return count;    }}

关于“java如何实现联机五子棋”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识,可以关注编程网行业资讯频道,小编每天都会为大家更新不同的知识点。

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯