Java实现五子棋网络版

作者:OnePointC 时间:2022-05-06 04:11:29 

本文实例为大家分享了Java实现五子棋网络版的具体代码,供大家参考,具体内容如下

需求分析:

对于网络五子棋而言,在普通五子棋的基础上需要添加以下功能:

1.拥有服务器端和客户端,用户通过客户端登录服务器后可与其他登录的用户进行对弈

2.服务器支持多组用户同时进行对弈

3.用户可以在服务器上创建新游戏或加入已创建的游戏

4.用户在下棋的时候可以进行聊天交流

由上可以知道需要实现的功能:

·提供服务器和客户端的功能

·服务器将监听客户端的登录情况并允许多个客户端进行登录

·用户通过客户端可以登录服务器,之后可以看到服务器当前在线的其他用户,并与他们进行聊天等

·用户登录服务器后,可以创建新的五子棋游戏或加入已创建的五子棋游戏

·用户通过客户端可以像普通五子棋那样与其他用户对弈

根据功能将网络五子棋分为4个模块:即用户面板模块、棋盘面板模块、五子棋服务器模块、五子棋客户端模块

Java实现五子棋网络版

下面我们开始进行编译用户面板模块:

1.开发用户列表面板


import java.awt.*;

/**
* Created by Administrator on 2016/11/21.
*/
//初始状态下将添加10个名称为“无用户“的信息到列表中,说明服务器最多支持10个用户同时在线
//该列表被添加到面板中,使用“BorderLayout”布局格式
public class UserListPad extends Panel{
public List userList=new List(10);

public UserListPad(){
setLayout(new BorderLayout());
for(int i=0;i<10;i++){
 userList.add(i+"."+"无用户");
}
add(userList,BorderLayout.CENTER);
}
}

2.开发用户聊天面板


import javax.swing.*;
import java.awt.*;

/**
* Created by Administrator on 2016/11/21.
*/
//聊天面板为一个TextArea视图控件,拥有一个垂直方向的滚动条。
//该TextArea被添加到面板中,使用“BorderLayout”布局格式。
public class UserChatPad extends JPanel{
public JTextArea chatTextArea=new JTextArea("命令区域",18,20);
public UserChatPad(){
setLayout(new BorderLayout());
chatTextArea.setAutoscrolls(true);
chatTextArea.setLineWrap(true);
add(chatTextArea,BorderLayout.CENTER);
}
}

3.开发用户输入面板


import javax.swing.*;
import java.awt.*;

/**
* Created by Administrator on 2016/11/21.
*/
//面板包含两个视图控件
//contentInpitted为TextField控件,用户可以在其中输入聊天信息
public class UserInputPad extends JPanel{
public JTextField contentInputted = new JTextField("",26);
public JComboBox userChoice = new JComboBox();

public UserInputPad(){
setLayout(new FlowLayout(FlowLayout.LEFT));
for(int i=0;i<50;i++){
 userChoice.addItem(i+"."+"无用户");
}
userChoice.setSize(60,24);
add(userChoice);
add(contentInputted);
}
}

4.开发用户操作面板


import javax.swing.*;
import java.awt.*;

/**
* Created by Administrator on 2016/11/21.
*/
public class UserControlPad extends JPanel {
public JLabel ipLabel = new JLabel("IP",JLabel.LEFT);
public JTextField ipInputted = new JTextField("localhost",10);
public JButton connectButton = new JButton("连接到服务器");
public JButton createButton = new JButton("创建游戏");
public JButton joinButton = new JButton("加入游戏");
public JButton cancelButton = new JButton("放弃游戏");
public JButton exitButton = new JButton("退出游戏");
public UserControlPad(){
setLayout(new FlowLayout(FlowLayout.LEFT));
setBackground(Color.LIGHT_GRAY);
add(ipLabel);
add(ipInputted);
add(connectButton);
add(createButton);
add(joinButton);
add(cancelButton);
add(exitButton);
}
}

下面开始开发棋盘面板模块

1.开发黑棋类


import java.awt.*;

/**
* Created by Administrator on 2016/11/21.
*/
public class FIRPointBlack extends Canvas {
FIRPad padBelonged; // 黑棋所属的棋盘

public FIRPointBlack(FIRPad padBelonged)
{
setSize(20, 20); // 设置棋子大小
this.padBelonged = padBelonged;
}

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

2.开发白棋类


import java.awt.*;

/**
* Created by Administrator on 2016/11/21.
*/
public class FIRPointWhite extends Canvas{
FIRPad padBelonged; // 白棋所属的棋盘

public FIRPointWhite(FIRPad padBelonged)
{
setSize(20, 20);
this.padBelonged = padBelonged;
}

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

3.开发棋盘面板


import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.net.*;

import javax.swing.JTextField;

/**
* Created by Administrator on 2016/11/21.
*/
public class FIRPad extends Panel implements MouseListener,ActionListener{
// 鼠标是否能使用
public boolean isMouseEnabled = false;
// 是否胜利
public boolean isWinned = false;
// 是否在下棋中
public boolean isGaming = false;
// 棋子的x轴坐标位
public int chessX_POS = -1;
// 棋子的y轴坐标位
public int chessY_POS = -1;
// 棋子的颜色
public int chessColor = 1;
// 黑棋x轴坐标位数组
public int chessBlack_XPOS[] = new int[200];
// 黑棋y轴坐标位数组
public int chessBlack_YPOS[] = new int[200];
// 白棋x轴坐标位数组
public int chessWhite_XPOS[] = new int[200];
// 白棋y轴坐标位数组
public int chessWhite_YPOS[] = new int[200];
// 黑棋数量
public int chessBlackCount = 0;
// 白棋数量
public int chessWhiteCount = 0;
// 黑棋获胜次数
public int chessBlackVicTimes = 0;
// 白棋获胜次数
public int chessWhiteVicTimes = 0;
// 套接口
public Socket chessSocket;
public DataInputStream inputData;
public DataOutputStream outputData;
public String chessSelfName = null;
public String chessPeerName = null;
public String host = null;
public int port = 4331;
public TextField statusText = new TextField("请连接服务器!");
public FIRThread firThread = new FIRThread(this);

public FIRPad()
{
setSize(440, 440);
setLayout(null);
setBackground(Color.LIGHT_GRAY);
addMouseListener(this);
add(statusText);
statusText.setBounds(new Rectangle(40, 5, 360, 24));
statusText.setEditable(false);
}

// 连接到主机
public boolean connectServer(String ServerIP, int ServerPort) throws Exception
{
try
{
 // 取得主机端口
 chessSocket = new Socket(ServerIP, ServerPort);
 // 取得输入流
 inputData = new DataInputStream(chessSocket.getInputStream());
 // 取得输出流
 outputData = new DataOutputStream(chessSocket.getOutputStream());
 firThread.start();
 return true;
}
catch (IOException ex)
{
 statusText.setText("连接失败! \n");
}
return false;
}

// 设定胜利时的棋盘状态
public void setVicStatus(int vicChessColor)
{
// 清空棋盘
this.removeAll();
// 将黑棋的位置设置到零点
for (int i = 0; i <= chessBlackCount; i++)
{
 chessBlack_XPOS[i] = 0;
 chessBlack_YPOS[i] = 0;
}
// 将白棋的位置设置到零点
for (int i = 0; i <= chessWhiteCount; i++)
{
 chessWhite_XPOS[i] = 0;
 chessWhite_YPOS[i] = 0;
}
// 清空棋盘上的黑棋数
chessBlackCount = 0;
// 清空棋盘上的白棋数
chessWhiteCount = 0;
add(statusText);
statusText.setBounds(40, 5, 360, 24);
if (vicChessColor == 1)
{ // 黑棋胜
 chessBlackVicTimes++;
 statusText.setText("黑方胜,黑:白 " + chessBlackVicTimes + ":" + chessWhiteVicTimes
  + ",游戏重启,等待白方...");
}
else if (vicChessColor == -1)
{ // 白棋胜
 chessWhiteVicTimes++;
 statusText.setText("白方胜,黑:白 " + chessBlackVicTimes + ":" + chessWhiteVicTimes
  + ",游戏重启,等待黑方...");
}
}

// 取得指定棋子的位置
public void setLocation(int xPos, int yPos, int chessColor)
{
if (chessColor == 1)
{ // 棋子为黑棋时
 chessBlack_XPOS[chessBlackCount] = xPos * 20;
 chessBlack_YPOS[chessBlackCount] = yPos * 20;
 chessBlackCount++;
}
else if (chessColor == -1)
{ // 棋子为白棋时
 chessWhite_XPOS[chessWhiteCount] = xPos * 20;
 chessWhite_YPOS[chessWhiteCount] = yPos * 20;
 chessWhiteCount++;
}
}

// 判断当前状态是否为胜利状态
public boolean checkVicStatus(int xPos, int yPos, int chessColor)
{
int chessLinkedCount = 1; // 连接棋子数
int chessLinkedCompare = 1; // 用于比较是否要继续遍历一个棋子的相邻网格
int chessToCompareIndex = 0; // 要比较的棋子在数组中的索引位置
int closeGrid = 1; // 相邻网格的位置
if (chessColor == 1)
{ // 黑棋时
 chessLinkedCount = 1; // 将该棋子自身算入的话,初始连接数为1
 //以下每对for循环语句为一组,因为下期的位置能位于中间而非两端
 for (closeGrid = 1; closeGrid <= 4; closeGrid++)
 { // 遍历相邻4个网格
 for (chessToCompareIndex = 0; chessToCompareIndex <= chessBlackCount; chessToCompareIndex++)
 { // 遍历棋盘上所有黑棋子
  if (((xPos + closeGrid) * 20 == chessBlack_XPOS[chessToCompareIndex])
   && ((yPos * 20) == chessBlack_YPOS[chessToCompareIndex]))
  { // 判断当前下的棋子的右边4个棋子是否都为黑棋
  chessLinkedCount = chessLinkedCount + 1; // 连接数加1
  if (chessLinkedCount == 5)
  { // 五子相连时,胜利
   return true;
  }
  }
 }
 if (chessLinkedCount == (chessLinkedCompare + 1)) {
  chessLinkedCompare++;
 }
 else {// 若中间有一个棋子非黑棋,则会进入此分支,此时无需再遍历
  break;
 }
 }
 for (closeGrid = 1; closeGrid <= 4; closeGrid++)
 {
 for (chessToCompareIndex = 0; chessToCompareIndex <= chessBlackCount; chessToCompareIndex++)
 {
  if (((xPos - closeGrid) * 20 == chessBlack_XPOS[chessToCompareIndex])
   && (yPos * 20 == chessBlack_YPOS[chessToCompareIndex]))
  { // 判断当前下的棋子的左边4个棋子是否都为黑棋
  chessLinkedCount++;
  if (chessLinkedCount == 5)
  {
   return true;
  }
  }
 }
 if (chessLinkedCount == (chessLinkedCompare + 1)) {
  chessLinkedCompare++;
 }
 else {
  break;
 }
 }
 // 进入新的一组for循环时要将连接数等重置
 chessLinkedCount = 1;
 chessLinkedCompare = 1;
 for (closeGrid = 1; closeGrid <= 4; closeGrid++)
 {
 for (chessToCompareIndex = 0; chessToCompareIndex <= chessBlackCount; chessToCompareIndex++)
 {
  if ((xPos * 20 == chessBlack_XPOS[chessToCompareIndex])
   && ((yPos + closeGrid) * 20 == chessBlack_YPOS[chessToCompareIndex]))
  { // 判断当前下的棋子的上边4个棋子是否都为黑棋
  chessLinkedCount++;
  if (chessLinkedCount == 5)
  {
   return true;
  }
  }
 }
 if (chessLinkedCount == (chessLinkedCompare + 1)) {
  chessLinkedCompare++;
 }
 else {
  break;
 }
 }
 for (closeGrid = 1; closeGrid <= 4; closeGrid++)
 {
 for (chessToCompareIndex = 0; chessToCompareIndex <= chessBlackCount; chessToCompareIndex++)
 {
  if ((xPos * 20 == chessBlack_XPOS[chessToCompareIndex])
   && ((yPos - closeGrid) * 20 == chessBlack_YPOS[chessToCompareIndex]))
  { // 判断当前下的棋子的下边4个棋子是否都为黑棋
  chessLinkedCount++;
  if (chessLinkedCount == 5)
  {
   return true;
  }
  }
 }
 if (chessLinkedCount == (chessLinkedCompare + 1)) {
  chessLinkedCompare++;
 }
 else {
  break;
 }
 }
 chessLinkedCount = 1;
 chessLinkedCompare = 1;
 for (closeGrid = 1; closeGrid <= 4; closeGrid++)
 {
 for (chessToCompareIndex = 0; chessToCompareIndex <= chessBlackCount; chessToCompareIndex++)
 {
  if (((xPos - closeGrid) * 20 == chessBlack_XPOS[chessToCompareIndex])
   && ((yPos + closeGrid) * 20 == chessBlack_YPOS[chessToCompareIndex]))
  { // 判断当前下的棋子的左上方向4个棋子是否都为黑棋
  chessLinkedCount++;
  if (chessLinkedCount == 5)
  {
   return true;
  }
  }
 }
 if (chessLinkedCount == (chessLinkedCompare + 1)) {
  chessLinkedCompare++;
 }
 else {
  break;
 }
 }
 for (closeGrid = 1; closeGrid <= 4; closeGrid++)
 {
 for (chessToCompareIndex = 0; chessToCompareIndex <= chessBlackCount; chessToCompareIndex++)
 {
  if (((xPos + closeGrid) * 20 == chessBlack_XPOS[chessToCompareIndex])
   && ((yPos - closeGrid) * 20 == chessBlack_YPOS[chessToCompareIndex]))
  { // 判断当前下的棋子的右下方向4个棋子是否都为黑棋
  chessLinkedCount++;
  if (chessLinkedCount == 5)
  {
   return true;
  }
  }
 }
 if (chessLinkedCount == (chessLinkedCompare + 1)) {
  chessLinkedCompare++;
 }
 else {
  break;
 }
 }
 chessLinkedCount = 1;
 chessLinkedCompare = 1;
 for (closeGrid = 1; closeGrid <= 4; closeGrid++)
 {
 for (chessToCompareIndex = 0; chessToCompareIndex <= chessBlackCount; chessToCompareIndex++)
 {
  if (((xPos + closeGrid) * 20 == chessBlack_XPOS[chessToCompareIndex])
   && ((yPos + closeGrid) * 20 == chessBlack_YPOS[chessToCompareIndex]))
  { // 判断当前下的棋子的右上方向4个棋子是否都为黑棋
  chessLinkedCount++;
  if (chessLinkedCount == 5)
  {
   return true;
  }
  }
 }
 if (chessLinkedCount == (chessLinkedCompare + 1)) {
  chessLinkedCompare++;
 }
 else {
  break;
 }
 }
 for (closeGrid = 1; closeGrid <= 4; closeGrid++)
 {
 for (chessToCompareIndex = 0; chessToCompareIndex <= chessBlackCount; chessToCompareIndex++)
 {
  if (((xPos - closeGrid) * 20 == chessBlack_XPOS[chessToCompareIndex])
   && ((yPos - closeGrid) * 20 == chessBlack_YPOS[chessToCompareIndex]))
  { // 判断当前下的棋子的左下方向4个棋子是否都为黑棋
  chessLinkedCount++;
  if (chessLinkedCount == 5)
  {
   return true;
  }
  }
 }
 if (chessLinkedCount == (chessLinkedCompare + 1)) {
  chessLinkedCompare++;
 }
 else {
  break;
 }
 }
}
else if (chessColor == -1)
{ // 白棋时
 chessLinkedCount = 1;
 for (closeGrid = 1; closeGrid <= 4; closeGrid++)
 {
 for (chessToCompareIndex = 0; chessToCompareIndex <= chessWhiteCount; chessToCompareIndex++)
 {
  if (((xPos + closeGrid) * 20 == chessWhite_XPOS[chessToCompareIndex])
   && (yPos * 20 == chessWhite_YPOS[chessToCompareIndex]))
  {// 判断当前下的棋子的右边4个棋子是否都为白棋
  chessLinkedCount++;
  if (chessLinkedCount == 5)
  {
   return true;
  }
  }
 }
 if (chessLinkedCount == (chessLinkedCompare + 1)) {
  chessLinkedCompare++;
 }
 else {
  break;
 }
 }
 for (closeGrid = 1; closeGrid <= 4; closeGrid++)
 {
 for (chessToCompareIndex = 0; chessToCompareIndex <= chessWhiteCount; chessToCompareIndex++)
 {
  if (((xPos - closeGrid) * 20 == chessWhite_XPOS[chessToCompareIndex])
   && (yPos * 20 == chessWhite_YPOS[chessToCompareIndex]))
  {// 判断当前下的棋子的左边4个棋子是否都为白棋
  chessLinkedCount++;
  if (chessLinkedCount == 5)
  {
   return true;
  }
  }
 }
 if (chessLinkedCount == (chessLinkedCompare + 1)) {
  chessLinkedCompare++;
 }
 else {
  break;
 }
 }
 chessLinkedCount = 1;
 chessLinkedCompare = 1;
 for (closeGrid = 1; closeGrid <= 4; closeGrid++)
 {
 for (chessToCompareIndex = 0; chessToCompareIndex <= chessWhiteCount; chessToCompareIndex++)
 {
  if ((xPos * 20 == chessWhite_XPOS[chessToCompareIndex])
   && ((yPos + closeGrid) * 20 == chessWhite_YPOS[chessToCompareIndex]))
  {// 判断当前下的棋子的上边4个棋子是否都为白棋
  chessLinkedCount++;
  if (chessLinkedCount == 5)
  {
   return true;
  }
  }
 }
 if (chessLinkedCount == (chessLinkedCompare + 1)) {
  chessLinkedCompare++;
 }
 else {
  break;
 }
 }
 for (closeGrid = 1; closeGrid <= 4; closeGrid++)
 {
 for (chessToCompareIndex = 0; chessToCompareIndex <= chessWhiteCount; chessToCompareIndex++)
 {
  if ((xPos * 20 == chessWhite_XPOS[chessToCompareIndex])
   && ((yPos - closeGrid) * 20 == chessWhite_YPOS[chessToCompareIndex]))
  {// 判断当前下的棋子的下边4个棋子是否都为白棋
  chessLinkedCount++;
  if (chessLinkedCount == 5)
  {
   return true;
  }
  }
 }
 if (chessLinkedCount == (chessLinkedCompare + 1)) {
  chessLinkedCompare++;
 }
 else {
  break;
 }
 }
 chessLinkedCount = 1;
 chessLinkedCompare = 1;
 for (closeGrid = 1; closeGrid <= 4; closeGrid++)
 {
 for (chessToCompareIndex = 0; chessToCompareIndex <= chessWhiteCount; chessToCompareIndex++)
 {
  if (((xPos - closeGrid) * 20 == chessWhite_XPOS[chessToCompareIndex])
   && ((yPos + closeGrid) * 20 == chessWhite_YPOS[chessToCompareIndex]))
  {// 判断当前下的棋子的左上方向4个棋子是否都为白棋
  chessLinkedCount++;
  if (chessLinkedCount == 5)
  {
   return true;
  }
  }
 }
 if (chessLinkedCount == (chessLinkedCompare + 1)) {
  chessLinkedCompare++;
 }
 else {
  break;
 }
 }
 for (closeGrid = 1; closeGrid <= 4; closeGrid++)
 {
 for (chessToCompareIndex = 0; chessToCompareIndex <= chessWhiteCount; chessToCompareIndex++)
 {
  if (((xPos + closeGrid) * 20 == chessWhite_XPOS[chessToCompareIndex])
   && ((yPos - closeGrid) * 20 == chessWhite_YPOS[chessToCompareIndex]))
  {// 判断当前下的棋子的右下方向4个棋子是否都为白棋
  chessLinkedCount++;
  if (chessLinkedCount == 5)
  {
   return true;
  }
  }
 }
 if (chessLinkedCount == (chessLinkedCompare + 1)) {
  chessLinkedCompare++;
 }
 else {
  break;
 }
 }
 chessLinkedCount = 1;
 chessLinkedCompare = 1;
 for (closeGrid = 1; closeGrid <= 4; closeGrid++)
 {
 for (chessToCompareIndex = 0; chessToCompareIndex <= chessWhiteCount; chessToCompareIndex++)
 {
  if (((xPos + closeGrid) * 20 == chessWhite_XPOS[chessToCompareIndex])
   && ((yPos + closeGrid) * 20 == chessWhite_YPOS[chessToCompareIndex]))
  {// 判断当前下的棋子的右上方向4个棋子是否都为白棋
  chessLinkedCount++;
  if (chessLinkedCount == 5)
  {
   return true;
  }
  }
 }
 if (chessLinkedCount == (chessLinkedCompare + 1)) {
  chessLinkedCompare++;
 }
 else {
  break;
 }
 }
 for (closeGrid = 1; closeGrid <= 4; closeGrid++)
 {
 for (chessToCompareIndex = 0; chessToCompareIndex <= chessWhiteCount; chessToCompareIndex++)
 {
  if (((xPos - closeGrid) * 20 == chessWhite_XPOS[chessToCompareIndex])
   && ((yPos - closeGrid) * 20 == chessWhite_YPOS[chessToCompareIndex]))
  {// 判断当前下的棋子的左下方向4个棋子是否都为白棋
  chessLinkedCount++;
  if (chessLinkedCount == 5)
  {
   return (true);
  }
  }
 }
 if (chessLinkedCount == (chessLinkedCompare + 1)) {
  chessLinkedCompare++;
 }
 else {
  break;
 }
 }
}
return false;
}

// 画棋盘
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 paintFirPoint(int xPos, int yPos, int chessColor)
{
FIRPointBlack firPBlack = new FIRPointBlack(this);
FIRPointWhite firPWhite = new FIRPointWhite(this);
if (chessColor == 1 && isMouseEnabled)
{ // 黑棋
 // 设置棋子的位置
 setLocation(xPos, yPos, chessColor);
 // 取得当前局面状态
 isWinned = checkVicStatus(xPos, yPos, chessColor);
 if (isWinned == false)
 { // 非胜利状态
 firThread.sendMessage("/" + chessPeerName + " /chess "
  + xPos + " " + yPos + " " + chessColor);
 this.add(firPBlack); // 将棋子添加到棋盘中
 firPBlack.setBounds(xPos * 20 - 7,
  yPos * 20 - 7, 16, 16); // 设置棋子边界
 statusText.setText("黑(第" + chessBlackCount + "步)"
  + xPos + " " + yPos + ",轮到白方.");
 isMouseEnabled = false; // 将鼠标设为不可用
 }
 else
 { // 胜利状态
 firThread.sendMessage("/" + chessPeerName + " /chess "
  + xPos + " " + yPos + " " + chessColor);
 this.add(firPBlack);
 firPBlack.setBounds(xPos * 20 - 7,
  yPos * 20 - 7, 16, 16);
 setVicStatus(1); // 调用胜利方法,传入参数为黑棋胜利
 isMouseEnabled = false;
 }
}
else if (chessColor == -1 && isMouseEnabled)
{ // 白棋
 setLocation(xPos, yPos, chessColor);
 isWinned = checkVicStatus(xPos, yPos, chessColor);
 if (isWinned == false)
 {
 firThread.sendMessage("/" + chessPeerName + " /chess "
  + xPos + " " + yPos + " " + chessColor);
 this.add(firPWhite);
 firPWhite.setBounds(xPos * 20 - 7,
  yPos * 20 - 7, 16, 16);
 statusText.setText("白(第" + chessWhiteCount + "步)"
  + xPos + " " + yPos + ",轮到黑方.");
 isMouseEnabled = false;
 }
 else
 {
 firThread.sendMessage("/" + chessPeerName + " /chess "
  + xPos + " " + yPos + " " + chessColor);
 this.add(firPWhite);
 firPWhite.setBounds(xPos * 20 - 7,
  yPos * 20 - 7, 16, 16);
 setVicStatus(-1); // 调用胜利方法,传入参数为白棋
 isMouseEnabled = false;
 }
}
}

// 画网络棋盘
public void paintNetFirPoint(int xPos, int yPos, int chessColor)
{
FIRPointBlack firPBlack = new FIRPointBlack(this);
FIRPointWhite firPWhite = new FIRPointWhite(this);
setLocation(xPos, yPos, chessColor);
if (chessColor == 1)
{
 isWinned = checkVicStatus(xPos, yPos, chessColor);
 if (isWinned == false)
 {
 this.add(firPBlack);
 firPBlack.setBounds(xPos * 20 - 7,
  yPos * 20 - 7, 16, 16);
 statusText.setText("黑(第" + chessBlackCount + "步)"
  + xPos + " " + yPos + ",轮到白方.");
 isMouseEnabled = true;
 }
 else
 {
 firThread.sendMessage("/" + chessPeerName + " /victory "
  + chessColor);//djr
 this.add(firPBlack);
 firPBlack.setBounds(xPos * 20 - 7,
  yPos * 20 - 7, 16, 16);
 setVicStatus(1);
 isMouseEnabled = true;
 }
}
else if (chessColor == -1)
{
 isWinned = checkVicStatus(xPos, yPos, chessColor);
 if (isWinned == false)
 {
 this.add(firPWhite);
 firPWhite.setBounds(xPos * 20 - 7,
  yPos * 20 - 7, 16, 16);
 statusText.setText("白(第" + chessWhiteCount + "步)"
  + xPos + " " + yPos + ",轮到黑方.");
 isMouseEnabled = true;
 }
 else
 {
 firThread.sendMessage("/" + chessPeerName + " /victory "
  + chessColor);
 this.add(firPWhite);
 firPWhite.setBounds(xPos * 20 - 7,
  yPos * 20 - 7, 16, 16);
 setVicStatus(-1);
 isMouseEnabled = true;
 }
}
}

// 捕获下棋事件
public void mousePressed(MouseEvent e)
{
if (e.getModifiers() == InputEvent.BUTTON1_MASK)
{
 chessX_POS = (int) e.getX();
 chessY_POS = (int) e.getY();
 int a = (chessX_POS + 10) / 20, b = (chessY_POS + 10) / 20;
 if (chessX_POS / 20 < 2 || chessY_POS / 20 < 2
  || chessX_POS / 20 > 19 || chessY_POS / 20 > 19)
 {
 // 下棋位置不正确时,不执行任何操作
 }
 else
 {
 paintFirPoint(a, b, chessColor); // 画棋子
 }
}
}

public void mouseReleased(MouseEvent e){}
public void mouseEntered(MouseEvent e){}
public void mouseExited(MouseEvent e){}
public void mouseClicked(MouseEvent e){}
public void actionPerformed(ActionEvent e){}
}

4.开发棋盘线程


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

/**
* Created by Administrator on 2016/11/21.
*/
public class FIRThread extends Thread{
FIRPad currPad; // 当前线程的棋盘

public FIRThread(FIRPad currPad)
{
this.currPad = currPad;
}

// 处理取得的信息
public void dealWithMsg(String msgReceived)
{
if (msgReceived.startsWith("/chess "))
{ // 收到的信息为下棋
 StringTokenizer userMsgToken = new StringTokenizer(msgReceived, " ");
 // 表示棋子信息的数组、0索引为:x坐标;1索引位:y坐标;2索引位:棋子颜色
 String[] chessInfo = { "-1", "-1", "0" };
 int i = 0; // 标志位
 String chessInfoToken;
 while (userMsgToken.hasMoreTokens())
 {
 chessInfoToken = (String) userMsgToken.nextToken(" ");
 if (i >= 1 && i <= 3)
 {
  chessInfo[i - 1] = chessInfoToken;
 }
 i++;
 }
 currPad.paintNetFirPoint(Integer.parseInt(chessInfo[0]), Integer
  .parseInt(chessInfo[1]), Integer.parseInt(chessInfo[2]));
}
else if (msgReceived.startsWith("/yourname "))
{ // 收到的信息为改名
 currPad.chessSelfName = msgReceived.substring(10);
}
else if (msgReceived.equals("/error"))
{ // 收到的为错误信息
 currPad.statusText.setText("用户不存在,请重新加入!");
}
}

// 发送信息
public void sendMessage(String sndMessage)
{
try
{
 currPad.outputData.writeUTF(sndMessage);
}
catch (Exception ea)
{
 ea.printStackTrace();;
}
}

public void run()
{
String msgReceived = "";
try
{
 while (true)
 { // 等待信息输入
 msgReceived = currPad.inputData.readUTF();
 dealWithMsg(msgReceived);
 }
}
catch (IOException es){}
}
}

下面开始开发服务器模块

1.开发服务器信息面板


import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.Label;
import java.awt.Panel;
import java.awt.TextArea;

import javax.swing.JLabel;

/**
* Created by Administrator on 2016/11/21.
*/
public class ServerMsgPanel extends Panel {
public TextArea msgTextArea = new TextArea("", 22, 50,
 TextArea.SCROLLBARS_VERTICAL_ONLY);
public JLabel statusLabel = new JLabel("当前连接数:", Label.LEFT);
public Panel msgPanel = new Panel();
public Panel statusPanel = new Panel();
public ServerMsgPanel()
{
setSize(350, 300);
setBackground(Color.LIGHT_GRAY);
setLayout(new BorderLayout());
msgPanel.setLayout(new FlowLayout());
msgPanel.setSize(210, 210);
statusPanel.setLayout(new BorderLayout());
statusPanel.setSize(210, 50);
msgPanel.add(msgTextArea);
statusPanel.add(statusLabel, BorderLayout.WEST);
add(msgPanel, BorderLayout.CENTER);
add(statusPanel, BorderLayout.NORTH);
}

}

2.开发服务器进程


import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.StringTokenizer;

/**
* Created by Administrator on 2016/11/21.
*/
public class FIRServerThread extends Thread{
Socket clientSocket; // 保存客户端套接口信息
Hashtable clientDataHash; // 保存客户端端口与输出流对应的Hash
Hashtable clientNameHash; // 保存客户端套接口和客户名对应的Hash
Hashtable chessPeerHash; // 保存游戏创建者和游戏加入者对应的Hash
ServerMsgPanel serverMsgPanel;
boolean isClientClosed = false;

public FIRServerThread(Socket clientSocket, Hashtable clientDataHash,
   Hashtable clientNameHash, Hashtable chessPeerHash,
   ServerMsgPanel server)
{
this.clientSocket = clientSocket;
this.clientDataHash = clientDataHash;
this.clientNameHash = clientNameHash;
this.chessPeerHash = chessPeerHash;
this.serverMsgPanel = server;
}

public void dealWithMsg(String msgReceived)
{
String clientName;
String peerName;
if (msgReceived.startsWith("/"))
{
 if (msgReceived.equals("/list"))
 { // 收到的信息为更新用户列表
 Feedback(getUserList());
 }
 else if (msgReceived.startsWith("/creatgame [inchess]"))
 { // 收到的信息为创建游戏
 String gameCreaterName = msgReceived.substring(20); //取得服务器名
 synchronized (clientNameHash)
 { // 将用户端口放到用户列表中
  clientNameHash.put(clientSocket, msgReceived.substring(11));
 }
 synchronized (chessPeerHash)
 { // 将主机设置为等待状态
  chessPeerHash.put(gameCreaterName, "wait");
 }
 Feedback("/yourname " + clientNameHash.get(clientSocket));
 sendGamePeerMsg(gameCreaterName, "/OK");
 sendPublicMsg(getUserList());
 }
 else if (msgReceived.startsWith("/joingame "))
 { // 收到的信息为加入游戏时
 StringTokenizer userTokens = new StringTokenizer(msgReceived, " ");
 String userToken;
 String gameCreatorName;
 String gamePaticipantName;
 String[] playerNames = { "0", "0" };
 int nameIndex = 0;
 while (userTokens.hasMoreTokens())
 {
  userToken = (String) userTokens.nextToken(" ");
  if (nameIndex >= 1 && nameIndex <= 2)
  {
  playerNames[nameIndex - 1] = userToken; // 取得游戏者命
  }
  nameIndex++;
 }
 gameCreatorName = playerNames[0];
 gamePaticipantName = playerNames[1];
 if (chessPeerHash.containsKey(gameCreatorName)
  && chessPeerHash.get(gameCreatorName).equals("wait"))
 { // 游戏已创建
  synchronized (clientNameHash)
  { // 增加游戏加入者的套接口与名称的对应
  clientNameHash.put(clientSocket,
   ("[inchess]" + gamePaticipantName));
  }
  synchronized (chessPeerHash)
  { // 增加或修改游戏创建者与游戏加入者的名称的对应
  chessPeerHash.put(gameCreatorName, gamePaticipantName);
  }
  sendPublicMsg(getUserList());
  // 发送信息给游戏加入者
  sendGamePeerMsg(gamePaticipantName,
   ("/peer " + "[inchess]" + gameCreatorName));
  // 发送游戏给游戏创建者
  sendGamePeerMsg(gameCreatorName,
   ("/peer " + "[inchess]" + gamePaticipantName));
 }
 else
 { // 若游戏未创建则拒绝加入游戏
  sendGamePeerMsg(gamePaticipantName, "/reject");
  try
  {
  closeClient();
  }
  catch (Exception ez)
  {
  ez.printStackTrace();
  }
 }
 }
 else if (msgReceived.startsWith("/[inchess]"))
 { // 收到的信息为游戏中时
 int firstLocation = 0, lastLocation;
 lastLocation = msgReceived.indexOf(" ", 0);
 peerName = msgReceived.substring((firstLocation + 1), lastLocation);
 msgReceived = msgReceived.substring((lastLocation + 1));
 if (sendGamePeerMsg(peerName, msgReceived))
 {
  Feedback("/error");
 }
 }
 else if (msgReceived.startsWith("/giveup "))
 { // 收到的信息为放弃游戏时
 String chessClientName = msgReceived.substring(8);
 if (chessPeerHash.containsKey(chessClientName)
  && !((String) chessPeerHash.get(chessClientName))
  .equals("wait"))
 { // 胜利方为游戏加入者,发送胜利信息
  sendGamePeerMsg((String) chessPeerHash.get(chessClientName),
   "/youwin");
  synchronized (chessPeerHash)
  { // 删除退出游戏的用户
  chessPeerHash.remove(chessClientName);
  }
 }
 if (chessPeerHash.containsValue(chessClientName))
 { // 胜利方为游戏创建者,发送胜利信息
  sendGamePeerMsg((String) getHashKey(chessPeerHash,
   chessClientName), "/youwin");
  synchronized (chessPeerHash)
  {// 删除退出游戏的用户
  chessPeerHash.remove((String) getHashKey(chessPeerHash,
   chessClientName));
  }
 }
 }
 else
 { // 收到的信息为其它信息时
 int lastLocation = msgReceived.indexOf(" ", 0);
 if (lastLocation == -1)
 {
  Feedback("无效命令");
  return;
 }
 }
}
else
{
 msgReceived = clientNameHash.get(clientSocket) + ">" + msgReceived;
 serverMsgPanel.msgTextArea.append(msgReceived + "\n");
 sendPublicMsg(msgReceived);
 serverMsgPanel.msgTextArea.setCaretPosition(serverMsgPanel.msgTextArea.getText()
  .length());
}
}

// 发送公开信息
public void sendPublicMsg(String publicMsg)
{
synchronized (clientDataHash)
{
 for (Enumeration enu = clientDataHash.elements(); enu
  .hasMoreElements();)
 {
 DataOutputStream outputData = (DataOutputStream) enu.nextElement();
 try
 {
  outputData.writeUTF(publicMsg);
 }
 catch (IOException es)
 {
  es.printStackTrace();
 }
 }
}
}

// 发送信息给指定的游戏中的用户
public boolean sendGamePeerMsg(String gamePeerTarget, String gamePeerMsg)
{
for (Enumeration enu = clientDataHash.keys(); enu.hasMoreElements();)
{ // 遍历以取得游戏中的用户的套接口
 Socket userClient = (Socket) enu.nextElement();
 if (gamePeerTarget.equals((String) clientNameHash.get(userClient))
  && !gamePeerTarget.equals((String) clientNameHash
  .get(clientSocket)))
 { // 找到要发送信息的用户时
 synchronized (clientDataHash)
 {
  // 建立输出流
  DataOutputStream peerOutData = (DataOutputStream) clientDataHash
   .get(userClient);
  try
  {
  // 发送信息
  peerOutData.writeUTF(gamePeerMsg);
  }
  catch (IOException es)
  {
  es.printStackTrace();
  }
 }
 return false;
 }
}
return true;
}

// 发送反馈信息给连接到主机的人
public void Feedback(String feedBackMsg)
{
synchronized (clientDataHash)
{
 DataOutputStream outputData = (DataOutputStream) clientDataHash
  .get(clientSocket);
 try
 {
 outputData.writeUTF(feedBackMsg);
 }
 catch (Exception eb)
 {
 eb.printStackTrace();
 }
}
}

// 取得用户列表
public String getUserList()
{
String userList = "/userlist";
for (Enumeration enu = clientNameHash.elements(); enu.hasMoreElements();)
{
 userList = userList + " " + (String) enu.nextElement();
}
return userList;
}

// 根据value值从Hashtable中取得相应的key
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 sendInitMsg()
{
sendPublicMsg(getUserList());
Feedback("/yourname " + (String) clientNameHash.get(clientSocket));
Feedback("Java 五子棋客户端");
Feedback("/list --更新用户列表");
Feedback("/<username> <talk> --私聊");
Feedback("注意:命令必须对所有用户发送");
}

public void closeClient()
{
serverMsgPanel.msgTextArea.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");
 }
}
synchronized (clientDataHash)
{ // 删除客户数据
 clientDataHash.remove(clientSocket);
}
synchronized (clientNameHash)
{ // 删除客户数据
 clientNameHash.remove(clientSocket);
}
sendPublicMsg(getUserList());
serverMsgPanel.statusLabel.setText("当前连接数:" + clientDataHash.size());
try
{
 clientSocket.close();
}
catch (IOException exx)
{
 exx.printStackTrace();
}
isClientClosed = true;
}

public void run()
{
DataInputStream inputData;
synchronized (clientDataHash)
{
 serverMsgPanel.statusLabel.setText("当前连接数:" + clientDataHash.size());
}
try
{ // 等待连接到主机的信息
 inputData = new DataInputStream(clientSocket.getInputStream());
 sendInitMsg();
 while (true)
 {
 String message = inputData.readUTF();
 dealWithMsg(message);
 }
}
catch (IOException esx){}
finally
{
 if (!isClientClosed)
 {
 closeClient();
 }
}
}
}

3.开发服务器端


import java.io.*;
import java.net.*;
import java.awt.*;
import java.util.*;
import java.awt.event.*;

import javax.swing.JButton;
/**
* Created by Administrator on 2016/11/21.
*/
public class FIRServer extends Frame implements ActionListener{
JButton clearMsgButton = new JButton("清空列表");
JButton serverStatusButton = new JButton("服务器状态");
JButton closeServerButton = new JButton("关闭服务器");
Panel buttonPanel = new Panel();
ServerMsgPanel serverMsgPanel = new ServerMsgPanel();
ServerSocket serverSocket;
Hashtable clientDataHash = new Hashtable(50); //将客户端套接口和输出流绑定
Hashtable clientNameHash = new Hashtable(50); //将客户端套接口和客户名绑定
Hashtable chessPeerHash = new Hashtable(50); //将游戏创建者和游戏加入者绑定

public FIRServer()
{
super("Java 五子棋服务器");
setBackground(Color.LIGHT_GRAY);
buttonPanel.setLayout(new FlowLayout());
clearMsgButton.setSize(60, 25);
buttonPanel.add(clearMsgButton);
clearMsgButton.addActionListener(this);
serverStatusButton.setSize(75, 25);
buttonPanel.add(serverStatusButton);
serverStatusButton.addActionListener(this);
closeServerButton.setSize(75, 25);
buttonPanel.add(closeServerButton);
closeServerButton.addActionListener(this);
add(serverMsgPanel, BorderLayout.CENTER);
add(buttonPanel, BorderLayout.SOUTH);

addWindowListener(new WindowAdapter()
{
 public void windowClosing(WindowEvent e)
 {
 System.exit(0);
 }
});
pack();
setVisible(true);
setSize(400, 300);
setResizable(false);
validate();

try
{
 createServer(4331, serverMsgPanel);
}
catch (Exception e)
{
 e.printStackTrace();
}
}

// 用指定端口和面板创建服务器
public void createServer(int port, ServerMsgPanel serverMsgPanel) throws IOException
{
Socket clientSocket; // 客户端套接口
long clientAccessNumber = 1; // 连接到主机的客户数量
this.serverMsgPanel = serverMsgPanel; // 设定当前主机
try
{
 serverSocket = new ServerSocket(port);
 serverMsgPanel.msgTextArea.setText("服务器启动于:"
  + InetAddress.getLocalHost() + ":" //djr
  + serverSocket.getLocalPort() + "\n");
 while (true)
 {
 // 监听客户端套接口的信息
 clientSocket = serverSocket.accept();
 serverMsgPanel.msgTextArea.append("已连接用户:" + clientSocket + "\n");
 // 建立客户端输出流
 DataOutputStream outputData = new DataOutputStream(clientSocket
  .getOutputStream());
 // 将客户端套接口和输出流绑定
 clientDataHash.put(clientSocket, outputData);
 // 将客户端套接口和客户名绑定
 clientNameHash
  .put(clientSocket, ("新玩家" + clientAccessNumber++));
 // 创建并运行服务器端线程
 FIRServerThread thread = new FIRServerThread(clientSocket,
  clientDataHash, clientNameHash, chessPeerHash, serverMsgPanel);
 thread.start();
 }
}
catch (IOException ex)
{
 ex.printStackTrace();
}
}

public void actionPerformed(ActionEvent e)
{
if (e.getSource() == clearMsgButton)
{ // 清空服务器信息
 serverMsgPanel.msgTextArea.setText("");
}
if (e.getSource() == serverStatusButton)
{ // 显示服务器信息
 try
 {
 serverMsgPanel.msgTextArea.append("服务器信息:"
  + InetAddress.getLocalHost() + ":"
  + serverSocket.getLocalPort() + "\n");
 }
 catch (Exception ee)
 {
 ee.printStackTrace();
 }
}
if (e.getSource() == closeServerButton)
{ // 关闭服务器
 System.exit(0);
}
}

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

下面开始编写客户端模块

1.开发客户端


import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.net.*;

import javax.swing.JFrame;

import djr.chess.gui.UserChatPad;
import djr.chess.gui.UserControlPad;
import djr.chess.gui.UserInputPad;
import djr.chess.gui.UserListPad;
import djr.chess.pad.FIRPad;

/**
* Created by Administrator on 2016/11/21.
*/
public class FIRClient extends Frame implements ActionListener,KeyListener {
// 客户端套接口
Socket clientSocket;
// 数据输入流
DataInputStream inputStream;
// 数据输出流
DataOutputStream outputStream;
// 用户名
String chessClientName = null;
// 主机地址
String host = null;
// 主机端口
int port = 4331;
// 是否在聊天
boolean isOnChat = false;
// 是否在下棋
boolean isOnChess = false;
// 游戏是否进行中
boolean isGameConnected = false;
// 是否为游戏创建者
boolean isCreator = false;
// 是否为游戏加入者
boolean isParticipant = false;
// 用户列表区
UserListPad userListPad = new UserListPad();
// 用户聊天区
UserChatPad userChatPad = new UserChatPad();
// 用户操作区
UserControlPad userControlPad = new UserControlPad();
// 用户输入区
UserInputPad userInputPad = new UserInputPad();
// 下棋区
FIRPad firPad = new FIRPad();
// 面板区
Panel southPanel = new Panel();
Panel northPanel = new Panel();
Panel centerPanel = new Panel();
Panel eastPanel = new Panel();

// 构造方法,创建界面
public FIRClient()
{
super("Java 五子棋客户端");
setLayout(new BorderLayout());
host = userControlPad.ipInputted.getText();

eastPanel.setLayout(new BorderLayout());
eastPanel.add(userListPad, BorderLayout.NORTH);
eastPanel.add(userChatPad, BorderLayout.CENTER);
eastPanel.setBackground(Color.LIGHT_GRAY);

userInputPad.contentInputted.addKeyListener(this);

firPad.host = userControlPad.ipInputted.getText();
centerPanel.add(firPad, BorderLayout.CENTER);
centerPanel.add(userInputPad, BorderLayout.SOUTH);
centerPanel.setBackground(Color.LIGHT_GRAY);
userControlPad.connectButton.addActionListener(this);
userControlPad.createButton.addActionListener(this);
userControlPad.joinButton.addActionListener(this);
userControlPad.cancelButton.addActionListener(this);
userControlPad.exitButton.addActionListener(this);
userControlPad.createButton.setEnabled(false);
userControlPad.joinButton.setEnabled(false);
userControlPad.cancelButton.setEnabled(false);

southPanel.add(userControlPad, BorderLayout.CENTER);
southPanel.setBackground(Color.LIGHT_GRAY);

addWindowListener(new WindowAdapter()
{
 public void windowClosing(WindowEvent e)
 {
 if (isOnChat)
 { // 聊天中
  try
  { // 关闭客户端套接口
  clientSocket.close();
  }
  catch (Exception ed){}
 }
 if (isOnChess || isGameConnected)
 { // 下棋中
  try
  { // 关闭下棋端口
  firPad.chessSocket.close();
  }
  catch (Exception ee){}
 }
 System.exit(0);
 }
});

add(eastPanel, BorderLayout.EAST);
add(centerPanel, BorderLayout.CENTER);
add(southPanel, BorderLayout.SOUTH);
pack();
setSize(670, 560);
setVisible(true);
setResizable(false);
this.validate();
}

// 按指定的IP地址和端口连接到服务器
public boolean connectToServer(String serverIP, int serverPort) throws Exception
{
try
{
 // 创建客户端套接口
 clientSocket = new Socket(serverIP, serverPort);
 // 创建输入流
 inputStream = new DataInputStream(clientSocket.getInputStream());
 // 创建输出流
 outputStream = new DataOutputStream(clientSocket.getOutputStream());
 // 创建客户端线程
 FIRClientThread clientthread = new FIRClientThread(this);
 // 启动线程,等待聊天信息
 clientthread.start();
 isOnChat = true;
 return true;
}
catch (IOException ex)
{
 userChatPad.chatTextArea
  .setText("不能连接!\n");
}
return false;
}

// 客户端事件处理
public void actionPerformed(ActionEvent e)
{
if (e.getSource() == userControlPad.connectButton)
{ // 连接到主机按钮单击事件
 host = firPad.host = userControlPad.ipInputted.getText(); // 取得主机地址
 try
 {
 if (connectToServer(host, port))
 { // 成功连接到主机时,设置客户端相应的界面状态
  userChatPad.chatTextArea.setText("");
  userControlPad.connectButton.setEnabled(false);
  userControlPad.createButton.setEnabled(true);
  userControlPad.joinButton.setEnabled(true);
  firPad.statusText.setText("连接成功,请等待!");
 }
 }
 catch (Exception ei)
 {
 userChatPad.chatTextArea
  .setText("不能连接!\n");
 }
}
if (e.getSource() == userControlPad.exitButton)
{ // 离开游戏按钮单击事件
 if (isOnChat)
 { // 若用户处于聊天状态中
 try
 { // 关闭客户端套接口
  clientSocket.close();
 }
 catch (Exception ed){}
 }
 if (isOnChess || isGameConnected)
 { // 若用户处于游戏状态中
 try
 { // 关闭游戏端口
  firPad.chessSocket.close();
 }
 catch (Exception ee){}
 }
 System.exit(0);
}
if (e.getSource() == userControlPad.joinButton)
{ // 加入游戏按钮单击事件
 String selectedUser = (String)userListPad.userList.getSelectedItem(); // 取得要加入的游戏
 if (selectedUser == null || selectedUser.startsWith("[inchess]") ||
  selectedUser.equals(chessClientName))
 { // 若未选中要加入的用户,或选中的用户已经在游戏,则给出提示信息
 firPad.statusText.setText("必须选择一个用户!");
 }
 else
 { // 执行加入游戏的操作
 try
 {
  if (!isGameConnected)
  { // 若游戏套接口未连接
  if (firPad.connectServer(firPad.host, firPad.port))
  { // 若连接到主机成功
   isGameConnected = true;
   isOnChess = true;
   isParticipant = true;
   userControlPad.createButton.setEnabled(false);
   userControlPad.joinButton.setEnabled(false);
   userControlPad.cancelButton.setEnabled(true);
   firPad.firThread.sendMessage("/joingame "
    + (String)userListPad.userList.getSelectedItem() + " "
    + chessClientName);
  }
  }
  else
  { // 若游戏端口连接中
  isOnChess = true;
  isParticipant = true;
  userControlPad.createButton.setEnabled(false);
  userControlPad.joinButton.setEnabled(false);
  userControlPad.cancelButton.setEnabled(true);
  firPad.firThread.sendMessage("/joingame "
   + (String)userListPad.userList.getSelectedItem() + " "
   + chessClientName);
  }
 }
 catch (Exception ee)
 {
  isGameConnected = false;
  isOnChess = false;
  isParticipant = false;
  userControlPad.createButton.setEnabled(true);
  userControlPad.joinButton.setEnabled(true);
  userControlPad.cancelButton.setEnabled(false);
  userChatPad.chatTextArea
   .setText("不能连接: \n" + ee);
 }
 }
}
if (e.getSource() == userControlPad.createButton)
{ // 创建游戏按钮单击事件
 try
 {
 if (!isGameConnected)
 { // 若游戏端口未连接
  if (firPad.connectServer(firPad.host, firPad.port))
  { // 若连接到主机成功
  isGameConnected = true;
  isOnChess = true;
  isCreator = true;
  userControlPad.createButton.setEnabled(false);
  userControlPad.joinButton.setEnabled(false);
  userControlPad.cancelButton.setEnabled(true);
  firPad.firThread.sendMessage("/creatgame "
   + "[inchess]" + chessClientName);
  }
 }
 else
 { // 若游戏端口连接中
  isOnChess = true;
  isCreator = true;
  userControlPad.createButton.setEnabled(false);
  userControlPad.joinButton.setEnabled(false);
  userControlPad.cancelButton.setEnabled(true);
  firPad.firThread.sendMessage("/creatgame "
   + "[inchess]" + chessClientName);
 }
 }
 catch (Exception ec)
 {
 isGameConnected = false;
 isOnChess = false;
 isCreator = false;
 userControlPad.createButton.setEnabled(true);
 userControlPad.joinButton.setEnabled(true);
 userControlPad.cancelButton.setEnabled(false);
 ec.printStackTrace();
 userChatPad.chatTextArea.setText("不能连接: \n"
  + ec);
 }
}
if (e.getSource() == userControlPad.cancelButton)
{ // 退出游戏按钮单击事件
 if (isOnChess)
 { // 游戏中
 firPad.firThread.sendMessage("/giveup " + chessClientName);
 firPad.setVicStatus(-1 * firPad.chessColor);
 userControlPad.createButton.setEnabled(true);
 userControlPad.joinButton.setEnabled(true);
 userControlPad.cancelButton.setEnabled(false);
 firPad.statusText.setText("请创建或加入游戏!");
 }
 if (!isOnChess)
 { // 非游戏中
 userControlPad.createButton.setEnabled(true);
 userControlPad.joinButton.setEnabled(true);
 userControlPad.cancelButton.setEnabled(false);
 firPad.statusText.setText("请创建或加入游戏!");
 }
 isParticipant = isCreator = false;
}
}

public void keyPressed(KeyEvent e)
{
TextField inputwords = (TextField) e.getSource();
if (e.getKeyCode() == KeyEvent.VK_ENTER)
{ // 处理回车按键事件
 if (userInputPad.userChoice.getSelectedItem().equals("所有用户"))
 { // 给所有人发信息
 try
 {
  // 发送信息
  outputStream.writeUTF(inputwords.getText());
  inputwords.setText("");
 }
 catch (Exception ea)
 {
  userChatPad.chatTextArea
   .setText("不能连接到服务器!\n");
  userListPad.userList.removeAll();
  userInputPad.userChoice.removeAll();
  inputwords.setText("");
  userControlPad.connectButton.setEnabled(true);
 }
 }
 else
 { // 给指定人发信息
 try
 {
  outputStream.writeUTF("/" + userInputPad.userChoice.getSelectedItem()
   + " " + inputwords.getText());
  inputwords.setText("");
 }
 catch (Exception ea)
 {
  userChatPad.chatTextArea
   .setText("不能连接到服务器!\n");
  userListPad.userList.removeAll();
  userInputPad.userChoice.removeAll();
  inputwords.setText("");
  userControlPad.connectButton.setEnabled(true);
 }
 }
}
}

public void keyTyped(KeyEvent e) {}
public void keyReleased(KeyEvent e) {}

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

2.开发客户端线程


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

import javax.swing.DefaultListModel;
import javax.swing.ListModel;

/**
* Created by Administrator on 2016/11/21.
*/
public class FIRClientThread extends Thread{
public FIRClient firClient;

public FIRClientThread(FIRClient firClient)
{
this.firClient = firClient;
}

public void dealWithMsg(String msgReceived)
{
if (msgReceived.startsWith("/userlist "))
{ // 若取得的信息为用户列表
 StringTokenizer userToken = new StringTokenizer(msgReceived, " ");
 int userNumber = 0;
 // 清空客户端用户列表
 firClient.userListPad.userList.removeAll();
 // 清空客户端用户下拉框
 firClient.userInputPad.userChoice.removeAll();
 // 给客户端用户下拉框添加一个选项
 firClient.userInputPad.userChoice.addItem("所有用户");
 while (userToken.hasMoreTokens())
 { // 当收到的用户信息列表中存在数据时
 String user = (String) userToken.nextToken(" "); // 取得用户信息
 if (userNumber > 0 && !user.startsWith("[inchess]"))
 { // 用户信息有效时
  firClient.userListPad.userList.add(user);// 将用户信息添加到用户列表中
  firClient.userInputPad.userChoice.addItem(user); // 将用户信息添加到用户下拉框中
 }
 userNumber++;
 }
 firClient.userInputPad.userChoice.setSelectedIndex(0);// 下拉框默认选中所有人
}
else if (msgReceived.startsWith("/yourname "))
{ // 收到的信息为用户本名时
 firClient.chessClientName = msgReceived.substring(10); // 取得用户本名
 firClient.setTitle("Java 五子棋客户端 " + "用户名:"
  + firClient.chessClientName); // 设置程序Frame的标题
}
else if (msgReceived.equals("/reject"))
{ // 收到的信息为拒绝用户时
 try
 {
 firClient.firPad.statusText.setText("不能加入游戏!");
 firClient.userControlPad.cancelButton.setEnabled(false);
 firClient.userControlPad.joinButton.setEnabled(true);
 firClient.userControlPad.createButton.setEnabled(true);
 }
 catch (Exception ef)
 {
 firClient.userChatPad.chatTextArea
  .setText("Cannot close!");
 }
 firClient.userControlPad.joinButton.setEnabled(true);
}
else if (msgReceived.startsWith("/peer "))
{ // 收到信息为游戏中的等待时
 firClient.firPad.chessPeerName = msgReceived.substring(6);
 if (firClient.isCreator)
 { // 若用户为游戏建立者
 firClient.firPad.chessColor = 1; // 设定其为黑棋先行
 firClient.firPad.isMouseEnabled = true;
 firClient.firPad.statusText.setText("黑方下...");
 }
 else if (firClient.isParticipant)
 { // 若用户为游戏加入者
 firClient.firPad.chessColor = -1; // 设定其为白棋后性
 firClient.firPad.statusText.setText("游戏加入,等待对手.");
 }
}
else if (msgReceived.equals("/youwin"))
{ // 收到信息为胜利信息
 firClient.isOnChess = false;
 firClient.firPad.setVicStatus(firClient.firPad.chessColor);
 firClient.firPad.statusText.setText("对手退出");
 firClient.firPad.isMouseEnabled = false;
}
else if (msgReceived.equals("/OK"))
{ // 收到信息为成功创建游戏
 firClient.firPad.statusText.setText("游戏创建等待对手");
}

else if (msgReceived.equals("/error"))
{ // 收到信息错误
 firClient.userChatPad.chatTextArea.append("错误,退出程序.\n");
}
else
{
 firClient.userChatPad.chatTextArea.append(msgReceived + "\n");
 firClient.userChatPad.chatTextArea.setCaretPosition(
  firClient.userChatPad.chatTextArea.getText().length());
}
}

public void run()
{
String message = "";
try
{
 while (true)
 {
 // 等待聊天信息,进入wait状态
 message = firClient.inputStream.readUTF();
 dealWithMsg(message);
 }
}
catch (IOException es){}
}
}

至此,网络版五子棋就算是开发完成了。关于这么多类和包的关系如下图:

Java实现五子棋网络版

来源:https://blog.csdn.net/qq_29496057/article/details/53258880

标签:java,五子棋
0
投稿

猜你喜欢

  • java.exe和javaw.exe的区别及使用方法

    2022-08-27 10:03:39
  • C#集合之集(set)的用法

    2023-05-18 06:04:53
  • 通过C#调用cmd来修改服务启动类型

    2022-01-02 04:25:46
  • SpringBoot整合MybatisPlus实现增删改查功能

    2022-10-31 05:24:15
  • C# WORD操作实现代码

    2023-11-20 05:16:25
  • Java使用TCP套接字实现多人聊天功能详解

    2023-12-16 15:42:40
  • 单例模式 分析代码优化方法

    2021-07-28 15:49:51
  • Spring bean对象实例化实现过程图解

    2023-01-02 07:32:13
  • Mybatis分页插件PageHelper的使用详解

    2022-02-26 16:43:05
  • Spring Boot 项目创建的详细步骤(图文)

    2023-03-23 20:11:55
  • java根据模板导出PDF的详细实现过程

    2022-04-07 21:48:52
  • Android实现九格智能拼图算法

    2021-11-07 22:40:11
  • C#(WinForm) ComboBox和ListBox添加项及设置默认选择项

    2022-05-13 10:09:49
  • Android实现GridView中ImageView动态变换的方法

    2022-06-21 06:16:55
  • Android添加水印的正确方法 只要三步!

    2022-08-07 16:48:15
  • java实现打砖块小游戏

    2021-07-26 14:47:11
  • c# 调用Win32Api关闭当前应用的方法

    2023-09-22 20:51:26
  • SpringBoot 利用thymeleaf自定义错误页面

    2023-11-29 08:29:55
  • Android Monkey压力测试详细介绍

    2021-10-24 08:02:37
  • Java lombok中@Accessors注解三个属性的作用

    2022-04-20 14:32:27
  • asp之家 软件编程 m.aspxhome.com