java课程设计

java课程设计
简介
利用socket实现了网络通信,模拟了一个低配版的qq游戏大厅。
具体地说,实现的功能有
上线下线
群发消息
私聊消息
五子棋对战
效果图片


图片.png

文件结构


图片.png

核心代码如下
1 客户端部分
CharClient.java
package com.nsd.charClient;

import java.awt.BorderLayout;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.TextArea;
import java.awt.TextField;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;

import javax.imageio.ImageIO;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;

import net.sf.json.JSONObject;

public class CharClient extends JFrame {
    private Socket socket = null;

    private JButton btSend = new JButton("Send");
    private JButton btPrivateSend = new JButton("PrivateSend");
    private JButton btLogOut = new JButton("LogOut");
    private JButton btShowAllUsers = new JButton("ShowAllUsers(execptSelf)");
    private TextArea txtMessageShow = new TextArea(30, 26);

    private TextField txtMessage = new TextField(40);
    private TextField txtPrivateTarget = new TextField(40);
    private TextField txtPrivateMessage = new TextField(40);

    private JButton btSolo = new JButton("Solo");
    private TextField opponentID = new TextField(40);

    public final int maxSize = 10 + 5;
    public final int n = 10;
    public int chessBoard[][];

    private boolean inSolo = false;
    private boolean canMove = false;

    public class MyPanel extends JPanel implements MouseListener {
        Image image = null;
        Image image1 = null;
        Image image2 = null;

        public MyPanel() {
            AddListener();
        }

        private void AddListener() {
            this.setFocusable(true);
            this.addMouseListener(this);
        }

        public void paint(Graphics g) {
            super.paint(g);
            try {
                image = ImageIO.read(new File(
                        "D:\\信息竞赛\\cpp\\vijoslong\\java\\charClient\\src\\com\\nsd\\charClient\\chessBoard.jpg"));
                image1 = ImageIO.read(
                        new File("D:\\信息竞赛\\cpp\\vijoslong\\java\\charClient\\src\\com\\nsd\\charClient\\black.jpg"));
                image2 = ImageIO.read(
                        new File("D:\\信息竞赛\\cpp\\vijoslong\\java\\charClient\\src\\com\\nsd\\charClient\\white.jpg"));
                g.drawImage(image, 0, 0, null);
                for (int i = 1; i <= n; i++) {
                    for (int j = 1; j <= n; j++) {
                        if (chessBoard[i][j] == 0)
                            continue;
                        int x = 30 + (i - 1) * 44;
                        int y = 30 + (j - 1) * 44;
                        if (chessBoard[i][j] == 1) {
                            g.drawImage(image1, x, y, null);
                        }
                        if (chessBoard[i][j] == 2) {
                            g.drawImage(image2, x, y, null);
                        }
                    }
                }
            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }

        @Override
        public void mouseClicked(MouseEvent e) {
            // TODO Auto-generated method stub

            if (canMove == false) {
//              if(inSolo == true) txtMessageShow.setText(txtMessageShow.getText() + "\n" + "【尚未轮到你落子】");
                return;
            }
            int x = e.getX();
            int y = e.getY();
            SendMoveMessage(x, y);
        }

        @Override
        public void mousePressed(MouseEvent e) {
            // TODO Auto-generated method stub

        }

        @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 static void main(String[] args) {
        // TODO Auto-generated method stub
        new CharClient();

    }

    public CharClient() {

        chessBoard = new int[maxSize][maxSize];
        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= n; j++) {
                chessBoard[i][j] = 0;
            }
        }

        // init 设置框架,设置容器,增加监听,增加菜单,增加业务处理,增加线程
        /*
         * setFrame(); setPanel();
         */
        setSize(730, 750);
        setTitle("QQ聊天室");
        setLocationRelativeTo(null);

        // 框架分为上下二个部分,
        this.setLayout(new BorderLayout(8, 8));
        this.add(txtMessageShow, BorderLayout.WEST);
        this.add(setButtonPanel(), BorderLayout.NORTH);
        this.add(setSoloPanel(), BorderLayout.CENTER);
        this.add(setButtonPanel2(), BorderLayout.SOUTH);
        //
        btSend.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent arg0) {
                // TODO Auto-generated method stub
                SendMessage();
            }
        });
        btPrivateSend.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent arg0) {
                // TODO Auto-generated method stub
                SendPrivateMessage();
            }
        });
        btLogOut.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                // TODO Auto-generated method stub
                LogOut();
            }

        });
        btShowAllUsers.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                // TODO Auto-generated method stub
                ShowAllUsers();
            }

        });

        btSolo.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                // TODO Auto-generated method stub
                if (inSolo == false)
                    Solo();
            }

        });

        // addMenu();

        addSocket();
        setVisible(true);

    }

    private void Solo() {
        String opponent = opponentID.getText().trim();
        try {
            // 获取客户端和服务器相连的socket,选择输出端口,转为字符输入流
            PrintWriter out = new PrintWriter(socket.getOutputStream());
            // 依照协议,设置json数据
            JSONObject jo = new JSONObject();
            jo.put("state", "solo");
            jo.put("targetID", opponent);
//          System.out.println(jo.toString()); // {"state":"private","targetID":"WWW"}
            // 发送到服务器端 println
            out.println(jo.toString());
            out.flush();
            inSolo = true;
            canMove = true;
            // out.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private void SendPrivateMessage() {
        String target = txtPrivateTarget.getText().trim();
        String message = txtPrivateMessage.getText().trim();
        try {
            // 获取客户端和服务器相连的socket,选择输出端口,转为字符输入流
            PrintWriter out = new PrintWriter(socket.getOutputStream());
            // 依照协议,设置json数据
            JSONObject jo = new JSONObject();
            jo.put("state", "private");
            jo.put("targetID", target);
            jo.put("Note", message);
//          System.out.println(jo.toString()); // {"state":"private","targetID":","Note":"wwwwww"}
            // 发送到服务器端 println
            out.println(jo.toString());
            out.flush();
            // out.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private void SendMessage() {
        String message = txtMessage.getText().trim();
        try {
            // 获取客户端和服务器相连的socket,选择输出端口,转为字符输入流
            PrintWriter out = new PrintWriter(socket.getOutputStream());
            // 依照协议,设置json数据
            JSONObject jo = new JSONObject();
            jo.put("state", "public");
            jo.put("Note", message);
//          System.out.println(jo.toString()); // {"state":"public","Note":"wwwwww"}
            // 发送到服务器端 println
            out.println(jo.toString());
            out.flush();
            // out.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private void LogOut() {
        // TODO Auto-generated method stub
        String message = txtMessage.getText().trim();
        try {
            // 获取客户端和服务器相连的socket,选择输出端口,转为字符输入流
            PrintWriter out = new PrintWriter(socket.getOutputStream());
            // 依照协议,设置json数据
            JSONObject jo = new JSONObject();
            jo.put("state", "leave");
            jo.put("Note", message);
//          System.out.println(jo.toString()); // {"state":"leave","Note":"wwwwww"}
            // 发送到服务器端 println
            out.println(jo.toString());
            out.flush();
            System.exit(0);
            // out.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private void ShowAllUsers() {
        // TODO Auto-generated method stub
        String message = txtMessage.getText().trim();
        try {
            // 获取客户端和服务器相连的socket,选择输出端口,转为字符输入流
            PrintWriter out = new PrintWriter(socket.getOutputStream());
            // 依照协议,设置json数据
            JSONObject jo = new JSONObject();
            jo.put("state", "show");
            jo.put("Note", message);
//          System.out.println(jo.toString()); // {"state":"show","Note":"wwwwww"}
            // 发送到服务器端 println
            out.println(jo.toString());
            out.flush();
            // out.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private void SendMoveMessage(int x, int y) {
        // 棋盘左上角第一个格子(32,32)
        // 格子间距40
//      System.out.println(""+x+" "+y);
        int X = (y - 30) / 44 + 1; // 换算到棋盘坐标 xy颠倒
        int Y = (x - 30) / 44 + 1;

        try {
            // 获取客户端和服务器相连的socket,选择输出端口,转为字符输入流
            PrintWriter out = new PrintWriter(socket.getOutputStream());
            // 依照协议,设置json数据
            JSONObject jo = new JSONObject();
            jo.put("state", "move");
            jo.put("x", X + "");
            jo.put("y", Y + "");
//          System.out.println(jo.toString()); // {"state":"public","x":"ww","y":"ww"}
            // 发送到服务器端 println
            out.println(jo.toString());
            out.flush();
            // out.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private void addSocket() {
        try {
            socket = new Socket("localhost", 30088);
//          System.out.println(socket);
            // Socket[addr=localhost/127.0.0.1,port=30088,localport=64332]

            this.setTitle("[" + socket.getLocalPort() + "]");
            //
            // 创建线程,用于客户端循环等待接受服务器的数据
            new Thread(new ClientRunnable(socket)).start();
            // st.getInputStream()
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private JPanel setButtonPanel() {
        JPanel jp = new JPanel(new BorderLayout(4, 4));
        // 群发
        JPanel jp1 = new JPanel(new BorderLayout(4, 4));
        jp1.add(new JLabel("Message"), BorderLayout.WEST);
        jp1.add(txtMessage, BorderLayout.CENTER);
        jp1.add(btSend, BorderLayout.EAST);
        jp.add(jp1, BorderLayout.NORTH);

//      JPanel jp2 = new JPanel(new BorderLayout(4, 4));
        jp.add(new JLabel("id"), BorderLayout.WEST);
        jp.add(txtPrivateTarget, BorderLayout.EAST);
        JPanel jp3 = new JPanel(new BorderLayout(4, 4));
        jp3.add(new JLabel("Message"), BorderLayout.WEST);
        jp3.add(txtPrivateMessage, BorderLayout.CENTER);
        jp3.add(btPrivateSend, BorderLayout.EAST);
//      jp3.add(jp2, BorderLayout.NORTH);
        jp.add(jp3, BorderLayout.SOUTH);

        return jp;
    }

    private JPanel setButtonPanel2() {
        JPanel jp = new JPanel(new BorderLayout(4, 4));
        jp.add(btShowAllUsers, BorderLayout.NORTH);
        jp.add(new JLabel("opponentID"), BorderLayout.WEST);
        jp.add(opponentID, BorderLayout.CENTER);
        jp.add(btSolo, BorderLayout.EAST);
        jp.add(btLogOut, BorderLayout.SOUTH);
        return jp;
    }

    private MyPanel setSoloPanel() { // 创建棋盘画布 在棋盘画布上的点击会向服务器发送move信息
        MyPanel jp = new MyPanel();

        return jp;
    }

    class ClientRunnable implements Runnable {
        private BufferedReader br = null;

        public ClientRunnable(Socket socket) throws IOException {
            // 从socket获取输入流,再强转为BufferedReader流
            // this.br = br;
            br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
        }

        @Override
        public void run() {
            // TODO Auto-generated method stub
            try {
                while (true) {
                    // 缓冲字符流,readLine
                    String str = br.readLine();
                    // str的解析。
                    int res = analyseStr(str);
                    if (res == 0)
                        txtMessageShow.setText(txtMessageShow.getText() + "\n" + str);
                    // RunStep();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    private int analyseStr(String s) {
        if (s == null)
            return 1;
        if (s.charAt(0) == '%') {
            inSolo = false; // 比赛结束
            for (int i = 1; i <= n; i++) {
                for (int j = 1; j <= n; j++) {
                    chessBoard[i][j] = 0;
                }
            }
            repaint();
            return 1;
        }
        if (s.charAt(0) == '&') {
//          System.out.println("s'len is "+s.length());
            for (int i = 1; i <= n; i++) {
                for (int j = 1; j <= n; j++) {
                    chessBoard[j][i] = s.charAt((i - 1) * n + j - 1 + 1) - '0'; // 横纵坐标需要颠倒
                    // 最后的 +1 是因为要考虑&
                }
            }
            if (canMove == false)
                canMove = true; // 交换移动权
            else
                canMove = false;
            repaint();
            return 1;
        }
        return 0;
    }
}

GomokuBoard.java

package com.nsd.charServer;

public class GomokuBoard {
    public final int maxSize = 10 + 5;
    public final int n = 10;
    public int p1, p2;
    public int moveFlag, drawFlag, winFlag;
    public int chessBoard[][];

    GomokuBoard(int _p1, int _p2) {
        p1 = _p1;
        p2 = _p2;
        moveFlag = 1;
        drawFlag = 0;
        winFlag = 0;
        chessBoard = new int[maxSize][maxSize];
        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= n; j++) {
                chessBoard[i][j] = 0;
            }
        }
    }

    public void show() {
        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= n; j++) {
                System.out.print(chessBoard[i][j]);
            }
            System.out.println();
        }
    }

    public int checkEnd() {
        int drawFlag = 1, winFlag = 0; // 平局 或者 当前moveFlag者获胜
        for (int i = 1; i <= n; i++) {
            if (drawFlag == 0)
                break;
            for (int j = 1; j <= n; j++) {
                if (chessBoard[i][j] == 0) { // 有空位 不算平局
                    drawFlag = 0;
                    break;
                }
            }
        }
        for (int i = 1; i <= n; i++) {
            if (winFlag == 1)
                break;
            for (int j = 1; j <= n; j++) { // 枚举中心点(i,j)
                if (chessBoard[i][j] != moveFlag)
                    continue;
                // 竖
                if (i >= 3 && i <= n - 2) {
                    if (chessBoard[i - 1][j] == moveFlag && chessBoard[i - 2][j] == moveFlag
                            && chessBoard[i + 1][j] == moveFlag && chessBoard[i + 2][j] == moveFlag) {
                        winFlag = 1;
                        break;
                    }
                }
                // 横
                if (j >= 3 && j <= n - 2) {
                    if (chessBoard[i][j - 1] == moveFlag && chessBoard[i][j - 2] == moveFlag
                            && chessBoard[i][j + 1] == moveFlag && chessBoard[i][j + 2] == moveFlag) {
                        winFlag = 1;
                        break;
                    }
                }
                // 斜
                if (i >= 3 && i <= n - 2 && j >= 3 && j <= n - 2) {
                    if (chessBoard[i - 1][j - 1] == moveFlag && chessBoard[i - 2][j - 2] == moveFlag
                            && chessBoard[i + 1][j + 1] == moveFlag && chessBoard[i + 2][j + 2] == moveFlag) {
                        winFlag = 1;
                        break;
                    }
                    if (chessBoard[i + 1][j - 1] == moveFlag && chessBoard[i + 2][j - 2] == moveFlag
                            && chessBoard[i - 1][j + 1] == moveFlag && chessBoard[i - 2][j + 2] == moveFlag) {
                        winFlag = 1;
                        break;
                    }
                }
            }
        }
        if (drawFlag == 1 || winFlag == 1)
            return 1;
        return 0;
    }
}

2 服务器代码
CharServer.java

package com.nsd.charServer;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.swing.JOptionPane;

import net.sf.json.JSONObject;

import com.google.gson.JsonObject;

public class CharServer {
    private List<Socket> lstSocket = new ArrayList<>();
    private List<GomokuBoard> lstSoloTables = new ArrayList<>();

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        new CharServer();
    }

    // alt+/
    public CharServer() {
        // init
        try {
            // 创建一个30088端口的服务器
            // 终止服务器进程方法:cmd中输入netstat -p tcp -ano | findstr :30088
            // 找到对应的pid(最后一列数),使用任务管理器结束任务
            ServerSocket ss = new ServerSocket(30088);

            // 创建线程,用于不断循环等待客户端上线,
            new Thread(new SocketAcceptThread(ss)).start();

        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    class SocketAcceptThread implements Runnable {
        private ServerSocket serverSocket = null;

        public SocketAcceptThread() {
            // TODO Auto-generated constructor stub
        }

        public SocketAcceptThread(ServerSocket ss) {
            this.serverSocket = ss;

        }

        @Override
        public void run() {
            // TODO Auto-generated method stub
            while (true) {
                try {
                    // accept是阻塞的过程,有客户上线,才能往下执行。
                    Socket st = serverSocket.accept();
                    // 将和客户端连接的Socket对象st保存。
                    lstSocket.add(st);

                    // 服务器端将这个用户信息获取,用该用户的端口号作为信息。
                    String strPort = "" + st.getPort();
                    System.out.println("Server: " + strPort);
                    System.out.println("Server: " + st);
                    // 服务器端将这个用户发布在群里,告知大家,该用户上线。
                    // SendAllUser(str, "up");
                    SendWelcomeUser(strPort);

                    // 当前的 Socket对象 需要接受对应这个对象客户端的数据,不断的接受数据
                    new ServerClientThread(st).start();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }
    }

    class ServerClientThread extends Thread {
        // 缓冲输入字符流
        private BufferedReader br = null;
        private Socket socket = null;
        private boolean exit = false;

        public ServerClientThread(Socket st) throws IOException {
            // TODO Auto-generated constructor stub
            socket = st;
            InputStream is = st.getInputStream();
            // 缓冲输入字符流 <= InputStream
            br = new BufferedReader(new InputStreamReader(is));
        }

        @Override
        public void run() {
            // TODO Auto-generated method stub
            try {
                while (!exit) {
                    // io , readline 阻塞状态,缓冲输入字符流
                    String str = br.readLine();
                    // 对str进行解析, {"state":"public","Note":"wwwwww"}
                    DoClient(str, socket.getPort());
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    private void DoClient(String str, int port) throws IOException {
        // 对客户端的str数据进行解析
        JSONObject jo = JSONObject.fromObject(str);
        String state = jo.get("state").toString();
        switch (state) {
        case "public":
            // 群发的消息
            for (int i = 0; i < lstSocket.size(); i++) {
                Socket st = lstSocket.get(i);
                OutputStream os = st.getOutputStream();
                PrintWriter out = new PrintWriter(os);
                // 状态,数据
                // 服务器端发送到客户端的数据,仅是一个字符串。下行消息
                out.println("【" + port + "】" + jo.get("Note").toString());
                out.flush();
            }
            break;
        case "private":
            // 私发的消息
            int flag = -1;
            int sender = -1;
            String targetID = jo.get("targetID").toString();
            int targetIDInt = Integer.parseInt(targetID);
            for (int i = 0; i < lstSocket.size(); i++) {
                Socket st = lstSocket.get(i);
                if (st.getPort() == port)
                    sender = i;
//              System.out.println("st.getPort():"+st.getPort());
//              System.out.println("targetID:"+targetID);
//              if(st.getPort() + "" != targetID) continue;
                if (targetIDInt != st.getPort())
                    continue;
//              System.out.println("success");
                flag = i;
                OutputStream os = st.getOutputStream();
                PrintWriter out = new PrintWriter(os);
                // 状态,数据
                // 服务器端发送到客户端的数据,仅是一个字符串。下行消息
                out.println("【" + port + "】私聊你的消息:" + jo.get("Note").toString());
                out.flush();
            }
            if (flag == -1) {
                Socket st = lstSocket.get(sender);
                OutputStream os = st.getOutputStream();
                PrintWriter out = new PrintWriter(os);
                out.println("【" + targetID + "】不存在或已下线");
                out.flush();
            }
            break;
        case "leave":
            // 下线消息
            for (int i = 0; i < lstSocket.size(); i++) {
                Socket st = lstSocket.get(i);
                OutputStream os = st.getOutputStream();
                PrintWriter out = new PrintWriter(os);
                // 状态,数据
                /*
                 * JSONObject jo = new JSONObject(); jo.put("state", state); jo.put("Name",
                 * str); out.println(jo.toString());
                 */
                out.println("【" + port + "】用户已离线");
                out.flush();
            }
            // 从socket列表中清除用户
            for (int i = 0; i < lstSocket.size(); i++) {
                Socket st = lstSocket.get(i);
                if (st.getPort() == port) {
                    lstSocket.remove(i);
                    break;
                }
            }
            break;
        case "show":
            // 显示所有在线用户
            int sender1 = -1;
            for (int i = 0; i < lstSocket.size(); i++) {
                Socket st = lstSocket.get(i);
                if (st.getPort() == port) {
                    sender1 = i;
                    break;
                }
            }
            Socket st = lstSocket.get(sender1);
            OutputStream os = st.getOutputStream();
            PrintWriter out = new PrintWriter(os);
            out.println("【" + "current users list" + "】");
            for (int j = 0; j < lstSocket.size(); j++) {
                if (sender1 == j)
                    continue;
                Socket st2 = lstSocket.get(j);
                out.println("【" + st2.getPort() + "】");
            }
            out.flush();
            break;
        case "solo":
            // 棋类比赛
            int flag1 = -1;
            int sender11 = -1;
            String targetID1 = jo.get("targetID").toString();
            int targetIDInt1 = Integer.parseInt(targetID1);
            for (int i = 0; i < lstSocket.size(); i++) {
                Socket st1 = lstSocket.get(i);
                if (st1.getPort() == port) {
                    sender11 = i;
                    break;
                }
            }
            Socket st1 = lstSocket.get(sender11);
            for (int i = 0; i < lstSocket.size(); i++) {
                if (i == sender11)
                    continue; // 不允许和自身solo
                Socket st2 = lstSocket.get(i);
//              System.out.println("st.getPort():"+st.getPort());
//              System.out.println("targetID:"+targetID);
//              if(st.getPort() + "" != targetID) continue;
                if (targetIDInt1 != st2.getPort())
                    continue;

                flag1 = i;
                int x = st1.getPort(), y = st2.getPort();
                OutputStream os1 = st1.getOutputStream();
                PrintWriter out1 = new PrintWriter(os1);
                OutputStream os2 = st2.getOutputStream();
                PrintWriter out2 = new PrintWriter(os2);
                boolean isInSolo = false;
                for (int j = 0; j < lstSoloTables.size(); j++) {
                    GomokuBoard temp = lstSoloTables.get(j);
                    if (x == temp.p1 || x == temp.p2) {
                        out1.println("【你已处于对局中,不可开始新的对局】");
                        out1.flush();
                        isInSolo = true;
                        break;
                    }
                    if (y == temp.p1 || y == temp.p2) {
                        out1.println("【对手已处于对局中,不可开始新的对局】");
                        out1.flush();
                        isInSolo = true;
                        break;
                    }

                }
                if (isInSolo == false) {
                    createSoloTables(st1.getPort(), st2.getPort());
                    // 服务器端发送到客户端的数据
                    out1.println("即将开始你和【" + targetID1 + "】的solo");
                    out1.flush();

                    out2.println("【" + port + "】发起了对你的solo");
                    out2.flush();
                }

                break;
            }
            if (flag1 == -1) {
//              Socket st1 = lstSocket.get(sender11);
                OutputStream os1 = st1.getOutputStream();
                PrintWriter out1 = new PrintWriter(os1);
                out1.println("【" + targetID1 + "】不存在或已下线");
                out1.flush();
            }
            break;
        case "move":
            // 下棋动作
            // x y为处理后的棋盘坐标
            // p1 p2为游戏双方端口号(其中p1为这一步下棋的人)
            String x = jo.get("x").toString();
            String y = jo.get("y").toString();
            int X = Integer.parseInt(x);
            int Y = Integer.parseInt(y); // 坐标
            int P1 = port; // P1为当前落子者 数值为端口号
            int P2 = -1;
            for (int i = 0; i < lstSoloTables.size(); i++) {
                GomokuBoard gb = lstSoloTables.get(i);
                if (gb.p1 == P1) {
                    P2 = gb.p2;
                    break;
                }
                if (gb.p2 == P1) {
                    P2 = gb.p1;
                    break;
                }
            }
            int s1 = -1, s2 = -1;
            for (int i = 0; i < lstSocket.size(); i++) {
                Socket temp = lstSocket.get(i);
                if (temp.getPort() == P1) {
                    s1 = i;
                }
                if (temp.getPort() == P2) {
                    s2 = i;
                }
            }
//          System.out.println(""+s1+" "+s2);
            if (s1 == -1 || s2 == -1)
                break; // 有人不在棋局之中

            Socket St1 = lstSocket.get(s1);
            Socket St2 = lstSocket.get(s2);
            OutputStream Os1 = St1.getOutputStream();
            PrintWriter Out1 = new PrintWriter(Os1);
            OutputStream Os2 = St2.getOutputStream();
            PrintWriter Out2 = new PrintWriter(Os2);

            for (int i = 0; i < lstSoloTables.size(); i++) {
                GomokuBoard gb = lstSoloTables.get(i);
                if ((gb.p1 == P1 && gb.p2 == P2) || (gb.p1 == P2 && gb.p2 == P1)) {
                    if (gb.chessBoard[X][Y] != 0) {
                        Out1.println("【落子位置已有棋子】");
                        Out1.flush();
                        break;
                    }
                    gb.chessBoard[X][Y] = gb.moveFlag;

                    Out1.print("&");
                    for (int i1 = 1; i1 <= gb.n; i1++) {
                        for (int j = 1; j <= gb.n; j++) {
                            Out1.print(gb.chessBoard[i1][j]);
                        }
//                      Out1.println();
                    }
                    Out1.println("&");
                    Out1.flush();
//                  Out1.close();
                    Out2.print("&");
                    for (int i1 = 1; i1 <= gb.n; i1++) {
                        for (int j = 1; j <= gb.n; j++) {
                            Out2.print(gb.chessBoard[i1][j]);
                        }
//                      Out2.println();
                    }
                    Out2.println("&"); // 这边输出要换行 因为客户端的读取是readline
                    Out2.flush();
//                  gb.show();
                    if (gb.checkEnd() == 1) {
                        if (gb.moveFlag == 1 || gb.moveFlag == 2) {
                            if (gb.drawFlag == 1) {
                                Out1.println("【平局】");
                                Out2.println("【平局】");
                                Out1.flush();
                                Out2.flush();
                            }
                            if (gb.drawFlag == 0) {
                                Out1.println("【你胜利了】");
                                Out2.println("【你失败了】");
                                Out1.flush();
                                Out2.flush();
                            }
                        }
                        try {
                            Thread.sleep(5000); // 游戏结束时停止5s
                        } catch (InterruptedException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        }
                        endSolo(i, s1, s2);
                    }
                    gb.moveFlag = 3 - gb.moveFlag; // 交换
                    break;
                }
            }
            break;
        }
        System.out.println("Server data : " + str);
    }

    private void createSoloTables(int x, int y) { // 创建lstSocket中两个socket的临时对战
        // TODO Auto-generated method stub
        GomokuBoard gb = new GomokuBoard(x, y);
        lstSoloTables.add(gb);
    }

    private void endSolo(int x, int s1, int s2) { // 删除lstSoloTables中的第x个棋盘,并结束对战窗口
        lstSoloTables.remove(x);
        // 加入在客户端结束对战窗口的代码
        Socket St1 = lstSocket.get(s1);
        Socket St2 = lstSocket.get(s2);
        OutputStream Os1 = null;
        try {
            Os1 = St1.getOutputStream();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        PrintWriter Out1 = new PrintWriter(Os1);
        OutputStream Os2 = null;
        try {
            Os2 = St2.getOutputStream();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        PrintWriter Out2 = new PrintWriter(Os2);
        Out1.println("%"); // %表示结束
        Out1.flush();
        Out2.println("%");
        Out2.flush();
    }

    private void SendWelcomeUser(String strPort) throws IOException {
        // 新客户上线,群发欢迎的消息
        for (int i = 0; i < lstSocket.size(); i++) {
            Socket st = lstSocket.get(i);
            OutputStream os = st.getOutputStream();
            PrintWriter out = new PrintWriter(os);
            // 状态,数据
            out.println("欢迎【" + strPort + "】用户上线");
            out.flush();
        }
    }
}
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 151,511评论 1 330
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 64,495评论 1 273
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 101,595评论 0 225
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 42,558评论 0 190
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 50,715评论 3 270
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 39,672评论 1 192
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,112评论 2 291
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 29,837评论 0 181
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 33,417评论 0 228
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 29,928评论 2 232
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,316评论 1 242
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 27,773评论 2 234
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,253评论 3 220
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 25,827评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,440评论 0 180
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 34,523评论 2 249
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 34,583评论 2 249

推荐阅读更多精彩内容