仅自学记录用,侵删
基于Socket编写的五子棋项目,采用TCP/IP协议。
操作方法:先开启一个服务端,查看服务器连接状态,再启动两个客户端就可以实现双人下棋
游戏规则:
(1)对局双方各执一色棋子
(2)空棋盘开局
(3)黑子先下,白子后下,交替下子,每次只能下一颗子
(4)棋子下在棋盘的空白点上,棋子下定后不得移动或拿走
(5)黑色或白色棋子在横、竖、斜方向上先连到五颗即获胜
实现步骤
(1)界面构建
构建界面分成了用户聊天区、按钮功能区、用户输入区、用户列表面板区、棋盘区
按钮区有连接到服务器、创建游戏、加入游戏、放弃游戏和退出程序,只有先连接到服务后,才可以开始游戏。
(2)下棋功能的实现
要将圆形的黑/白棋子落到线的交叉点处,所以一定要在棋盘区建立一个鼠标监听机制,再重写事件监听方法,画棋子可以使用fillOval方法。实现了在棋盘上正确的落子后,通过数组将棋盘上棋子的信息记录下来方便后面对输赢的判断。
(3)输赢判断
通过扫描各个横行、竖行、左右斜行来判断棋子是否有连续有5个以上相连的情况,则可以判断达到了胜利的条件
(4)TCP/IP的实现
服务端:在服务端显示玩家的连接状态,连接IP,因为存在功能按钮,所以同样要实现鼠标监听器
客户端:将上图界面构件的各个区其实都是JPanel或Panel,将客户端类继承Frame,然后将JPanel和Panel添加到Frame上,再构建服务端和客户端的数据传输即可
最后附上所有代码
com.chess.client
package com.chess.client;
//五子棋客户端
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Panel;
import java.awt.TextField;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.InetAddress;
import java.net.Socket;
import javax.swing.JFrame;
import javax.swing.JPanel;
import com.chess.pad.UserChatPad;
import com.chess.pad.UserControlPad;
import com.chess.pad.UserInputPad;
import com.chess.pad.UserListPad;
import com.chess.rule.Pad;
public class Client extends JFrame implements ActionListener,KeyListener{
//客户端套接口
Socket clientSocket;
//数据输入流
DataInputStream inputStream;
//数据输出流
DataOutputStream outputStream;
//用户名
String chessClientName = null;
//主机地址
String host = null;
//主机端口
int port = 13000;
//是否在聊天
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();
//下棋区
Pad pad = new Pad();
//面板区
Panel southPanel = new Panel();
Panel northPanel = new Panel();
Panel centerPanel = new Panel();
Panel eastPanel = new Panel();
//构造方法,创建界面
public Client() {
// TODO Auto-generated constructor stub
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);
pad.host = userControlPad.ipInputted.getText();
centerPanel.add(pad, 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
{ // 关闭下棋端口
pad.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
{
System.out.println( InetAddress.getLocalHost().toString());
// 创建客户端套接口
clientSocket = new Socket(serverIP, serverPort);
// 创建输入流
inputStream = new DataInputStream(clientSocket.getInputStream());
// 创建输出流
outputStream = new DataOutputStream(clientSocket.getOutputStream());
// 创建客户端线程
ClientThread clientthread = new ClientThread(this);
// 启动线程,等待聊天信息
clientthread.start();
isOnChat = true;
return true;
}
catch (IOException ex)
{
userChatPad.chatTextArea
.setText("不能连接!\n");
}
return false;
}
@Override
public void keyTyped(KeyEvent e) {
// TODO Auto-generated method stub
}
@Override
public void keyPressed(KeyEvent e) {
// TODO Auto-generated method stub
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);
}
}
}
}
@Override
public void keyReleased(KeyEvent e) {
// TODO Auto-generated method stub
}
@Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
if (e.getSource() == userControlPad.connectButton)
{ // 连接到主机按钮单击事件
host = pad.host = userControlPad.ipInputted.getText(); // 取得主机地址
try
{
if (connectToServer(host, port))
{ // 成功连接到主机时,设置客户端相应的界面状态
userChatPad.chatTextArea.setText("");
userControlPad.connectButton.setEnabled(false);
userControlPad.createButton.setEnabled(true);
userControlPad.joinButton.setEnabled(true);
pad.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
{ // 关闭游戏端口
pad.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))
{ // 若未选中要加入的用户,或选中的用户已经在游戏,则给出提示信息
pad.statusText.setText("必须选择一个用户!");
}
else
{ // 执行加入游戏的操作
try
{
if (!isGameConnected)
{ // 若游戏套接口未连接
if (pad.connectServer(pad.host, pad.port))
{ // 若连接到主机成功
isGameConnected = true;
isOnChess = true;
isParticipant = true;
userControlPad.createButton.setEnabled(false);
userControlPad.joinButton.setEnabled(false);
userControlPad.cancelButton.setEnabled(true);
pad.thread.sendMessage("/joingame "
+ (String)userListPad.userList.getSelectedItem() + " "
+ chessClientName);
}
}
else
{ // 若游戏端口连接中
isOnChess = true;
isParticipant = true;
userControlPad.createButton.setEnabled(false);
userControlPad.joinButton.setEnabled(false);
userControlPad.cancelButton.setEnabled(true);
pad.thread.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 (pad.connectServer(pad.host, pad.port))
{ // 若连接到主机成功
isGameConnected = true;
isOnChess = true;
isCreator = true;
userControlPad.createButton.setEnabled(false);
userControlPad.joinButton.setEnabled(false);
userControlPad.cancelButton.setEnabled(true);
pad.thread.sendMessage("/creatgame "
+ "[inchess]" + chessClientName);
}
}
else
{ // 若游戏端口连接中
isOnChess = true;
isCreator = true;
userControlPad.createButton.setEnabled(false);
userControlPad.joinButton.setEnabled(false);
userControlPad.cancelButton.setEnabled(true);
pad.thread.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)
{ // 游戏中
pad.thread.sendMessage("/giveup " + chessClientName);
pad.setVicStatus(-1 * pad.chessColor);
userControlPad.createButton.setEnabled(true);
userControlPad.joinButton.setEnabled(true);
userControlPad.cancelButton.setEnabled(false);
pad.statusText.setText("请创建或加入游戏!");
}
if (!isOnChess)
{ // 非游戏中
userControlPad.createButton.setEnable