基于Socket的五子棋游戏

本文记录了一个使用Java和Socket实现的双人在线五子棋游戏。游戏规则包括黑子先手,交替下子,连五获胜等。项目通过TCP/IP协议进行通信,包括界面构建、下棋功能、输赢判断和TCP/IP实现四个步骤。源代码分为com.chess.client、com.chess.pad、com.chess.rule和com.chess.server四部分。
摘要由CSDN通过智能技术生成

仅自学记录用,侵删

基于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
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值