五子棋人机对战java,java五子棋网络对战

  五子棋人机对战java,java五子棋网络对战

  做完java单机五子棋,开始尝试写网络五子棋(在局域网,因为没有公开IP)。上次五子棋写的很乱,都是一个班写的。这一次,我使用了面向对象的思想,将特定的函数和属性编写到一个类中。代码分为两部分,客户端和服务器端。客户端用AWT编写,主要由五子棋面板和功能键面板组成。网络使用TCP,通过序列化和反序列化来读写消息。运行时,先运行服务器程序,再运行两个客户端。代码放在文章的末尾。

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

  下面是代码包的结构:

  然后我再依次说说这几个类的作用。

  Media包

  媒体包:主要包括五子棋的背景图片、播放音乐的类别以及音乐内容。

  我是跟室友上的音乐演奏课,所以不太懂。我扫了一眼,是用Applet做的,只能用处理音乐。wav后缀。

  Net包

  Net:它包含两个类。细心的朋友要注意,客户端没有main方法。客户端实际上包含了与服务器通信的套接字,其中包含了一些读写方法。我在服务器端使用线程池的方法来处理客户端的请求(我对线程池不是很了解,类似于多线程)。

  View包

  套装:包含四个类,即棋盘,棋盘,棋子和谁查看。

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

  ChessPanel是一个棋盘面板,完成绘制19*19棋盘线、加载背景图片、不断接收和处理来自服务器的消息(给面板添加棋子)、给面板添加棋子和每次点击后给服务器发送棋子、判断胜负并给出提示消息等任务。

  棋子是棋子,包含颜色、棋子半径、棋子位置、命令等属性(与前面的命令面板配合使用,默认为发送)。

  谁是五子棋中判断谁胜谁负的那一部分。每一步都需要判断。

  播放音乐的类:

  包装媒体。音乐;导入Java . io . file;导入Java . io . io exception;导入javax . sound . sampled . audio inputstream;导入javax . sound . sampled . audio system;导入javax . sound . sampled . clip;导入javax . sound . sampled . lineunavailableexception;import javax . sound . sampled . unsupportdaudiofileexception;公开课PlayMusic { private Clip clippublic PlayMusic(String filePath)抛出LineUnavailableException,UnsupportedAudioFileException,io exception { File File=new File(File path);audio inputstream audio inputstream=audio system . getaudioinputstream(file);clip=audio system . get clip();clip . open(audio inputstream);} public void play(){ clip . setframeposition(1);clip . start();} public void loop(){ Clip . loop(Clip。循环_连续);} public void stop(){ clip . stop();}}TcpClient:

  包网;导入视图。件;导入Java . io . *;导入Java . net . socket;公共类TcpClient { private Socket socket私有ObjectInputStream ois私有ObjectOutputStream oospublic TcpClient(Socket socket,ObjectInputStream ois,ObjectOutputStream OOS){ this . Socket=Socket;this.ois=ois这

  .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:

 

  

/** 1.变量值不变的问题* 2.输入输出流先后顺序的问题(socket阻塞)* 3.socket 短连接不关闭输入输出流,为何看起来就像长连接一样(长短连接的区别是什么)* */// 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,"Its 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) {                    

	  
	  
	  
	  
	  
	  
        

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

留言与评论(共有 条评论)
   
验证码: