java 联网版五子棋

最近学习了Java的多线程和网络编程后,利用相关知识写了一个简单的联网版五子棋小游戏,客户端和服务器就是两个玩家,实现了下棋、判断输赢和聊天的功能。
具体代码如下:
public class clientChess {
private static myFrame frame=null;
public clientChess(myFrame frame) {
    this.frame=frame;
}
public void start() throws Exception{
    Socket client=new Socket("192.168.43.102",10000);

    final PrintWriter writer=new PrintWriter(client.getOutputStream(),true);
    java.io.InputStream in=client.getInputStream();
    new clientThread(client,frame).start();
    //没分出胜负时,需要向服务器传棋子的坐标
    Scanner sc=new Scanner(System.in);

    new Thread(new Runnable() {
        String line;

        @Override
        public void run() {
            while((line=sc.nextLine())!=null) {
                //frame.text.setText("我:"+line);
                frame.text.append("我:"+line+"\r\n");
                writer.println("chat:"+line);
            }

        }

    }).start();
    new Thread(new Runnable(){
        @Override
        public void run() {
            while(!frame.isWin()) {
                if(frame.backChess) {
                    writer.println("back:"+frame.getRow()+":"+frame.getCol());  
                }else {
                    writer.println(frame.getRow()+","+frame.getCol());
                }
                frame.backChess=false;

            }
            writer.println("win:"+frame.isWin());

        }

    }).start();


}
public static void main(String[] args) throws Exception {
    myFrame frame=new myFrame();
    clientChess client=new clientChess(frame);
    client.start();
}

}

客户端线程,主要用来接收服务器发来的消息,并做出处理
class clientThread extends Thread{
Socket socket=null;
myFrame frame=null;
java.io.InputStream stream=null;
BufferedReader reader=null;
PrintWriter writer = null;
public clientThread(Socket socket,myFrame frame) {
this.socket=socket;
this.frame=frame;
try {
this.stream=this.socket.getInputStream();
this.reader=new BufferedReader(new InputStreamReader(stream));
this.writer=new PrintWriter(this.socket.getOutputStream(),true);
} catch (IOException e) {
e.printStackTrace();
}
}

@Override
public void run() {
    String line=null;
    try {
        while((line=this.reader.readLine())!=null) {
            if(line.contains("ok")){
                myFrame.occupy=false;
            }
            if(line.contains(",")) {
                String[] data=line.split(",");
                int row=Integer.parseInt(data[0]);
                int col=Integer.parseInt(data[1]);
                if(frame.chess[row][col]==0){
                    writer.println("ok");
                    frame.chess[row][col]=2;
                    frame.repaint();
                    //writer.println(frame.getRow()+","+frame.getCol());
                }   
            }

            if(line.contains("win:")) {
                //System.out.println("你输了");
                JOptionPane.showMessageDialog(null, "你输了");
                frame.repaint();
            }

            if(line.contains("chat:")) {
                String[] data=line.split(":");
                //frame.text.setText("对方:"+data[1]);
                frame.text.append("对方:"+data[1]+"\r\n");
            }

            if(line.contains("back:")) {
                System.out.println(line);
                String[] data=line.split(":");
                int row=Integer.parseInt(data[1]);
                int col=Integer.parseInt(data[2]);
                frame.chess[row][col]=0;
                frame.repaint();
                frame.setRow(Integer.parseInt(data[1]));
                frame.setCol(Integer.parseInt(data[2]));

            }
        }

        this.socket.close();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

}

客户端界面:
class myPanel extends JPanel{
public static int[][] board=new int[16][16];
public myPanel(int[][] board){
this.board=board;
}

public myPanel() {

}

@Override
public void paint(Graphics g) {
    g.setColor(new Color(165,185,75));
    g.fillRect(60, 60, 360, 360);
    g.setColor(Color.black);
    //绘制棋盘
    for(int i=0;i<15;i++) {
        g.drawLine(65, 65+i*25, 415, 65+i*25);
        g.drawLine(65+i*25, 65, 65+i*25, 415);
    }
    //绘制棋子
    for(int i=1;i<board.length;i++) {
        for(int j=1;j<board[i].length;j++) {
            if(board[i][j]!=0) {
                if(board[i][j]==1) {
                    g.setColor(Color.BLACK);
                }else {
                    g.setColor(Color.WHITE);
                }
                g.fillOval(25*(j+2), 25*(i+2), 20, 20);

                if(board[i][j]==2) {
                    g.setColor(Color.BLACK);
                    g.drawOval(25*(j+2), 25*(i+2), 20, 20);
                }
            }   
        }
    }
}
//初始化数组
public boolean addPiece(int row,int col,boolean isBlack) {
    if(board[row][col]==0) {
        board[row][col]=isBlack?1:2;
        return true;
    }
    return false;

}

public boolean reducePiece(int row,int col) {
    if(board[row][col]!=0) {
        board[row][col]=0;
        return true;
    }
    return false;


}

public boolean isWin(int row,int col,boolean isBlack) {

    return checkH(row, col, isBlack) || 
            checkV(row, col, isBlack) || 
            checkX1(row, col, isBlack) || 
            checkX2(row, col, isBlack); 

}
//判断从右上到左下的斜线上是否连成5颗棋子
private boolean checkX2(int row, int col, boolean isBlack) {
    int counter=1;
    int currentRow=row;
    int currentCol=col;
    int v=isBlack?1:2;
    if(currentRow>0 && currentCol<14 && board[--currentRow][++currentCol]==v) {
        counter++;
    }
    currentRow=row;
    currentCol=col;
    if(currentRow<14 && currentCol>0 && board[++currentRow][--currentCol]==v) {
        counter++;
    }
    return counter>=5;
}
//判断从左上到右下
private boolean checkX1(int row, int col, boolean isBlack) {
    int counter=1;
    int currentRow=row;
    int currentCol=col;
    int v=isBlack?1:2;
    while(currentRow>0 && currentCol>0 && board[--currentRow][--currentCol]==v) {
        counter++;
    }
    currentRow=row;
    currentCol=col;
    while(currentRow<14 && currentCol<14 && board[++currentRow][++currentCol]==v) {
        counter++;
    }
    return counter>=5;
}
//判断竖着方向是否连成5颗棋子
private boolean checkV(int row, int col, boolean isBlack) {
    int counter=1;
    int currentRow=row;
    int currentCol=col;
    int v=isBlack?1:2;
    while(currentRow>0 && board[--currentRow][currentCol]==v) {
        counter++;
    }
    currentRow=row;
    currentCol=col;
    while(currentRow<14  && board[++currentRow][currentCol]==v) {
        counter++;
    }
    return counter>=5;
}

private boolean checkH(int row, int col, boolean isBlack) {

    int counter=1;
    int currentRow=row;
    int currentCol=col;
    int v=isBlack?1:2;
    while(currentCol>0 && board[currentRow][--currentCol]==v) {
        counter++;
    }
    currentRow=row;
    currentCol=col;
    while(currentCol<14 && board[currentRow][++currentCol]==v) {
        counter++;
    }
    return counter>=5;

}

}

public class myFrame extends JFrame{
public static int[][] chess=new int[16][16];
private volatile boolean isBlack = true;// 是否轮到黑棋
public static boolean occupy=false;
private boolean isWin = false;// 是否获得胜利
private boolean isStart = false;// 是否联机成功开始游戏
public static boolean backChess=false;
private int row=0;
private int col=0;

public static JTextArea text;


public boolean isWin() {
    return isWin;
}

public void setWin(boolean isWin) {
    this.isWin = isWin;
}


public int getRow() {
    return row;
}

public void setRow(int row) {
    this.row = row;
}

public int getCol() {
    return col;
}

public void setCol(int col) {
    this.col = col;
}



public myFrame() {
    this.setName("联机版五子棋");
    this.setBounds(100, 100, 500, 580);
    this.setLayout(null);

    JButton start=new JButton("开始");
    start.setBounds(10, 10, 60, 25);
    this.add(start);
    //开始按钮

    JButton back=new JButton("悔棋");
    back.setBounds(80, 10, 60, 25);;
    this.add(back);

    text=new JTextArea();
    JScrollPane pane=new JScrollPane(text);
    pane.setBounds(60, 430, 360, 100);
    this.add(pane);


    JButton end=new JButton("退出");
    end.setBounds(150, 10, 60, 25);
    this.add(end);

    end.addActionListener(new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent e) {
            System.exit(0);
        }
    });


    final myPanel panel=new myPanel(chess);
    panel.setBounds(0, 0, 500, 500);
    this.add(panel);

    //JTextField innfo=new


    panel.addMouseListener(new MouseAdapter() {
        @Override
        public void mousePressed(MouseEvent e) {
            if(isStart  && !isWin() && !occupy ) {
                int x=e.getX();
                int y=e.getY();
                if(x>=65 && x<=415 && y>=65 &&y<=415) {
                    setRow(Math.round((y-65)/25f));
                    setCol(Math.round((x-65)/25f));
                    //System.out.println(getRow()+","+getCol());
                    repaint();
                    if(panel.addPiece(getRow(), getCol(), isBlack)) {
                        setWin(panel.isWin(getRow(), getCol(), isBlack));
                        if(!isWin()) {

                        }else {
                            JOptionPane.showMessageDialog(null, "你赢了。。。。");
                            setWin(true);
                            repaint();
                        }
                    }

                }
            }

        }
    });


    start.addActionListener(new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent e) {
            isStart=true;


        }
    });




    //悔棋按钮监听事件
    back.addActionListener(new ActionListener() {

        @Override
        public void actionPerformed(ActionEvent e) {
            System.out.println(getRow()+","+getCol());
            chess[getRow()][getCol()]=0;
            backChess=true;

// backChess=panel.reducePiece(getRow(), getCol());
repaint();

        }
    });

    this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    this.setVisible(true);
}

}

服务器端:
public class serverChess extends JFrame{

public static myFrame2 frame=null;
public serverChess(myFrame2 frame) {
    this.frame=frame;
}

public void start() throws Exception{

    ServerSocket server=new ServerSocket(10000);
    System.out.println("服务器端启动");
    while(true){
        Socket socket=server.accept();
        final PrintWriter writer=new PrintWriter(socket.getOutputStream(),true);
        Scanner sc=new Scanner(System.in);
        new Thread(new Runnable() {

            String line;
            @Override
            public void run() {
                while((line=sc.nextLine())!=null) {
                    //frame.text.setText("我:"+line);
                    frame.text.append("我:"+line+"\r\n");
                    writer.println("chat:"+line);
                }

            }

        }).start();

        new Thread(new Runnable(){
            @Override
            public void run() {
                while(!frame.isWin()) {
                    writer.println(frame.getRow()+","+frame.getCol());
                    if(frame.backChess) {
                        writer.println("back:"+frame.getRow()+":"+frame.getCol());
                    }
                }
                writer.println("win:"+frame.isWin());
            }

        }).start();
        new serverThread(socket,frame).start();
    }

}

public static void main(String[] args) throws Exception {
    myFrame2 frame=new myFrame2();
    serverChess server=new serverChess(frame);
    server.start();
}

}

服务器线程,接收客户端的消息并做出处理
class serverThread extends Thread{
private Socket socket=null;
private myFrame2 frame=null;
public serverThread(Socket socket,myFrame2 frame2){
this.socket=socket;
this.frame=frame2;
}

@Override
public void run() {

    BufferedReader reader = null;
    PrintWriter writer = null;
    try {
        reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
        writer = new PrintWriter(socket.getOutputStream(),true);
        String line =reader.readLine();

        while((line=reader.readLine()) != null) {
            if(line.contains("ok")){
                myFrame2.occupy=false;
            }
            if(line.contains(",")) {
                String[] data=line.split(",");
                int row=Integer.parseInt(data[0]);
                int col=Integer.parseInt(data[1]);
                if(frame.chess[row][col]==0){
                    writer.println("ok");
                    frame.chess[row][col]=1;
                    frame.repaint();
                    //writer.println(frame.getRow()+","+frame.getCol());
                }   
            }



            if(line.contains("win:")) {
                //System.out.println("你输了");
                JOptionPane.showMessageDialog(null, "你输了");
                frame.setWin(true);
                frame.repaint();
            }

            if(line.contains("chat:")) {
                String[] data=line.split(":");
                //frame.text.setText("对方:"+data[1]);
                frame.text.append("对方:"+data[1]+"\r\n");
            }
            if(line.contains("back:")) {



                System.out.println(line);

// String[] data=line.split(“:”);
// int row=Integer.parseInt(data[1]);
// int col=Integer.parseInt(data[2]);
// frame.chess[row][col]=0;
// frame.repaint();
// frame.setRow(Integer.parseInt(data[1]));
// frame.setCol(Integer.parseInt(data[2]));
// System.out.println(frame.getRow()+”,”+frame.getCol());
// frame.chess[row][col]=1;

            }
        }
        this.socket.close(); // 连接关闭,所有的流都会随之关闭

    } catch (Exception e) {
        e.printStackTrace();
    }

}

}

class serverPanel extends JPanel{
public static int[][] board=new int[16][16];

public serverPanel(int[][] board){
    this.board=board;
}


@Override
public void paint(Graphics g) {
    g.setColor(new Color(165,185,75));
    g.fillRect(60, 60, 360, 360);
    g.setColor(Color.black);
    //绘制棋盘
    for(int i=0;i<15;i++) {
        g.drawLine(65, 65+i*25, 415, 65+i*25);
        g.drawLine(65+i*25, 65, 65+i*25, 415);
    }
    //绘制棋子
    for(int i=1;i<board.length;i++) {
        for(int j=1;j<board[i].length;j++) {
            if(board[i][j]!=0) {
                if(board[i][j]==1) {
                    g.setColor(Color.BLACK);
                }else {
                    g.setColor(Color.WHITE);
                }
                g.fillOval(25*(j+2), 25*(i+2), 20, 20);

                if(board[i][j]==2) {
                    g.setColor(Color.BLACK);
                    g.drawOval(25*(j+2), 25*(i+2), 20, 20);
                }
            }   
        }
    }
}
//初始化数组
public boolean addPiece(int row,int col,boolean isBlack) {
    if(board[row][col]==0) {
        board[row][col]=isBlack?1:2;
        return true;
    }
    return false;

}

public boolean reducePiece(int row,int col) {
    if(board[row][col]!=0) {
        board[row][col]=0;
        return true;
    }
    return false;
}



public boolean isWin(int row,int col,boolean isBlack) {

    return checkH(row, col, isBlack) || 
            checkV(row, col, isBlack) || 
            checkX1(row, col, isBlack) || 
            checkX2(row, col, isBlack); 

}
//判断从右上到左下的斜线上是否连成5颗棋子
private boolean checkX2(int row, int col, boolean isBlack) {
    int counter=1;
    int currentRow=row;
    int currentCol=col;
    int v=isBlack?1:2;
    if(currentRow>0 && currentCol<14 && board[--currentRow][++currentCol]==v) {
        counter++;
    }
    currentRow=row;
    currentCol=col;
    if(currentRow<14 && currentCol>0 && board[++currentRow][--currentCol]==v) {
        counter++;
    }
    return counter>=5;
}
//判断从左上到右下
private boolean checkX1(int row, int col, boolean isBlack) {
    int counter=1;
    int currentRow=row;
    int currentCol=col;
    int v=isBlack?1:2;
    while(currentRow>0 && currentCol>0 && board[--currentRow][--currentCol]==v) {
        counter++;
    }
    currentRow=row;
    currentCol=col;
    while(currentRow<14 && currentCol<14 && board[++currentRow][++currentCol]==v) {
        counter++;
    }
    return counter>=5;
}
//判断竖着方向是否连成5颗棋子
private boolean checkV(int row, int col, boolean isBlack) {
    int counter=1;
    int currentRow=row;
    int currentCol=col;
    int v=isBlack?1:2;
    while(currentRow>0 && board[--currentRow][currentCol]==v) {
        counter++;
    }
    currentRow=row;
    currentCol=col;
    while(currentRow<14  && board[++currentRow][currentCol]==v) {
        counter++;
    }
    return counter>=5;
}

private boolean checkH(int row, int col, boolean isBlack) {

    int counter=1;
    int currentRow=row;
    int currentCol=col;
    int v=isBlack?1:2;
    while(currentCol>0 && board[currentRow][--currentCol]==v) {
        counter++;
    }
    currentRow=row;
    currentCol=col;
    while(currentCol<14 && board[currentRow][++currentCol]==v) {
        counter++;
    }
    return counter>=5;

}

}

服务器界面:
public class myFrame2 extends JFrame {

public static int[][] chess=new int[16][16];

private volatile boolean isBlack = false;// 是否轮到黑棋
public static boolean occupy=false;
private boolean isWin = false;// 是否获得胜利
private boolean isStart = false;// 是否联机成功
private int row=0;
private int col=0;

public static boolean backChess=false;

public JButton back;
final serverPanel panel;
public static JTextArea text;


public myFrame2() {
    this.setName("联机版五子棋");
    this.setBounds(100, 100, 500, 580);
    this.setLayout(null);

    JButton start=new JButton("开始");
    start.setBounds(10, 10, 60, 25);
    this.add(start);
    //开始按钮

    back=new JButton("悔棋");
    back.setBounds(80, 10, 60, 25);;
    this.add(back);




    JButton end=new JButton("退出");
    end.setBounds(150, 10, 60, 25);
    this.add(end);

    JButton oppoBack=new JButton("对方悔棋");
    oppoBack.setBounds(230, 10, 120, 25);
    this.add(oppoBack);




    end.addActionListener(new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent e) {
            System.exit(0);
        }
    });


    text=new JTextArea();
    JScrollPane pane=new JScrollPane(text);
    pane.setBounds(60, 430, 360, 100);
    this.add(pane);



    panel=new serverPanel(chess);
    panel.setBounds(0, 0, 430, 500);
    this.add(panel);



    panel.addMouseListener(new MouseAdapter() {
        @Override
        public void mousePressed(MouseEvent e) {
            if(isStart  && !isWin() && !occupy ) {
                int x=e.getX();
                int y=e.getY();
                if(x>=65 && x<=415 && y>=65 &&y<=415) {
                    setRow(Math.round((y-65)/25f));
                    setCol(Math.round((x-65)/25f));
                    //System.out.println(getRow()+","+getCol());
                    repaint();
                    if(panel.addPiece(getRow(), getCol(), isBlack)) {
                        setWin(panel.isWin(getRow(), getCol(), isBlack));
                        if(!isWin()) {

                        }else {
                            JOptionPane.showMessageDialog(null, "你赢了。。。。。");
                            setWin(true);
                            repaint();
                        }
                    }

                }
            }

        }
    });


    start.addActionListener(new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent e) {
            isStart=true;

        }
    });




    //悔棋按钮监听事件
    back.addActionListener(new ActionListener() {

        @Override
        public void actionPerformed(ActionEvent e) {
            System.out.println(getRow()+","+getCol());
            chess[getRow()][getCol()]=0;
            backChess=true;
            repaint();

        }
    });

   oppoBack.addActionListener(new ActionListener() {

    @Override
    public void actionPerformed(ActionEvent e) {
        panel.reducePiece(getRow(), getCol());
        repaint();

    }
});

    this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    this.setVisible(true);
}






public boolean isWin() {
    return isWin;
}

public void setWin(boolean isWin) {
    this.isWin = isWin;
}


public int getRow() {
    return row;
}

public void setRow(int row) {
    this.row = row;
}

public int getCol() {
    return col;
}

public void setCol(int col) {
    this.col = col;
}

}

游戏截图:

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值