简单五子棋java源码

本实例是一个简单的网络五子棋程序。程序由两个部分组成:一部分为服务器端,另一部分为五子棋客户端。其中服务器端以消息方式完成客户端的管理,客户端支持对弈和聊天。

实例源代码由com.fivechess.chessface、com.fivechess.client、com.fivechess.server三个包组成。

 

chessServer.java

 


package com.fivechess.server;
import java.io.*;
import java.net.*;
import java.awt.*;
import java.util.*;
import java.awt.event.*;
/**
 * 显示服务器及用户信息的Panel类
 */
class MessageServerPanel extends Panel
{
 TextArea messageBoard = new TextArea("", 22, 50,
   TextArea.SCROLLBARS_VERTICAL_ONLY);

 Label statusLabel = new Label("当前连接数:", Label.LEFT);

 Panel boardPanel = new Panel();//主显示区Panel

 Panel statusPanel = new Panel();//连接状态Panel

 MessageServerPanel() {
  setSize(350, 300);
  setBackground(new Color(204,204,204));
  setLayout(new BorderLayout());
  boardPanel.setLayout(new FlowLayout());
  boardPanel.setSize(210, 210);
  statusPanel.setLayout(new BorderLayout());
  statusPanel.setSize(210, 50);
  boardPanel.add(messageBoard);
  statusPanel.add(statusLabel, BorderLayout.WEST);
  add(boardPanel, BorderLayout.CENTER);
  add(statusPanel, BorderLayout.NORTH);
 }
}
/**
 * 服务器线程,主要用于服务器与客户端的通信
 */
class ServerThread extends Thread {
 Socket clientSocket;

 Hashtable clientDataHash;//Socket与发送数据的流的映射

 Hashtable clientNameHash;//Socket与用户名的映射

 Hashtable chessPeerHash;//对弈的两个客户端用户名的映射

 MessageServerPanel server;

 boolean isClientClosed = false;
    /**
     * 服务器端线程的构造函数,用于初始化一些对象。
     */
 ServerThread(Socket clientSocket, Hashtable clientDataHash,
   Hashtable clientNameHash, Hashtable chessPeerHash,
   MessageServerPanel server) {
  this.clientSocket = clientSocket;
  this.clientDataHash = clientDataHash;
  this.clientNameHash = clientNameHash;
  this.chessPeerHash = chessPeerHash;
  this.server = server;
 }
/**
 * 对客户端发来的消息处理的函数,处理后转发回客户端。处理消息的过程比较复杂,
 * 要针对很多种情况分别处理。
 */
 public void messageTransfer(String message) {
  String clientName, peerName;
     //如果消息以“/”开头,表明是命令消息。
  if (message.startsWith("/")) {
        //消息以“/changename”开头的几种情况.
   if (message.startsWith("/changename ")) {
    //获取修改后的用户名
    clientName = message.substring(12);
    if (clientName.length() <= 0 || clientName.length() > 20
      || clientName.startsWith("/")
      || clientNameHash.containsValue(clientName)
      || clientName.startsWith("changename")
      || clientName.startsWith("list")
      || clientName.startsWith("[inchess]")
      || clientName.startsWith("creatgame")
      || clientName.startsWith("joingame")
      || clientName.startsWith("yourname")
      || clientName.startsWith("userlist")
      || clientName.startsWith("chess")
      || clientName.startsWith("OK")
      || clientName.startsWith("reject")
      || clientName.startsWith("peer")
      || clientName.startsWith("peername")
      || clientName.startsWith("giveup")
      || clientName.startsWith("youwin")
      || clientName.startsWith("所有人")) {
     //如果名字不合规则,则向客户端发送信息“无效命令”。
     message = "无效命令";
     Feedback(message);
    } else {
     if (clientNameHash
       .containsValue(("[inchess]" + (String) clientNameHash
         .get(clientSocket)))) {
        //如果用户正在对弈中,则直接修改Socket和名字的映射Hash表。
      synchronized (clientNameHash) {
       clientNameHash.put((Socket) getHashKey(
         clientNameHash,
         ("[inchess]" + clientNameHash
           .get(clientSocket))),
         ("[inchess]" + clientName));
       chessPeerTalk(("[inchess" + clientName),
         ("/yourname " + ("[inchess]" + clientName)));
      }
     }
     //如果用户在对弈双方的客户端,做如下处理。
     else if (chessPeerHash.containsKey(clientNameHash
       .get(clientSocket))) {
      //将客户端的新名字映射到clientNameHash
      synchronized (clientNameHash) {
       clientNameHash.put((Socket) getHashKey(
         clientNameHash,
         ("[inchess]" + clientNameHash
           .get(clientSocket))),
         ("[inchess]" + clientName));
      }

      synchronized (chessPeerHash) {
       //chessPeerHash添加新名字映射
       chessPeerHash.put(clientName, chessPeerHash
         .get(clientNameHash.get(clientSocket)));
       //chessPeerHash删除旧映射
       chessPeerHash.remove(clientNameHash
         .get(clientSocket));
      }
      //向游戏客户端发送新名字
      chessPeerTalk(("[inchess]" + clientName),
        ("/yourname " + ("[inchess]" + clientName)));
      //向peer游戏客户端发送
      chessPeerTalk((String) chessPeerHash.get(clientName),
        ("/peer " + "[inchess]" + clientName));

     }
//     如果用户在对弈双方的服务端,做如下处理。
     else if (chessPeerHash.containsValue(clientNameHash
       .get(clientSocket))) {
      synchronized (clientNameHash) {
       //游戏客户端改名字
       clientNameHash.put((Socket) getHashKey(
         clientNameHash,
         ("[inchess]" + clientNameHash
           .get(clientSocket))),
         ("[inchess]" + clientName));
      }
      synchronized (chessPeerHash) {
       //chessPeerHash重新映射
       chessPeerHash.put((String) getHashKey(
         chessPeerHash, clientNameHash
           .get(clientSocket)), clientName);
       //向游戏客户端发送新名字
       chessPeerTalk(("[inchess]" + clientName),
         ("/yourname " + ("[inchess]" + clientName)));
      }
      //向peer游戏客户端发送
      chessPeerTalk((String) getHashKey(chessPeerHash,
        clientName),
        ("/peer " + "[inchess]" + clientName));

     }
                    //将改名消息封装好以备发送
     message = clientNameHash.get(clientSocket) + "改名为:"
       + clientName;
     synchronized (clientNameHash) {
      clientNameHash.put(clientSocket, clientName);
     }
     //向所有的客户端发送消息
     publicTalk(message);
     //回馈到改名的客户端
     Feedback("/yourname "
       + (String) clientNameHash.get(clientSocket));
     //刷新用户列表
     publicTalk(getUserList());

    }

   }
   //如果消息以“/list”开头,则将其回馈到客户端以更新用户列表
   else if (message.equals("/list")) {
    Feedback(getUserList());
   }
   //如果消息以"/creatgame [inchess]"开头,则修改clientNameHash映射
   //和chessPeerHash映射。
   else if (message.startsWith("/creatgame [inchess]")) {
    String chessServerName = message.substring(20);
    synchronized (clientNameHash) {
     clientNameHash.put(clientSocket, message.substring(11));
    }
    synchronized (chessPeerHash) {
     chessPeerHash.put(chessServerName, "wait");
    }
    Feedback("/yourname " + clientNameHash.get(clientSocket));
    chessPeerTalk(chessServerName, "/OK");
    publicTalk(getUserList());
   }
   //如果消息以“/joingame”开头,则将消息的服务端名字和本地用户名提取出来,
   //然后修改clientNameHash表和chessPeerHash表。
   else if (message.startsWith("/joingame ")) {
    StringTokenizer userToken = new StringTokenizer(message, " ");
    String getUserToken, serverName, selfName;
    String[] chessNameOpt = { "0", "0" };
    int getOptNum = 0;
            //提取服务端用户名和本地用户名
    while (userToken.hasMoreTokens()) {
     getUserToken = (String) userToken.nextToken(" ");
     if (getOptNum >= 1 && getOptNum <= 2) {
      chessNameOpt[getOptNum - 1] = getUserToken;
     }
     getOptNum++;
    }
    serverName = chessNameOpt[0];
    selfName = chessNameOpt[1];
                //如果有服务端在等待开始棋局
    if (chessPeerHash.containsKey(serverName)
      && chessPeerHash.get(serverName).equals("wait")) {
     //修改Socket和名字映射
     synchronized (clientNameHash) {
      clientNameHash.put(clientSocket,
        ("[inchess]" + selfName));
     }
     //修改chessPeerHash映射
     synchronized (chessPeerHash) {
      chessPeerHash.put(serverName, selfName);
     }
     publicTalk(getUserList());
     chessPeerTalk(selfName,
       ("/peer " + "[inchess]" + serverName));
     chessPeerTalk(serverName,
       ("/peer " + "[inchess]" + selfName));
    } else {
     chessPeerTalk(selfName, "/reject");
     try {
      clientClose();
     } catch (Exception ez) {
     }
    }
   }
   //如果消息以“/[inchess]”开头,则获取要发送消息的用户名和发送的消息
   //然后发送出去。
   else if (message.startsWith("/[inchess]")) {
    int firstLocation = 0, lastLocation;

    lastLocation = message.indexOf(" ", 0);

    peerName = message.substring((firstLocation + 1), lastLocation);
    message = message.substring((lastLocation + 1));
    if (chessPeerTalk(peerName, message)) {
     Feedback("/error");
    }
   }
   //如果消息以“/giveup”开头,则判断是对弈双方哪方放弃了。
   else if (message.startsWith("/giveup ")) {
    String chessClientName = message.substring(8);
    if (chessPeerHash.containsKey(chessClientName)
      && !((String) chessPeerHash.get(chessClientName))
        .equals("wait")) {
     //如果服务方放弃,则发送消息“/youwin”表明对方获胜
     chessPeerTalk((String) chessPeerHash.get(chessClientName),
       "/youwin");
     synchronized (chessPeerHash) {
      chessPeerHash.remove(chessClientName);
     }
    }
    if (chessPeerHash.containsValue(chessClientName)) {
     //如果客户方放弃,也发送消息“/youwin”表明对方获胜
     chessPeerTalk((String) getHashKey(chessPeerHash,
       chessClientName), "/youwin");
     synchronized (chessPeerHash) {
      chessPeerHash.remove((String) getHashKey(chessPeerHash,
        chessClientName));
     }
    }
   }
   //如果找不到发送消息的用户,则输出消息说“没有这个用户”
   else {

    int firstLocation = 0, lastLocation;

    lastLocation = message.indexOf(" ", 0);
    if (lastLocation == -1) {
     Feedback("无效命令");
     return;
    } else {
     peerName = message.substring((firstLocation + 1),
       lastLocation);
     message = message.substring((lastLocation + 1));
     message = (String) clientNameHash.get(clientSocket) + ">"
       + message;
     if (peerTalk(peerName, message)) {
      Feedback("没有这个用户:" + peerName + "/n");
     }
    }

   }

  }
       //如果不以“/”开头,表明是普通消息,直接发送
  else {
   message = clientNameHash.get(clientSocket) + ">" + message;
   server.messageBoard.append(message + "/n");
   publicTalk(message);
   server.messageBoard.setCaretPosition(server.messageBoard.getText()
     .length());
  }

 }
   /**
    * 发送公共消息的函数,将消息向每个客户端都发送一份
    */
 public void publicTalk(String publicTalkMessage) {

  synchronized (clientDataHash) {
   for (Enumeration enu = clientDataHash.elements(); enu
     .hasMoreElements();) {
    DataOutputStream outData = (DataOutputStream) enu.nextElement();
    try {
     outData.writeUTF(publicTalkMessage);
    } catch (IOException es) {
     es.printStackTrace();
    }
   }
  }

 }
  /**
   * 选择对象发送消息,参数peerTalk为发送的用户名,后面的参数为发送的消息
   */
 public boolean peerTalk(String peerTalk, String talkMessage) {
        //
  for (Enumeration enu = clientDataHash.keys(); enu.hasMoreElements();) {
   Socket userClient = (Socket) enu.nextElement();
           //找到发送消息的对象,获取它的输出流以发送消息
   if (peerTalk.equals((String) clientNameHash.get(userClient))
     && !peerTalk.equals((String) clientNameHash
       .get(clientSocket))) {
    synchronized (clientDataHash) {
     DataOutputStream peerOutData = (DataOutputStream) clientDataHash
       .get(userClient);
     try {
      peerOutData.writeUTF(talkMessage);
     } catch (IOException es) {
      es.printStackTrace();
     }
    }
    Feedback(talkMessage);
    return (false);
   }
   //如果是发给自己的,直接回馈
   else if (peerTalk.equals((String) clientNameHash
     .get(clientSocket))) {
    Feedback(talkMessage);
    return (false);
   }
  }

  return (true);

 }
   /**
    * 此函数也用于选择发送消息,但不能发送给自己。
    */
 public boolean chessPeerTalk(String chessPeerTalk, String chessTalkMessage) {

  for (Enumeration enu = clientDataHash.keys(); enu.hasMoreElements();) {
   Socket userClient = (Socket) enu.nextElement();

   if (chessPeerTalk.equals((String) clientNameHash.get(userClient))
     && !chessPeerTalk.equals((String) clientNameHash
       .get(clientSocket))) {
    synchronized (clientDataHash) {
     DataOutputStream peerOutData = (DataOutputStream) clientDataHash
       .get(userClient);
     try {
      peerOutData.writeUTF(chessTalkMessage);
     } catch (IOException es) {
      es.printStackTrace();
     }
    }
    return (false);
   }
  }
  return (true);
 }
  /**
   * 用于处理消息回馈的函数
   */
 public void Feedback(String feedbackString) {
  synchronized (clientDataHash) {
   DataOutputStream outData = (DataOutputStream) clientDataHash
     .get(clientSocket);
   try {
    outData.writeUTF(feedbackString);
   } catch (Exception eb) {
    eb.printStackTrace();
   }
  }

 }
   /**
    * 获取用户列表的函数,此函数读取clientNameHash获取用户列表,
    * 然后将其保存在一个字符串userList中。
    */
 public String getUserList() {
  String userList = "/userlist";

  for (Enumeration enu = clientNameHash.elements(); enu.hasMoreElements();) {
   userList = userList + " " + (String) enu.nextElement();
  }
  return userList;
 }
    /**
     * 给出HashTable和值对象,获取相对应得键值的函数。
     */
 public Object getHashKey(Hashtable targetHash, Object hashValue) {
  Object hashKey;
  for (Enumeration enu = targetHash.keys(); enu.hasMoreElements();) {
   hashKey = (Object) enu.nextElement();
   if (hashValue.equals((Object) targetHash.get(hashKey)))
    return (hashKey);
  }
  return (null);
 }

 public void firstCome() {
  publicTalk(getUserList());
  Feedback("/yourname " + (String) clientNameHash.get(clientSocket));
  Feedback("Java五子棋聊天客户端");
  Feedback("/changename <你的名字> --更改名字");
  Feedback("/list --更新用户列表");
  Feedback("/<用户名> <要说的话> --私聊");
  Feedback("注意:用命令的时候,先把谈话的对象定为所有人");
 }
    /**
     * 用于和客户端断开的函数。
     */
 public void clientClose() {
  server.messageBoard.append("用户断开:" + clientSocket + "/n");
  //如果是游戏客户端主机
  synchronized (chessPeerHash) {
   if (chessPeerHash.containsKey(clientNameHash.get(clientSocket))) {
    chessPeerHash.remove((String) clientNameHash.get(clientSocket));
   }
   if (chessPeerHash.containsValue(clientNameHash.get(clientSocket))) {
    chessPeerHash.put((String) getHashKey(chessPeerHash,
      (String) clientNameHash.get(clientSocket)),
      "tobeclosed");
   }
  }
  //将保留的HashTable里的数据清除
  synchronized (clientDataHash) {
   clientDataHash.remove(clientSocket);
  }
  synchronized (clientNameHash) {
   clientNameHash.remove(clientSocket);
  }
  publicTalk(getUserList());
  //计算当前连接数,并显示在状态框中
  server.statusLabel.setText("当前连接数:" + clientDataHash.size());
  try {
   clientSocket.close();
  } catch (IOException exx) {
  }

  isClientClosed = true;

 }

 public void run() {
  DataInputStream inData;
  synchronized (clientDataHash) {
   server.statusLabel.setText("当前连接数:" + clientDataHash.size());
  }
  try {
   inData = new DataInputStream(clientSocket.getInputStream());
   firstCome();
   while (true) {
    String message = inData.readUTF();
    messageTransfer(message);
   }
  } catch (IOException esx) {
  } finally {
   if (!isClientClosed) {
    clientClose();
   }
  }
 }

}

/**
 * @author wufenghanren
 * 服务器端框架类
 */
public class chessServer extends Frame implements ActionListener {

 Button messageClearButton = new Button("清除显示");

 Button serverStatusButton = new Button("服务器状态");

 Button serverOffButton = new Button("关闭服务器");

 Panel buttonPanel = new Panel();

 MessageServerPanel server = new MessageServerPanel();

 ServerSocket serverSocket;

 Hashtable clientDataHash = new Hashtable(50);

 Hashtable clientNameHash = new Hashtable(50);

 Hashtable chessPeerHash = new Hashtable(50);
    /**
     *框架类的构造函数
     */
 chessServer() {
  super("Java五子棋服务器");
  setBackground(new Color(204,204,204));

  buttonPanel.setLayout(new FlowLayout());
  messageClearButton.setSize(60, 25);
  buttonPanel.add(messageClearButton);
  messageClearButton.addActionListener(this);
  serverStatusButton.setSize(75, 25);
  buttonPanel.add(serverStatusButton);
  serverStatusButton.addActionListener(this);
  serverOffButton.setSize(75, 25);
  buttonPanel.add(serverOffButton);
  serverOffButton.addActionListener(this);

  add(server, BorderLayout.CENTER);
  add(buttonPanel, BorderLayout.SOUTH);
        //退出窗口的监听器
  addWindowListener(new WindowAdapter() {
   public void windowClosing(WindowEvent e) {
    System.exit(0);
   }
  });
  setVisible(true);
  setSize(400, 450);
  setResizable(false);
  validate();
  try {
   makeMessageServer(4331, server);
  } catch (Exception e) {
   System.out.println("e");
  }
 }
    /**
     * 初始化消息服务器的类
     */
 public void makeMessageServer(int port, MessageServerPanel server)
   throws IOException {
  Socket clientSocket;
  long clientAccessNumber = 1;
  this.server = server;

  try {
   //输出服务器的启动信息
   serverSocket = new ServerSocket(port);
   server.messageBoard.setText("服务器开始于:"
     + serverSocket.getInetAddress().getLocalHost() + ":"
     + serverSocket.getLocalPort() + "/n");

   while (true) {
    clientSocket = serverSocket.accept();
    server.messageBoard.append("用户连接:" + clientSocket + "/n");

    DataOutputStream outData = new DataOutputStream(clientSocket
      .getOutputStream());

    clientDataHash.put(clientSocket, outData);
    clientNameHash
      .put(clientSocket, ("新来客" + clientAccessNumber++));

    ServerThread thread = new ServerThread(clientSocket,
      clientDataHash, clientNameHash, chessPeerHash, server);

    thread.start();
   }
  } catch (IOException ex) {
   System.out.println("已经有服务器在运行. /n");
  }

 }
 /**
  * 按钮的事件监听器,响应按钮点击事件
  */
 public void actionPerformed(ActionEvent e) {
  if (e.getSource() == messageClearButton) {
   server.messageBoard.setText("");
  }
  //当“服务器状态”按钮点击时,显示服务器状态
  if (e.getSource() == serverStatusButton) {
   try {
    server.messageBoard.append("服务器信息:"
      + serverSocket.getInetAddress().getLocalHost() + ":"
      + serverSocket.getLocalPort() + "/n");
   } catch (Exception ee) {
    System.out
      .println("serverSocket.getInetAddress().getLocalHost() error /n");
   }
  }
  if (e.getSource() == serverOffButton) {
   System.exit(0);
  }
 }

 public static void main(String args[]) {
  chessServer chessServer = new chessServer();
 }
}

 

chessClient.java

 

package com.fivechess.client;

import com.fivechess.chessface.chatPad;
import com.fivechess.chessface.inputPad;
import com.fivechess.chessface.userPad;
import com.fivechess.chessface.chessPad;
import com.fivechess.chessface.controlPad;
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.net.*;
import java.util.*;
import javax.swing.JColorChooser;

/**
 * @author wufenghanren
 * 五子棋客户端框架,实现了动作监听器和键盘监听器
 */

public class chessClient extends Frame implements ActionListener, KeyListener {
 userPad userpad = new userPad();//用户列表Panel

 chatPad chatpad = new chatPad();//聊天信息Panel

 controlPad controlpad = new controlPad();//控制Panel

 chessPad chesspad = new chessPad();//棋盘Panel

 inputPad inputpad = new inputPad();//信息输入Panel

 Socket chatSocket;

 DataInputStream in;

 DataOutputStream out;

 String chessClientName = null;

 String host = null;

 int port = 4331;

 boolean isOnChat = false; //是否在聊天

 boolean isOnChess = false; //是否在下棋

 boolean isGameConnected = false; //是否下棋的客户端连接

 boolean isServer = false; //是否建立游戏的主机

 boolean isClient = false; //是否加入游戏的客户端

 Panel southPanel = new Panel();

 Panel centerPanel = new Panel();

 Panel westPanel = new Panel();

 /*
  * 五子棋客户端框架的构造函数。用来初始化一些对象、布局和为按钮添加监听器。
  */
 public chessClient() {
  super("五子棋客户端");
  setLayout(new BorderLayout());
  host = controlpad.inputIP.getText();

  westPanel.setLayout(new BorderLayout());
  westPanel.add(userpad, BorderLayout.NORTH);
  westPanel.add(chatpad, BorderLayout.CENTER);
  westPanel.setBackground(new Color(204, 204, 204));

  inputpad.inputWords.addKeyListener(this);
  chesspad.host = controlpad.inputIP.getText();

  centerPanel.add(chesspad, BorderLayout.CENTER);
  centerPanel.add(inputpad, BorderLayout.SOUTH);
  centerPanel.setBackground(new Color(204, 204, 204));

  controlpad.connectButton.addActionListener(this);
  controlpad.creatGameButton.addActionListener(this);
  controlpad.joinGameButton.addActionListener(this);
  controlpad.cancelGameButton.addActionListener(this);
  controlpad.colorChangeButton.addActionListener(this);
  controlpad.exitGameButton.addActionListener(this);

  controlpad.creatGameButton.setEnabled(false);
  controlpad.joinGameButton.setEnabled(false);
  controlpad.cancelGameButton.setEnabled(false);

  southPanel.add(controlpad, BorderLayout.CENTER);
  southPanel.setBackground(new Color(204, 204, 204));
  //添加窗口监听器,当窗口关闭时,关闭用于通讯的Socket。
  addWindowListener(new WindowAdapter() {
   public void windowClosing(WindowEvent e) {
    if (isOnChat) {
     try {
      chatSocket.close();
     } catch (Exception ed) {
     }
    }
    if (isOnChess || isGameConnected) {
     try {
      chesspad.chessSocket.close();
     } catch (Exception ee) {
     }
    }
    System.exit(0);
   }
  });

  add(westPanel, BorderLayout.WEST);
  add(centerPanel, BorderLayout.CENTER);
  add(southPanel, BorderLayout.SOUTH);

  setSize(670, 548);
  setVisible(true);
  setResizable(true);
  validate();
 }

 /**
  * 和服务器建立连接并通信的函数。
  */
 public boolean connectServer(String serverIP, int serverPort)
   throws Exception {
  try {
   chatSocket = new Socket(serverIP, serverPort);
   in = new DataInputStream(chatSocket.getInputStream());
   out = new DataOutputStream(chatSocket.getOutputStream());

   clientThread clientthread = new clientThread(this);
   clientthread.start();
   isOnChat = true;
   return true;
  } catch (IOException ex) {
   chatpad.chatLineArea
     .setText("chessClient:connectServer:无法连接,建议重新启动程序 /n");
  }
  return false;
 }

 /**
  * 动作监听器,响应按钮点击动作。
  */
 public void actionPerformed(ActionEvent e) {
  //如果点击的是“连接主机”按钮,则用获取的服务器主机名连接服务器。
  if (e.getSource() == controlpad.connectButton) {
   host = chesspad.host = controlpad.inputIP.getText();
   try {
    if (connectServer(host, port)) {
     chatpad.chatLineArea.setText("");
     controlpad.connectButton.setEnabled(false);
     controlpad.creatGameButton.setEnabled(true);
     controlpad.joinGameButton.setEnabled(true);
     chesspad.statusText.setText("连接成功,请创建游戏或加入游戏");
    }

   } catch (Exception ei) {
    chatpad.chatLineArea
      .setText("controlpad.connectButton:无法连接,建议重新启动程序 /n");
   }
  }
  //  如果点击的是“关闭程序”按钮,则关闭正在进行通信的Socekt并退出游戏。
  if (e.getSource() == controlpad.exitGameButton) {
   if (isOnChat) {
    try {
     chatSocket.close();
    } catch (Exception ed) {
    }
   }
   if (isOnChess || isGameConnected) {
    try {
     chesspad.chessSocket.close();
    } catch (Exception ee) {
    }
   }
   System.exit(0);

  }
  //如果点击的是“加入游戏”按钮,则先判断选定的加入的目标是否有效。
  //如果选定的目标为空或正在下棋或为其本身,则认为目标无效。
  if (e.getSource() == controlpad.joinGameButton) {
   String selectedUser = userpad.userList.getSelectedItem();
   if (selectedUser == null || selectedUser.startsWith("[inchess]")
     || selectedUser.equals(chessClientName)) {
    chesspad.statusText.setText("必须先选定一个有效用户");
   } else {
    try {
     //如果未建立与服务器的连接,创建连接,设定用户的当前状态。
     //此外还要对按钮作一些处理,将“创建连接”按钮和“加入游戏按钮”设为不可用。
     if (!isGameConnected) {
      if (chesspad
        .connectServer(chesspad.host, chesspad.port)) {
       isGameConnected = true;
       isOnChess = true;
       isClient = true;
       controlpad.creatGameButton.setEnabled(false);
       controlpad.joinGameButton.setEnabled(false);
       controlpad.cancelGameButton.setEnabled(true);
       chesspad.chessthread.sendMessage("/joingame "
         + userpad.userList.getSelectedItem() + " "
         + chessClientName);
      }
     }
     //如果已建立连接,省去建立连接的操作。
     else {
      isOnChess = true;
      isClient = true;
      controlpad.creatGameButton.setEnabled(false);
      controlpad.joinGameButton.setEnabled(false);
      controlpad.cancelGameButton.setEnabled(true);
      chesspad.chessthread.sendMessage("/joingame "
        + userpad.userList.getSelectedItem() + " "
        + chessClientName);
     }

    } catch (Exception ee) {
     isGameConnected = false;
     isOnChess = false;
     isClient = false;
     controlpad.creatGameButton.setEnabled(true);
     controlpad.joinGameButton.setEnabled(true);
     controlpad.cancelGameButton.setEnabled(false);
     chatpad.chatLineArea
       .setText("chesspad.connectServer无法连接 /n" + ee);
    }

   }
  }
  //如果点击的是“创建游戏”按钮,设定用户状态、按钮状态,然后与服务器通讯。
  if (e.getSource() == controlpad.creatGameButton) {
   try {
    //未建立连接时的操作。
    if (!isGameConnected) {
     if (chesspad.connectServer(chesspad.host, chesspad.port)) {
      isGameConnected = true;
      isOnChess = true;
      isServer = true;
      controlpad.creatGameButton.setEnabled(false);
      controlpad.joinGameButton.setEnabled(false);
      controlpad.cancelGameButton.setEnabled(true);
      chesspad.chessthread.sendMessage("/creatgame "
        + "[inchess]" + chessClientName);
     }
    }
    //建立连接时的操作。
    else {
     isOnChess = true;
     isServer = true;
     controlpad.creatGameButton.setEnabled(false);
     controlpad.joinGameButton.setEnabled(false);
     controlpad.cancelGameButton.setEnabled(true);
     chesspad.chessthread.sendMessage("/creatgame "
       + "[inchess]" + chessClientName);
    }
   } catch (Exception ec) {
    isGameConnected = false;
    isOnChess = false;
    isServer = false;
    controlpad.creatGameButton.setEnabled(true);
    controlpad.joinGameButton.setEnabled(true);
    controlpad.cancelGameButton.setEnabled(false);
    ec.printStackTrace();
    chatpad.chatLineArea.setText("chesspad.connectServer无法连接 /n"
      + ec);
   }

  }
  //如果点击的是“取消游戏”按钮,同样要修改按钮状态。
  if (e.getSource() == controlpad.cancelGameButton) {
   //如果棋局正在进行,判定退出游戏的一方输
   if (isOnChess) {
    chesspad.chessthread.sendMessage("/giveup " + chessClientName);
    chesspad.chessVictory(-1 * chesspad.chessColor);
    controlpad.creatGameButton.setEnabled(true);
    controlpad.joinGameButton.setEnabled(true);
    controlpad.cancelGameButton.setEnabled(false);
    chesspad.statusText.setText("请建立游戏或者加入游戏");
   }
   if (!isOnChess) {
    controlpad.creatGameButton.setEnabled(true);
    controlpad.joinGameButton.setEnabled(true);
    controlpad.cancelGameButton.setEnabled(false);
    chesspad.statusText.setText("请建立游戏或者加入游戏");
   }
   isClient = isServer = false;
  }
  //如果点击的是“改变颜色”按钮,则弹出“颜色选择”对话框供用户选择界面颜色。
  if (e.getSource() == controlpad.colorChangeButton) {
   JColorChooser nextColor = new JColorChooser();
   Color selectedColor = JColorChooser.showDialog(this, "选择背景颜色",
     Color.BLACK);
   chesspad.setBackground(selectedColor);
   inputpad.setBackground(selectedColor);
   controlpad.setBackground(selectedColor);
   chesspad.statusLabel.setBackground(selectedColor);
   inputpad.chatLabel.setBackground(selectedColor);
   controlpad.IPlabel.setBackground(selectedColor);
   westPanel.setBackground(selectedColor);
   centerPanel.setBackground(selectedColor);
   southPanel.setBackground(selectedColor);
  }

 }

 /**
  * 键盘监听器,响应“回车按下”事件.
  */
 public void keyPressed(KeyEvent e) {
  TextField inputWords = (TextField) e.getSource();
  //如果选择向所有人发消息,则将所发消息直接发给服务器
  if (e.getKeyCode() == KeyEvent.VK_ENTER) {
   if (inputpad.userChoice.getSelectedItem().equals("所有人")) {
    try {
     out.writeUTF(inputWords.getText());
     inputWords.setText("");
    } catch (Exception ea) {
     chatpad.chatLineArea
       .setText("chessClient:KeyPressed无法连接,建议重新连接 /n");
     userpad.userList.removeAll();
     inputpad.userChoice.removeAll();
     inputWords.setText("");
     controlpad.connectButton.setEnabled(true);
    }
   }
   //如果选择向一个人发消息,则将所发消息封装成一定格式发给服务器
   else {
    try {
     out.writeUTF("/" + inputpad.userChoice.getSelectedItem()
       + " " + inputWords.getText());
     inputWords.setText("");
    } catch (Exception ea) {
     chatpad.chatLineArea
       .setText("chessClient:KeyPressed无法连接,建议重新连接 /n");
     userpad.userList.removeAll();
     inputpad.userChoice.removeAll();
     inputWords.setText("");
     controlpad.connectButton.setEnabled(true);
    }
   }
  }

 }

 public void keyTyped(KeyEvent e) {
 }

 public void keyReleased(KeyEvent e) {
 }

 public static void main(String args[]) {
  chessClient chessClient = new chessClient();
 }
}
/**
 * 客户端线程
 */

class clientThread extends Thread {
 chessClient chessclient;

 clientThread(chessClient chessclient) {
  this.chessclient = chessclient;
 }

 /**
  * 客户端线程对接收到的信息进行处理的函数
  */
 public void acceptMessage(String recMessage) {
  if (recMessage.startsWith("/userlist ")) {
   //如果接收到的信息以"/userlist "开头,将其后的用户名提取出来,添加到
   //输入信息Panel左边的用户列表中。
   StringTokenizer userToken = new StringTokenizer(recMessage, " ");
   int userNumber = 0;

   chessclient.userpad.userList.removeAll();
   chessclient.inputpad.userChoice.removeAll();
   chessclient.inputpad.userChoice.addItem("所有人");
   while (userToken.hasMoreTokens()) {
    String user = (String) userToken.nextToken(" ");
    if (userNumber > 0 && !user.startsWith("[inchess]")) {
     chessclient.userpad.userList.add(user);
     chessclient.inputpad.userChoice.addItem(user);
    }

    userNumber++;
   }
   chessclient.inputpad.userChoice.select("所有人");
  }
  //如果如果接收到的信息以"/yourname "开头,将用户名显示在客户端对话框标题栏。
  else if (recMessage.startsWith("/yourname ")) {
   chessclient.chessClientName = recMessage.substring(10);
   chessclient.setTitle("五子棋客户端 " + "当前用户名:"
     + chessclient.chessClientName);
  }
  //如果如果接收到的信息以"/reject"开头,在状态栏显示拒绝加入游戏。
  else if (recMessage.equals("/reject")) {
   try {
    chessclient.chesspad.statusText.setText("不能加入游戏");
    chessclient.controlpad.cancelGameButton.setEnabled(false);
    chessclient.controlpad.joinGameButton.setEnabled(true);
    chessclient.controlpad.creatGameButton.setEnabled(true);
   } catch (Exception ef) {
    chessclient.chatpad.chatLineArea
      .setText("chessclient.chesspad.chessSocket.close无法关闭");
   }
   chessclient.controlpad.joinGameButton.setEnabled(true);
  }
  //如果如果接收到的信息以"/peer"开头,则记下对方的名字,然后进入等待状态
  else if (recMessage.startsWith("/peer ")) {
   chessclient.chesspad.chessPeerName = recMessage.substring(6);
   if (chessclient.isServer) {
    chessclient.chesspad.chessColor = 1;
    chessclient.chesspad.isMouseEnabled = true;
    chessclient.chesspad.statusText.setText("请黑棋下子");
   } else if (chessclient.isClient) {
    chessclient.chesspad.chessColor = -1;
    chessclient.chesspad.statusText.setText("已加入游戏,等待对方下子...");
   }

  } else if (recMessage.equals("/youwin")) {
   chessclient.isOnChess = false;
   chessclient.chesspad.chessVictory(chessclient.chesspad.chessColor);
   chessclient.chesspad.statusText.setText("对方退出,请点放弃游戏退出连接");
   chessclient.chesspad.isMouseEnabled = false;
  } else if (recMessage.equals("/OK")) {
   chessclient.chesspad.statusText.setText("创建游戏成功,等待别人加入...");
  } else if (recMessage.equals("/error")) {
   chessclient.chatpad.chatLineArea.append("传输错误:请退出程序,重新加入 /n");
  } else {
   chessclient.chatpad.chatLineArea.append(recMessage + "/n");
   chessclient.chatpad.chatLineArea
     .setCaretPosition(chessclient.chatpad.chatLineArea
       .getText().length());
  }
 }

 public void run() {
  String message = "";
  try {
   while (true) {
    message = chessclient.in.readUTF();
    acceptMessage(message);
   }
  } catch (IOException es) {
  }
 }

}

 

chatPad.java

 

package com.fivechess.chessface;

import java.awt.BorderLayout;
import java.awt.Panel;
import java.awt.TextArea;

/**
 * @author wufenghanren
 * 聊天信息Panel。Panel上的文本域可以显示用户聊天信息。
 */
public class chatPad extends Panel {
 public TextArea chatLineArea = new TextArea("", 18, 30,
   TextArea.SCROLLBARS_VERTICAL_ONLY);

 public chatPad() {
  setLayout(new BorderLayout());

  add(chatLineArea, BorderLayout.CENTER);
 }

}

 

chessPad.java

 package com.fivechess.chessface;
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.net.*;


/**
 * @author wufenghanren
 * 显示棋盘的Panel。此Panel实现了鼠标监听器
 */
public class chessPad extends Panel implements MouseListener {
 public int chessPoint_x = -1, chessPoint_y = -1, chessColor = 1;

 int chessBlack_x[] = new int[200];//黑子的x坐标

 int chessBlack_y[] = new int[200];//黑子的y坐标

 int chessWhite_x[] = new int[200];//白子的x坐标

 int chessWhite_y[] = new int[200];//白子的y坐标

 int chessBlackCount = 0, chessWhiteCount = 0;

 int chessBlackWin = 0, chessWhiteWin = 0;

 public boolean isMouseEnabled = false, isWin = false, isInGame = false;

 public Label statusLabel = new Label("客户端状态");

 public TextField statusText = new TextField("请先连接服务器");//显示客户端状态的文本框

 public Socket chessSocket;

 DataInputStream inData;

 DataOutputStream outData;

 public String chessSelfName = null;//己方的名字

 public String chessPeerName = null;//对方的名字

 public String host = null;

 public int port = 4331;

 public chessThread chessthread = new chessThread(this);

 /**
  * 棋盘Panel的构造函数
  */
 public chessPad() {
  setSize(440, 440);
  setLayout(null);
  setBackground(new Color(204, 204, 204));
  addMouseListener(this);
  add(statusLabel);
  statusLabel.setBounds(30, 5, 70, 24);
  add(statusText);
  statusText.setBounds(100, 5, 300, 24);
  statusText.setEditable(false);
 }

 /**
  * 和服务器通信的函数
  */
 public boolean connectServer(String ServerIP, int ServerPort)
   throws Exception {
  try {
   //利用参数创建一个Socket的实例来完成和服务器之间的信息交换
   chessSocket = new Socket(ServerIP, ServerPort);
   inData = new DataInputStream(chessSocket.getInputStream());
   outData = new DataOutputStream(chessSocket.getOutputStream());
   chessthread.start();
   return true;
  } catch (IOException ex) {
   statusText.setText("chessPad:connectServer:无法连接 /n");
  }
  return false;
 }

 /**
  * 一方获胜时的对棋局的处理
  */
 public void chessVictory(int chessColorWin) {
  //清除所有的棋子
  this.removeAll();
  //将保存所有黑棋和白棋的位置坐标的数组清空,为西一盘棋做准备。
  for (int i = 0; i <= chessBlackCount; i++) {
   chessBlack_x[i] = 0;
   chessBlack_y[i] = 0;
  }
  for (int i = 0; i <= chessWhiteCount; i++) {
   chessWhite_x[i] = 0;
   chessWhite_y[i] = 0;
  }
  chessBlackCount = 0;
  chessWhiteCount = 0;
  add(statusText);
  statusText.setBounds(40, 5, 360, 24);
  //如果黑棋获胜,计算双方获胜盘数,将双方的战绩比在状态文本框显示出来。
  if (chessColorWin == 1) {
   chessBlackWin++;
   statusText.setText("黑棋胜,黑:白为" + chessBlackWin + ":" + chessWhiteWin
     + ",重新开局,等待白棋下子...");
  }
  //白棋获胜,同上。
  else if (chessColorWin == -1) {
   chessWhiteWin++;
   statusText.setText("白棋胜,黑:白为" + chessBlackWin + ":" + chessWhiteWin
     + ",重新开局,等待黑棋下子...");
  }
 }

 /**
  * 将各个棋子的坐标保存在数组里
  */
 public void getLocation(int a, int b, int color) {

  if (color == 1) {
   chessBlack_x[chessBlackCount] = a * 20;
   chessBlack_y[chessBlackCount] = b * 20;
   chessBlackCount++;
  } else if (color == -1) {
   chessWhite_x[chessWhiteCount] = a * 20;
   chessWhite_y[chessWhiteCount] = b * 20;
   chessWhiteCount++;
  }
 }

 /**
  * 依据五子棋的行棋规则判断某方获胜
  */
 public boolean checkWin(int a, int b, int checkColor) {
  int step = 1, chessLink = 1, chessLinkTest = 1, chessCompare = 0;
  if (checkColor == 1) {
   chessLink = 1;
   for (step = 1; step <= 4; step++) {
    for (chessCompare = 0; chessCompare <= chessBlackCount; chessCompare++) {
     if (((a + step) * 20 == chessBlack_x[chessCompare])
       && ((b * 20) == chessBlack_y[chessCompare])) {
      chessLink = chessLink + 1;
      if (chessLink == 5) {
       return (true);
      }
     }
    }
    if (chessLink == (chessLinkTest + 1))
     chessLinkTest++;
    else
     break;
   }
   for (step = 1; step <= 4; step++) {
    for (chessCompare = 0; chessCompare <= chessBlackCount; chessCompare++) {
     if (((a - step) * 20 == chessBlack_x[chessCompare])
       && (b * 20 == chessBlack_y[chessCompare])) {
      chessLink++;
      if (chessLink == 5) {
       return (true);
      }
     }
    }
    if (chessLink == (chessLinkTest + 1))
     chessLinkTest++;
    else
     break;
   }
   chessLink = 1;
   chessLinkTest = 1;
   for (step = 1; step <= 4; step++) {
    for (chessCompare = 0; chessCompare <= chessBlackCount; chessCompare++) {
     if ((a * 20 == chessBlack_x[chessCompare])
       && ((b + step) * 20 == chessBlack_y[chessCompare])) {
      chessLink++;
      if (chessLink == 5) {
       return (true);
      }
     }
    }
    if (chessLink == (chessLinkTest + 1))
     chessLinkTest++;
    else
     break;
   }
   for (step = 1; step <= 4; step++) {
    for (chessCompare = 0; chessCompare <= chessBlackCount; chessCompare++) {
     if ((a * 20 == chessBlack_x[chessCompare])
       && ((b - step) * 20 == chessBlack_y[chessCompare])) {
      chessLink++;
      if (chessLink == 5) {
       return (true);
      }
     }
    }
    if (chessLink == (chessLinkTest + 1))
     chessLinkTest++;
    else
     break;
   }
   chessLink = 1;
   chessLinkTest = 1;
   for (step = 1; step <= 4; step++) {
    for (chessCompare = 0; chessCompare <= chessBlackCount; chessCompare++) {
     if (((a - step) * 20 == chessBlack_x[chessCompare])
       && ((b + step) * 20 == chessBlack_y[chessCompare])) {
      chessLink++;
      if (chessLink == 5) {
       return (true);
      }
     }
    }
    if (chessLink == (chessLinkTest + 1))
     chessLinkTest++;
    else
     break;
   }
   for (step = 1; step <= 4; step++) {
    for (chessCompare = 0; chessCompare <= chessBlackCount; chessCompare++) {
     if (((a + step) * 20 == chessBlack_x[chessCompare])
       && ((b - step) * 20 == chessBlack_y[chessCompare])) {
      chessLink++;
      if (chessLink == 5) {
       return (true);
      }
     }
    }
    if (chessLink == (chessLinkTest + 1))
     chessLinkTest++;
    else
     break;
   }
   chessLink = 1;
   chessLinkTest = 1;
   for (step = 1; step <= 4; step++) {
    for (chessCompare = 0; chessCompare <= chessBlackCount; chessCompare++) {
     if (((a + step) * 20 == chessBlack_x[chessCompare])
       && ((b + step) * 20 == chessBlack_y[chessCompare])) {
      chessLink++;
      if (chessLink == 5) {
       return (true);
      }
     }
    }
    if (chessLink == (chessLinkTest + 1))
     chessLinkTest++;
    else
     break;
   }
   for (step = 1; step <= 4; step++) {
    for (chessCompare = 0; chessCompare <= chessBlackCount; chessCompare++) {
     if (((a - step) * 20 == chessBlack_x[chessCompare])
       && ((b - step) * 20 == chessBlack_y[chessCompare])) {
      chessLink++;
      if (chessLink == 5) {
       return (true);
      }
     }
    }
    if (chessLink == (chessLinkTest + 1))
     chessLinkTest++;
    else
     break;
   }
  } else if (checkColor == -1) {
   chessLink = 1;
   for (step = 1; step <= 4; step++) {
    for (chessCompare = 0; chessCompare <= chessWhiteCount; chessCompare++) {
     if (((a + step) * 20 == chessWhite_x[chessCompare])
       && (b * 20 == chessWhite_y[chessCompare])) {
      chessLink++;
      if (chessLink == 5) {
       return (true);
      }
     }
    }
    if (chessLink == (chessLinkTest + 1))
     chessLinkTest++;
    else
     break;
   }
   for (step = 1; step <= 4; step++) {
    for (chessCompare = 0; chessCompare <= chessWhiteCount; chessCompare++) {
     if (((a - step) * 20 == chessWhite_x[chessCompare])
       && (b * 20 == chessWhite_y[chessCompare])) {
      chessLink++;
      if (chessLink == 5) {
       return (true);
      }
     }
    }
    if (chessLink == (chessLinkTest + 1))
     chessLinkTest++;
    else
     break;
   }
   chessLink = 1;
   chessLinkTest = 1;
   for (step = 1; step <= 4; step++) {
    for (chessCompare = 0; chessCompare <= chessWhiteCount; chessCompare++) {
     if ((a * 20 == chessWhite_x[chessCompare])
       && ((b + step) * 20 == chessWhite_y[chessCompare])) {
      chessLink++;
      if (chessLink == 5) {
       return (true);
      }
     }
    }
    if (chessLink == (chessLinkTest + 1))
     chessLinkTest++;
    else
     break;
   }
   for (step = 1; step <= 4; step++) {
    for (chessCompare = 0; chessCompare <= chessWhiteCount; chessCompare++) {
     if ((a * 20 == chessWhite_x[chessCompare])
       && ((b - step) * 20 == chessWhite_y[chessCompare])) {
      chessLink++;
      if (chessLink == 5) {
       return (true);
      }
     }
    }
    if (chessLink == (chessLinkTest + 1))
     chessLinkTest++;
    else
     break;
   }
   chessLink = 1;
   chessLinkTest = 1;
   for (step = 1; step <= 4; step++) {
    for (chessCompare = 0; chessCompare <= chessWhiteCount; chessCompare++) {
     if (((a - step) * 20 == chessWhite_x[chessCompare])
       && ((b + step) * 20 == chessWhite_y[chessCompare])) {
      chessLink++;
      if (chessLink == 5) {
       return (true);
      }
     }
    }
    if (chessLink == (chessLinkTest + 1))
     chessLinkTest++;
    else
     break;
   }
   for (step = 1; step <= 4; step++) {
    for (chessCompare = 0; chessCompare <= chessWhiteCount; chessCompare++) {
     if (((a + step) * 20 == chessWhite_x[chessCompare])
       && ((b - step) * 20 == chessWhite_y[chessCompare])) {
      chessLink++;
      if (chessLink == 5) {
       return (true);
      }
     }
    }
    if (chessLink == (chessLinkTest + 1))
     chessLinkTest++;
    else
     break;
   }
   chessLink = 1;
   chessLinkTest = 1;
   for (step = 1; step <= 4; step++) {
    for (chessCompare = 0; chessCompare <= chessWhiteCount; chessCompare++) {
     if (((a + step) * 20 == chessWhite_x[chessCompare])
       && ((b + step) * 20 == chessWhite_y[chessCompare])) {
      chessLink++;
      if (chessLink == 5) {
       return (true);
      }
     }
    }
    if (chessLink == (chessLinkTest + 1))
     chessLinkTest++;
    else
     break;
   }
   for (step = 1; step <= 4; step++) {
    for (chessCompare = 0; chessCompare <= chessWhiteCount; chessCompare++) {
     if (((a - step) * 20 == chessWhite_x[chessCompare])
       && ((b - step) * 20 == chessWhite_y[chessCompare])) {
      chessLink++;
      if (chessLink == 5) {
       return (true);
      }
     }
    }
    if (chessLink == (chessLinkTest + 1))
     chessLinkTest++;
    else
     break;
   }
  }
  return (false);
 }

 /**
  * 绘制棋盘,将棋盘绘制成19*19的个子并将棋盘上应有的五个点绘制上去。
  */
 public void paint(Graphics g) {
  for (int i = 40; i <= 380; i = i + 20) {
   g.drawLine(40, i, 400, i);
  }
  g.drawLine(40, 400, 400, 400);
  for (int j = 40; j <= 380; j = j + 20) {
   g.drawLine(j, 40, j, 400);
  }
  g.drawLine(400, 40, 400, 400);
  g.fillOval(97, 97, 6, 6);
  g.fillOval(337, 97, 6, 6);
  g.fillOval(97, 337, 6, 6);
  g.fillOval(337, 337, 6, 6);
  g.fillOval(217, 217, 6, 6);
 }

 /**
  * 落子的时候绘制棋子
  */
 public void chessPaint(int chessPoint_a, int chessPoint_b, int color) {
  chessPoint_black chesspoint_black = new chessPoint_black(this);
  chessPoint_white chesspoint_white = new chessPoint_white(this);

  if (color == 1 && isMouseEnabled) {
   //当黑子落子时,记下此子的位置
   getLocation(chessPoint_a, chessPoint_b, color);
   //判断是否获胜
   isWin = checkWin(chessPoint_a, chessPoint_b, color);
   if (isWin == false) {
    //如果没有获胜,向对方发送落子信息,并绘制棋子
    chessthread.sendMessage("/" + chessPeerName + " /chess "
      + chessPoint_a + " " + chessPoint_b + " " + color);
    this.add(chesspoint_black);
    chesspoint_black.setBounds(chessPoint_a * 20 - 7,
      chessPoint_b * 20 - 7, 16, 16);
    //在状态文本框显示行棋信息
    statusText.setText("黑(第" + chessBlackCount + "步)"
      + chessPoint_a + " " + chessPoint_b + ",请白棋下子");
    isMouseEnabled = false;
   } else {
    //如果获胜,直接调用chessVictory完成后续工作
    chessthread.sendMessage("/" + chessPeerName + " /chess "
      + chessPoint_a + " " + chessPoint_b + " " + color);
    this.add(chesspoint_black);
    chesspoint_black.setBounds(chessPoint_a * 20 - 7,
      chessPoint_b * 20 - 7, 16, 16);
    chessVictory(1);
    isMouseEnabled = false;
   }
  }
  //白棋落子,同黑棋类似处理
  else if (color == -1 && isMouseEnabled) {
   getLocation(chessPoint_a, chessPoint_b, color);
   isWin = checkWin(chessPoint_a, chessPoint_b, color);
   if (isWin == false) {
    chessthread.sendMessage("/" + chessPeerName + " /chess "
      + chessPoint_a + " " + chessPoint_b + " " + color);
    this.add(chesspoint_white);
    chesspoint_white.setBounds(chessPoint_a * 20 - 7,
      chessPoint_b * 20 - 7, 16, 16);
    statusText.setText("白(第" + chessWhiteCount + "步)"
      + chessPoint_a + " " + chessPoint_b + ",请黑棋下子");
    isMouseEnabled = false;
   } else {
    chessthread.sendMessage("/" + chessPeerName + " /chess "
      + chessPoint_a + " " + chessPoint_b + " " + color);
    this.add(chesspoint_white);
    chesspoint_white.setBounds(chessPoint_a * 20 - 7,
      chessPoint_b * 20 - 7, 16, 16);
    chessVictory(-1);
    isMouseEnabled = false;
   }
  }
 }

 /**
  * 落子时在对方客户端绘制棋子。 对方接受到发送来的落子信息,调用此函数绘制棋子,显示落子状态等等
  */
 public void netChessPaint(int chessPoint_a, int chessPoint_b, int color) {
  chessPoint_black chesspoint_black = new chessPoint_black(this);
  chessPoint_white chesspoint_white = new chessPoint_white(this);
  getLocation(chessPoint_a, chessPoint_b, color);
  if (color == 1) {
   isWin = checkWin(chessPoint_a, chessPoint_b, color);
   if (isWin == false) {

    this.add(chesspoint_black);
    chesspoint_black.setBounds(chessPoint_a * 20 - 7,
      chessPoint_b * 20 - 7, 16, 16);
    statusText.setText("黑(第" + chessBlackCount + "步)"
      + chessPoint_a + " " + chessPoint_b + ",请白棋下子");
    isMouseEnabled = true;
   } else {
    this.add(chesspoint_black);
    chesspoint_black.setBounds(chessPoint_a * 20 - 7,
      chessPoint_b * 20 - 7, 16, 16);
    chessVictory(1);
    isMouseEnabled = true;
   }
  } else if (color == -1) {
   isWin = checkWin(chessPoint_a, chessPoint_b, color);
   if (isWin == false) {
    this.add(chesspoint_white);
    chesspoint_white.setBounds(chessPoint_a * 20 - 7,
      chessPoint_b * 20 - 7, 16, 16);
    statusText.setText("白(第" + chessWhiteCount + "步)"
      + chessPoint_a + " " + chessPoint_b + ",请黑棋下子");
    isMouseEnabled = true;
   } else {
    chessthread.sendMessage("/" + chessPeerName + " /victory "
      + color);
    this.add(chesspoint_white);
    chesspoint_white.setBounds(chessPoint_a * 20 - 7,
      chessPoint_b * 20 - 7, 16, 16);
    chessVictory(-1);
    isMouseEnabled = true;
   }
  }
 }

 /**
  * 当鼠标按下时响应的动作。记下当前鼠标点击的位置,即当前落子的位置。
  */
 public void mousePressed(MouseEvent e) {
  if (e.getModifiers() == InputEvent.BUTTON1_MASK) {
   chessPoint_x = (int) e.getX();
   chessPoint_y = (int) e.getY();
   int a = (chessPoint_x + 10) / 20, b = (chessPoint_y + 10) / 20;
   if (chessPoint_x / 20 < 2 || chessPoint_y / 20 < 2
     || chessPoint_x / 20 > 19 || chessPoint_y / 20 > 19) {
   } else {
    chessPaint(a, b, chessColor);
   }
  }
 }

 public void mouseReleased(MouseEvent e) {
 }

 public void mouseEntered(MouseEvent e) {
 }

 public void mouseExited(MouseEvent e) {
 }

 public void mouseClicked(MouseEvent e) {
 }

}
/**
 * 表示黑子的类
 */

class chessPoint_black extends Canvas {
 chessPad chesspad = null;

 chessPoint_black(chessPad p) {
  setSize(20, 20);
  chesspad = p;
 }

 public void paint(Graphics g) {
  g.setColor(Color.black);
  g.fillOval(0, 0, 14, 14);
 }

}
/**
 * 表示白子的类
 */

class chessPoint_white extends Canvas {
 chessPad chesspad = null;

 chessPoint_white(chessPad p) {
  setSize(20, 20);

  chesspad = p;
 }

 public void paint(Graphics g) {
  g.setColor(Color.white);
  g.fillOval(0, 0, 14, 14);
 }

}

 

 

 

chessThread.java


package com.fivechess.chessface;

import java.io.IOException;
import java.util.StringTokenizer;

/**
 * @author wufenghanren
 */
public class chessThread extends Thread {
 chessPad chesspad;

 public chessThread(chessPad chesspad) {
  this.chesspad = chesspad;
 }

 /**
  * 发送消息
  */
 public void sendMessage(String sndMessage) {
  try {
   chesspad.outData.writeUTF(sndMessage);
  } catch (Exception ea) {
   System.out.println("chessThread.sendMessage:" + ea);
  }
 }

 /**
  * 接收消息
  */
 public void acceptMessage(String recMessage) {
  //如果收到的消息以“/chess”开头,将其中的坐标信息和颜色信息提取出来
  if (recMessage.startsWith("/chess ")) {
   StringTokenizer userToken = new StringTokenizer(recMessage, " ");
   String chessToken;
   String[] chessOpt = { "-1", "-1", "0" };
   int chessOptNum = 0;
   //使用Tokenizer将空格分隔的字符串分成三段
   while (userToken.hasMoreTokens()) {
    chessToken = (String) userToken.nextToken(" ");
    if (chessOptNum >= 1 && chessOptNum <= 3) {
     chessOpt[chessOptNum - 1] = chessToken;

    }
    chessOptNum++;
   }
   //将己方的走棋信息如棋子摆放的位置、棋子的颜色为参数,使用netChessPaint函数
   //是对方客户端也看到己方的落子位置。
   chesspad.netChessPaint(Integer.parseInt(chessOpt[0]), Integer
     .parseInt(chessOpt[1]), Integer.parseInt(chessOpt[2]));

  } else if (recMessage.startsWith("/yourname ")) {
   chesspad.chessSelfName = recMessage.substring(10);
  } else if (recMessage.equals("/error")) {
   chesspad.statusText.setText("错误:没有这个用户,请退出程序,重新加入");
  }
 }

 public void run() {
  String message = "";
  try {
   while (true) {
    message = chesspad.inData.readUTF();
    acceptMessage(message);
   }
  } catch (IOException es) {
  }
 }

}

 

controlPad.java

 
package com.fivechess.chessface;

import java.awt.Button;
import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.Label;
import java.awt.Panel;
import java.awt.TextField;

/**
 * @author wufenghanren
 * 控制Panel。此Panel上的按钮如其名,完成相应的功能。
 */
public class controlPad extends Panel {
 public Label IPlabel = new Label("服务器IP:", Label.LEFT);

 public TextField inputIP = new TextField("localhost", 10);

 public Button connectButton = new Button("连接主机");

 public Button creatGameButton = new Button("建立游戏");

 public Button joinGameButton = new Button("加入游戏");

 public Button cancelGameButton = new Button("放弃游戏");

 public Button colorChangeButton = new Button("选择界面颜色");

 public Button exitGameButton = new Button("关闭程序");
    //构造函数,负责Panel的初始布局。
 public controlPad() {
  setLayout(new FlowLayout(FlowLayout.LEFT));
  setBackground(new Color(204,204,204));

  add(IPlabel);
  add(inputIP);
  add(connectButton);
  add(creatGameButton);
  add(joinGameButton);
  add(cancelGameButton);
  add(colorChangeButton);
  add(exitGameButton);
 }

}

 

inputPad.java

package com.fivechess.chessface;

import java.awt.Choice;
import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.Label;
import java.awt.Panel;
import java.awt.TextField;

/**
 * @author wufenghanren
 * 输入信息Panel。Panel左边的下拉列表中列出了所有用户的名字。
 * 右边的文本框可以输入聊天信息,点击回车信息被发送。
 * 此外还可以 在文本框中输入命令如changename、list等。
 */

public class inputPad extends Panel {
 public TextField inputWords = new TextField("点击回车发送信息", 20);

 public Choice userChoice = new Choice();

 public Label chatLabel = new Label("输入发送信息:");

 public inputPad() {
  setLayout(new FlowLayout(FlowLayout.LEFT));
  setBackground(new Color(204, 204, 204));
  for (int i = 0; i < 30; i++) {
   userChoice.addItem(i + "." + "当前暂无用户");
  }
  userChoice.setSize(60, 24);
  add(userChoice);
  add(chatLabel);
  add(inputWords);
 }

}

 

userPad.java

  
package com.fivechess.chessface;

import java.awt.*;

/**
 * @author wufenghanren
 * 用户列表Panel。此Panel维护一个服务器的当前用户列表,
 * 所有的用户名都将显示在列表中。
 */
public class userPad extends Panel {
 public List userList = new List(10);

 public userPad() {
  setLayout(new BorderLayout());

  for (int i = 0; i < 30; i++) {
   userList.add(i + "." + "当前暂无用户");
  }
  add(userList, BorderLayout.CENTER);

 }
}

 

 

 

 

 

 

你可能感兴趣的:(Java实用功能源码集锦)