服务端
客户端
项目结构
源码
1、服务端:主函数
package jiemian;
import moxing.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.util.*;
public class jiemian1 extends JFrame implements ActionListener {
JLabel bq = new JLabel("端口号");// 创建标签 用于显示文本框中的内容表示的是什么
JTextField wbk = new JTextField("9999");// 创建文本框 并初始化文本框中的内容
JButton b1 = new JButton("开启");// 创建 开始 按钮
JButton b2 = new JButton("关闭");// 创建 关闭 按钮
JPanel p1 = new JPanel();// 创建面板用于添加 按钮 标签 文本框
Vector online = new Vector();// 用于存储在线用户的集合
JList lis = new JList();// 创建列表
JScrollPane gd = new JScrollPane(lis);
JSplitPane fg = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, gd, p1);
ZThread zt;// 创建主线程对象
public static void main(String[] args) {
jiemian1 one = new jiemian1();
}
public jiemian1()// 构造函数
{
this.cskj();// 初始化控件
this.sjjt();// 初始化监听scrollPane.getViewport().setView(myList);
this.csct();// 初始化窗体
}
public void cskj()// 初始化组件的函数
{
p1.setLayout(null);
bq.setBounds(20, 20, 50, 50);
p1.add(bq);// 将标签添加进面板
wbk.setBounds(70, 35, 50, 20);
p1.add(wbk);// 将文本框添加进面板
b1.setBounds(15, 70, 60, 20);
p1.add(b1);// 将开启服务器按钮添加进面板
b2.setBounds(85, 70, 60, 20);
b2.setEnabled(false);// 将关闭按钮设置成不可操作的
p1.add(b2);// 将关闭按钮添加进面板
fg.setDividerLocation(230);// 设置分割条的位置
fg.setDividerSize(4);// 设置分割条的大小
}
public void csct()// 初始化窗体的函数
{
this.add(fg);
this.setTitle("网络象棋服务器");
this.setSize(420, 400);
int wieth = Toolkit.getDefaultToolkit().getScreenSize().width;
int heigth = Toolkit.getDefaultToolkit().getScreenSize().height;
this.setLocation(wieth / 2 - 200, heigth / 2 - 200);
this.setVisible(true);
this.setResizable(true);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public void sjjt()// 为组件做监听的函数
{
b1.addActionListener(this);
b2.addActionListener(this);
}
public void sjnr1()// 按下启动按钮后做的动作
{
int ii = 0;
try {
String str = wbk.getText().trim();
ii = Integer.parseInt(str);
} catch (Exception e) {
JOptionPane.showMessageDialog(this, "端口号填写错误,为整数(0-65535)");
return;
}
if (ii < 0 || ii > 65535) {
JOptionPane.showMessageDialog(this, "端口号填写错误,为整数(0-65535)");
return;
}
JOptionPane.showMessageDialog(this, "服务器开启成功");
b2.setEnabled(true);// 将关闭按钮设为可操作
b1.setEnabled(false);// 将开启按钮设为不可操作
this.wbk.setEditable(false);
this.sxlist();
zt = new ZThread(this);
zt.start();// 开启主线程
}
public void sjnr2()// 按下关闭按钮后的动作
{
JOptionPane.showMessageDialog(this, "服务器关闭成功");
this.b2.setEnabled(false);// 将关闭按钮设为不可操作
this.b1.setEnabled(true);// 将开启按钮设为可操作
this.wbk.setEditable(true);
zt.shengm(false);// 将主线程的生命设为False
zt.close();// 关闭ss he s
online.clear();// 将在线用户清除
lis.setListData(online);// 刷新在线用户列表
}
public void sxlist()// 刷新列表的函数
{
// for(int i=0;i<20;i++){
// online.add("dfsdfasdf");
// }
lis.setListData(online);
}
public Vector getVector() {
return online;
}
public void actionPerformed(ActionEvent e)// 重写事件里的方法
{
if (e.getSource() == b1) {
this.sjnr1();
} else if (e.getSource() == b2) {
this.sjnr2();
}
}
}
2、服务端:主线程
package moxing;
import jiemian.jiemian1;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Vector;
public class ZThread extends Thread {
ServerSocket ss;// 声明ServerSocket 引用
boolean flag = true;
jiemian1 jm;//
FThread zh;
public ZThread(jiemian1 jm)// 构造函数
{
this.jm = jm;
this.cjss();// 对ServerSocket 进行初始化
}
public void cjss()// ServerSocket 初始化的函数
{
try {
ss = new ServerSocket(9999);
} catch (Exception e) {
System.out.println(e.toString());
}
System.out.println("ServerSocket 初始化成功");
}
public void shengm(boolean a)// 设置主线程生命的方法
{
flag = a;
}
int sum = 1;
public void run()// run 方法
{
while (flag) {
try {
System.out.println("正在等待接收第:" + sum + "个客户端的链接");
Socket s = ss.accept();// 接收 Socket 对象,也就是等待客户端的链接
zh = new FThread(jm, s);// 创建分线程的对象
zh.start();// 启动分线程
} catch (Exception e) {
System.out.println(e.toString());
}
System.out.println("主线程接收到客户端的链接 Socket 对象创建成功");
sum++;// 用于显示第几个客户端
}
System.out.println("主线程正常关闭");
}
public void close()// 关闭 ServerSocket 和 Socket 的方法
{
try {
ss.close();// 关闭serversocket 方法
zh.clse();// 调用分线程的服务器关闭方法
} catch (Exception e) {
System.out.println("服务关闭异常" + e.toString());
}
}
}
3、服务端:子线程
package moxing;
import jiemian.jiemian1;//导入界面包
import java.net.*;
import java.io.*;
import java.util.*;
public class FThread extends Thread {
Socket s;// 创建Socket 引用
Vector v = new Vector();// 建立Vector 集合
boolean sm = true;// 初始化辅助线程的生命
DataInputStream din;// 声明数据输入流对象引用
DataOutputStream dou;// 声明数据输出流对象引用
jiemian1 jm;// 声明主界面的类引用
public FThread(jiemian1 jm, Socket s)// 构造方法 参数 从主线程传入的 Socket 对象
{
this.jm = jm;
this.s = s;
this.cjfzxc();// 初始化数据流
}
public void cjfzxc()// 创建数据流的方法
{
try {
din = new DataInputStream(s.getInputStream());
dou = new DataOutputStream(s.getOutputStream());
} catch (Exception e) {
System.out.println("辅助线程 数据流的创建异常:" + e.toString());
}
}
public void shengm1(boolean boo)// 改变辅助线程的生命
{
sm = boo;
}
public void run()// run 方法
{
System.out.println("进入辅助线程");
while (sm) {
try {
String str = din.readUTF().trim();
System.out.println("客户端发来的昵称:" + str);
if (str.startsWith("#nc#"))// 客户端新用户上线
{
this.xyh(str);// 用户上线的方法
} else if (str.startsWith("#likai#"))// 客户端离开
{
this.yhlk(str);// 用户离开的方法
} else if (str.startsWith("#tiaozhan#"))// 客户端发送挑战的信息
{
this.yhfqtz(str);
} else if (str.startsWith("#jieshou#"))// 客户端接受挑战
{
this.yhjstz(str);
} else if (str.startsWith("#jjtz#"))// 客户端拒绝挑战
{
this.yhjjtz(str);// 被挑战者拒绝挑战的方法
} else if (str.startsWith("#yjjstz#"))// 客户端已经接受了挑战(第一种情况)
{
this.yjjstz(str);
} else if (str.startsWith("#yhfm#"))// 客户端已经接受了挑战 (第二种情况)
{
this.yhfm(str);
} else if (str.startsWith("#renshu#"))// 客户端认输的方法
{
this.renshu(str);
} else if (str.startsWith("#yidong#"))// 收到客户端发来移动棋子的信息
{
this.yidong(str);
}
} catch (Exception e) {
System.out.println("辅助线程读取异常" + e.toString());
}
}
}
public void xyh(String str)// 新用户的方法
{
String name = str.substring(4);
this.setName(name);
boolean boo = false;
v = jm.getVector();
for (Iterator it = v.iterator(); it.hasNext();) {
FThread aa = (FThread) it.next();
String bb = aa.getName();
if (bb.equals(name)) {
boo = true;
break;
}
}
if (boo == true)// 如果出现重名
{
try {
this.dou.writeUTF("#chongming#");
this.s.close();
this.din.close();
this.dou.close();
this.sm = false;
System.out.println("重名了");
} catch (Exception e) {
}
} else {
try {
this.dou.writeUTF("#nochongming#");
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
v = jm.getVector();// 获取主界面的集合
v.add(this);// 讲读取到的昵称添加进集合
jm.sxlist();// 更新主界面列表中的集合数据
for (Iterator it = v.iterator(); it.hasNext();) {
FThread na = (FThread) it.next();// 获取服务器中的所有线程
for (int i = 0; i < v.size(); i++)// 再次便利获取所有线程的名字
{
FThread ft = (FThread) v.get(i);
try {
// 让每一个线程把所有线程的名字都发送到每个客户端
na.dou.writeUTF("#liebiao#" + ft.getName());
} catch (Exception e) {
}
}
if (!na.getName().equals(name)) {// 将新上线的用户名字发给每个在线用户
try {
na.dou.writeUTF("#tishi#" + name);
} catch (Exception e) {
}
}
}
}
}
public void yhlk(String str)// 用户离开的方法
{
System.out.println("收到用户离开的消息");
String name = str.substring(7);
v = this.jm.getVector();
for (Iterator it = v.iterator(); it.hasNext();) {
FThread ft = (FThread) it.next();
if (!(ft.getName().equals(name)))// 将离开的用户发送给每个在线用户
{
try {
ft.dou.writeUTF("#likai#" + name);
} catch (Exception e) {
}
} else if (ft.getName().equals(name))// 将下线的用的线程关闭
{
try {
ft.din.close();
ft.dou.close();
ft.s.close();
ft.sm = false;
} catch (Exception e) {
}
}
}
for (Iterator it = v.iterator(); it.hasNext();)// 便利服务器的列表讲下线用户删除
{
FThread fy = (FThread) it.next();
if (fy.getName().equals(name)) {
v.remove(fy);
this.jm.sxlist();
}
}
}
public void yhfqtz(String str)// 用户发起挑战的方法
{
String name1 = this.getName();// 发起挑战的人
String name2 = str.substring(10);
v = this.jm.getVector();
for (Iterator it = v.iterator(); it.hasNext();) {
FThread ff = (FThread) it.next();// 遍历得到所有用户
if (ff.getName().equals(name2))// 得到被挑战人的线程
{
try {
ff.dou.writeUTF("#tiaozhan#" + name1);
} catch (Exception e) {
}
}
}
}
public void yhjstz(String str)// 用户接受挑战的方法
{
String name = str.substring(9);// 接收到挑战者的名字
v = this.jm.getVector();
for (Iterator it = v.iterator(); it.hasNext();) {
FThread ff = (FThread) it.next();
if (ff.getName().equals(name))// 遍历取得被挑战者的线程
{
try {
ff.dou.writeUTF("#jieshou#" + this.getName());// 将接受挑战的人名字发送给挑战者
} catch (Exception e) {
}
}
}
}
public void yhjjtz(String str)// 用户拒绝挑战的方法
{
String name = str.substring(6);// 获取挑战者的名字
v = this.jm.getVector();
for (Iterator it = v.iterator(); it.hasNext();) {
FThread ff = (FThread) it.next();
if (ff.getName().equals(name))// 遍历得到挑战者的线程
{
try {
ff.dou.writeUTF("#jjtz#" + this.getName());// 将被挑战者的名字发送给挑战者
} catch (Exception e) {
}
}
}
}
public void yjjstz(String str)// 自己已经接受挑战了 发送给另一个接受挑战的玩家一个信息
{
String name = str.substring(8);
v = this.jm.getVector();
for (Iterator it = v.iterator(); it.hasNext();) {
FThread ff = (FThread) it.next();
if (ff.getName().equals(name)) {
try {
ff.dou.writeUTF("#yjjstz#" + this.getName());
} catch (Exception e) {
}
}
}
}
public void yhfm(String str)// 用户繁忙不能接受挑战
{
String name = str.substring(6);// 获取发起挑战的人
v = this.jm.getVector();
for (Iterator it = v.iterator(); it.hasNext();) {
FThread ff = (FThread) it.next();
if (ff.getName().equals(name)) {
try {
ff.dou.writeUTF("#yhfm#" + this.getName());// 将被挑战者繁忙的信息发送给挑战者
} catch (Exception e) {
}
}
}
}
public void renshu(String str)// 用户认输的方法
{
String name = str.substring(8);
v = this.jm.getVector();
for (Iterator it = v.iterator(); it.hasNext();) {
FThread ff = (FThread) it.next();
if (ff.getName().equals(name)) {
try {
ff.dou.writeUTF("#renshu#" + this.getName());
} catch (Exception e) {
}
}
}
}
public void zouqi()// 用户奏起的信息
{
}
public void clse()// 服务器关闭的后调用的方法
{
v = this.jm.getVector();
try {
for (Iterator it = v.iterator(); it.hasNext();)// 给每个线程发送服务器关闭的信息
{
FThread ft = (FThread) it.next();
ft.dou.writeUTF("#close#");
break;
}
this.din.close();
this.dou.close();
this.s.close();
} catch (Exception e) {
}
}
public void yidong(String str) {
String na = str.substring(8, str.length() - 4);// 获取对方得名字
v = this.jm.getVector();
for (Iterator it = v.iterator(); it.hasNext();) {
FThread ft = (FThread) it.next();
if (ft.getName().equals(na)) {
try {
ft.dou.writeUTF(str);
break;
} catch (Exception e) {
}
}
}
}
}
4、客户端:主函数
package jiem;
import MX.lianjie;
import java.awt.Color;
import java.awt.Font;
import java.awt.Toolkit;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
import java.util.*;
public class mainJM extends JFrame implements ActionListener {
public static final Color bgColor = new Color(245, 250, 160);// 棋盘的背景色
public static final Color focusbg = new Color(242, 242, 242);// 棋子选中后的背景色
public static final Color focuschar = new Color(96, 95, 91);// 棋子选中后的字符颜色
public static final Color color1 = new Color(249, 183, 100);// 红方的颜色
public static final Color color2 = Color.white;// 白方的颜色
int kuan = 50;// 楚河汉界的宽度
QZ[][] arr = new QZ[9][10];// 创建一个用于添加棋子的二维数组
boolean caiPan = false;// 可否走棋的标志位
int color = 0;// 0 代表红棋,1代表白棋
JLabel bq1, bq2, bq3;
JTextField wbk1, wbk2;
JTextField wbk3 = new JTextField("Play1");
JButton b1, b2, b3, b4, b5, b6;
JComboBox xllb;// 下拉列表
JPanel p1;
JSplitPane fg;
Vector vv = new Vector();
lianjie lj;// 声明连接类的引用
QP qp;// 声明棋盘的引用
public mainJM() {
this.cjzj();// 初始化组件
this.cjjt();// 初始化监听
this.cshzt();// 初始化组件的状态
this.cjct();// 初始化窗体
this.cshqz();// 初始化棋子
}
public void cjzj()// 创建组件的方法
{
qp = new QP(arr, kuan, this);
p1 = new JPanel();
p1.setLayout(null);
Font ft = new Font("楷体", Font.PLAIN, 22);
bq1 = new JLabel("主机名");
bq1.setBounds(20, 20, 80, 80);
bq1.setFont(ft);
p1.add(bq1);
bq2 = new JLabel("端口号");
bq2.setBounds(21, 60, 80, 80);
bq2.setFont(ft);
p1.add(bq2);
bq3 = new JLabel("昵 称");
bq3.setBounds(22, 100, 80, 80);
bq3.setFont(ft);
p1.add(bq3);
wbk1 = new JTextField("127.0.0.1");
wbk1.setBounds(100, 48, 80, 25);
p1.add(wbk1);
wbk2 = new JTextField("9999");
wbk2.setBounds(100, 88, 80, 25);
p1.add(wbk2);
// wbk3=new JTextField("Play1");
wbk3.setBounds(100, 128, 80, 25);
p1.add(wbk3);
b1 = new JButton("链接");
b1.setBounds(15, 170, 90, 20);
p1.add(b1);
b2 = new JButton("断开");
b2.setBounds(115, 170, 90, 20);
p1.add(b2);
xllb = new JComboBox();
xllb.setBounds(65, 200, 90, 20);
p1.add(xllb);
b3 = new JButton("挑战");
b3.setBounds(15, 230, 90, 20);
p1.add(b3);
b4 = new JButton("认输");
b4.setBounds(115, 230, 90, 20);
p1.add(b4);
b5 = new JButton("接受挑战");
b5.setBounds(15, 260, 90, 20);
p1.add(b5);
b6 = new JButton("拒绝挑战");
b6.setBounds(115, 260, 90, 20);
p1.add(b6);
fg = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, qp, p1);
fg.setDividerLocation(520);
fg.setDividerSize(4);
}
public Vector getVector() {
return vv;
}
public void sxlb() {
this.xllb.setModel(new DefaultComboBoxModel(vv));
}
public JTextField getWbk3() {
return wbk3;
}
public void cjct()// 创建窗体
{
this.add(fg);
this.setTitle("网络象棋客户端");
this.setSize(750, 550);
int aa = Toolkit.getDefaultToolkit().getScreenSize().width;
int bb = Toolkit.getDefaultToolkit().getScreenSize().height;
this.setLocation(aa / 2 - 500, bb / 2 - 350);
this.setVisible(true);
this.setResizable(true);//窗体大小可变
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.out.println("guanbi");
System.exit(0);
}
});
}
public void cjjt()// 创建监听的方法
{
b1.addActionListener(this);
b2.addActionListener(this);
b3.addActionListener(this);
b4.addActionListener(this);
b5.addActionListener(this);
b6.addActionListener(this);
wbk1.addActionListener(this);
wbk2.addActionListener(this);
wbk3.addActionListener(this);
}
public void cshzt()// 初始化组件的方法
{
b2.setEnabled(false);
b3.setEnabled(false);
b4.setEnabled(false);
b5.setEnabled(false);
b6.setEnabled(false);
xllb.setEnabled(false);
}
public void cshqz() {
arr[0][0] = new QZ(color1, "車", 0, 0);
arr[1][0] = new QZ(color1, "馬", 1, 0);
arr[2][0] = new QZ(color1, "相", 2, 0);
arr[3][0] = new QZ(color1, "仕", 3, 0);
arr[4][0] = new QZ(color1, "帥", 4, 0);
arr[5][0] = new QZ(color1, "仕", 5, 0);
arr[6][0] = new QZ(color1, "相", 6, 0);
arr[7][0] = new QZ(color1, "馬", 7, 0);
arr[8][0] = new QZ(color1, "車", 8, 0);
arr[1][2] = new QZ(color1, "砲", 1, 2);
arr[7][2] = new QZ(color1, "砲", 7, 2);
arr[0][3] = new QZ(color1, "兵", 0, 3);
arr[2][3] = new QZ(color1, "兵", 2, 3);
arr[4][3] = new QZ(color1, "兵", 4, 3);
arr[6][3] = new QZ(color1, "兵", 6, 3);
arr[8][3] = new QZ(color1, "兵", 8, 3);
arr[0][9] = new QZ(color2, "車", 0, 9);
arr[1][9] = new QZ(color2, "馬", 1, 9);
arr[2][9] = new QZ(color2, "象", 2, 9);
arr[3][9] = new QZ(color2, "士", 3, 9);
arr[4][9] = new QZ(color2, "將", 4, 9);
arr[5][9] = new QZ(color2, "士", 5, 9);
arr[6][9] = new QZ(color2, "象", 6, 9);
arr[7][9] = new QZ(color2, "馬", 7, 9);
arr[8][9] = new QZ(color2, "車", 8, 9);
arr[1][7] = new QZ(color2, "炮", 1, 7);
arr[7][7] = new QZ(color2, "炮", 7, 7);
arr[0][6] = new QZ(color2, "卒", 0, 6);
arr[2][6] = new QZ(color2, "卒", 2, 6);
arr[4][6] = new QZ(color2, "卒", 4, 6);
arr[6][6] = new QZ(color2, "卒", 6, 6);
arr[8][6] = new QZ(color2, "卒", 8, 6);
}
public void actionPerformed(ActionEvent e) {
if (e.getSource() == this.b1) {
if (this.yzdkh())// 调用验证端口号的方法
{
this.qidong();// 调用启动按钮的操作
}
} else if (e.getSource() == this.b2) {
this.setGuanbi();
} else if (e.getSource() == this.b3) {
this.tiaozhan();
} else if (e.getSource() == this.b4) {
this.renshu();
} else if (e.getSource() == this.b5) {
this.jieshou();
} else if (e.getSource() == this.b6) {
this.jujue();
}
}
public void qidong()// 点击启动按钮的方法
{
lj = new lianjie(this, qp);// 创建连接类对象 查看是否链接成功
if (lj.cjsocket()) {
wbk1.setEditable(false);
wbk2.setEditable(false);
wbk3.setEditable(false);
b2.setEnabled(true);// 关闭设为可用
b1.setEnabled(false);// 开启设为不可用
b3.setEnabled(true);// 挑战设为可用
b4.setEnabled(false);
b5.setEnabled(false);
b6.setEnabled(false);
xllb.setEnabled(true);// 下拉列表设为可用
lj.start();// 启动客户端线程
} else {
JOptionPane.showMessageDialog(this, "链接失败");
}
}
public void setGuanbi()// 点击关闭按钮的方法
{
wbk1.setEditable(true);// 主机设为可用
wbk2.setEditable(true);// 端口设为可用
wbk3.setEditable(true);// 设为可用户
b2.setEnabled(false);// 关闭设为不可用
b1.setEnabled(true);// 开启设为可用
b3.setEnabled(false);// 挑战设为不可用
b4.setEnabled(false);// 认输设为不可用
b6.setEnabled(false);// jieshou挑战设为不可用
b5.setEnabled(false);// 拒绝挑战设为不可用
xllb.setEnabled(false);// 下拉列表设为不可用
lj.zdlk();// 调用客户端线程的主动离开方法
// JOptionPane.showMessageDialog(this,"关闭链接");
}
public void tiaozhan()// 挑战
{
String str = (String) xllb.getSelectedItem();// 获取玩家姓名
if (str == null || str == "") {// 判断是否取到了玩家姓名
JOptionPane.showMessageDialog(this, "请选中一名玩家!");
} else {
lj.fqtz(str);// 调用发起挑战的方法并将选中的玩家做参数传进去
this.caiPan = true;
this.color = 0;// 将自己设为红旗
JOptionPane.showMessageDialog(this, "已发出挑战! 请稍等!!");
}
}
public void renshu()// 主动认输
{
wbk1.setEditable(false);
wbk2.setEditable(false);
wbk3.setEditable(false);
b2.setEnabled(true);// 关闭设为可用
b1.setEnabled(false);// 开启设为不可用
b3.setEnabled(true);// 挑战设为可用
b4.setEnabled(false);
b5.setEnabled(false);
b6.setEnabled(false);
xllb.setEnabled(true);// 下拉列表设为可用
lj.yhrs();// 调用连接里的主动认输的方法
// JOptionPane.showMessageDialog(this,"认输");
}
public void renshu1()// 对方认输调用的方法
{
wbk1.setEditable(false);
wbk2.setEditable(false);
wbk3.setEditable(false);
b2.setEnabled(true);// 关闭设为可用
b1.setEnabled(false);// 开启设为不可用
b3.setEnabled(true);// 挑战设为可用
b4.setEnabled(false);
b5.setEnabled(false);
b6.setEnabled(false);
xllb.setEnabled(true);// 下拉列表设为可用
}
public void setCaiPan() {
caiPan = true;
}
public void jieshou()// 接受挑战
{
this.caiPan = true;
this.color = 1;// 将自己设为白棋
wbk1.setEditable(false);// 主机设为可用
wbk2.setEditable(false);// 端口设为可用
wbk3.setEditable(false);// 设为可用户
b2.setEnabled(false);// 关闭设为不可用
b1.setEnabled(false);// 开启设为可用
b3.setEnabled(false);// 挑战设为不可用
b4.setEnabled(true);// 认输设为不可用
b6.setEnabled(false);// 发起挑战设为不可用
b5.setEnabled(false);// 拒绝挑战设为不可用
xllb.setEnabled(false);// 下拉列表设为不可用
lj.jieshou1();// 调用链接类中被挑战者接受挑战的方法
JOptionPane.showMessageDialog(this, "请走白棋!!");
}
public void jieshou1()// 挑战者接收到被挑战者同意的放啊
{
wbk1.setEditable(false);// 主机设为可用
wbk2.setEditable(false);// 端口设为可用
wbk3.setEditable(false);// 设为可用户
b2.setEnabled(false);// 关闭设为不可用
b1.setEnabled(false);// 开启设为可用
b3.setEnabled(false);// 挑战设为不可用
b4.setEnabled(true);// 认输设为不可用
b6.setEnabled(false);// 发起挑战设为不可用
b5.setEnabled(false);// 拒绝挑战设为不可用
xllb.setEnabled(false);// 下拉列表设为不可用
JOptionPane.showMessageDialog(this, "请走红旗!!");
}
public void yjjstz()// 对方已经接受了挑战自己不能同对方挑战
{
wbk1.setEditable(false);
wbk2.setEditable(false);
wbk3.setEditable(false);
b2.setEnabled(true);// 关闭设为可用
b1.setEnabled(false);// 开启设为不可用
b3.setEnabled(true);// 挑战设为可用
b4.setEnabled(false);
b5.setEnabled(false);
b6.setEnabled(false);
xllb.setEnabled(true);// 下拉列表设为可用
// lj.start();//启动客户端线程
}
public void jujue()// 拒绝挑战
{
wbk1.setEditable(false);
wbk2.setEditable(false);
wbk3.setEditable(false);
b2.setEnabled(true);// 关闭设为可用
b1.setEnabled(false);// 开启设为不可用
b3.setEnabled(true);// 挑战设为可用
b4.setEnabled(false);
b5.setEnabled(false);
b6.setEnabled(false);
xllb.setEnabled(true);// 下拉列表设为可用
lj.jujue1();// 调用连接类中的被挑战方拒绝挑战的方法
}
public void tz()// 对方发来挑战后讲接受和拒绝按钮设为可用
{
wbk1.setEditable(false);// 主机设为可用
wbk2.setEditable(false);// 端口设为可用
wbk3.setEditable(false);// 设为可用户
b2.setEnabled(false);// 关闭设为不可用
b1.setEnabled(false);// 开启设为可用
b3.setEnabled(false);// 挑战设为不可用
b4.setEnabled(false);// 认输设为不可用
b6.setEnabled(true);// 发起挑战设为可用
b5.setEnabled(true);// 拒绝挑战设为可用
xllb.setEnabled(false);// 下拉列表设为不可用
}
public boolean yzdkh()// 验证端口号是否正确 如果正确返回true 不正确返回false
{
int port = 0;
try {
String str = this.wbk2.getText().trim();
port = Integer.parseInt(str);
} catch (Exception e) {
JOptionPane.showMessageDialog(this, "请输入整数(0-65535)");
return false;
}
if (port < 0 || port > 65535) {
JOptionPane.showMessageDialog(this, "请输入整数(0-65535)");
return false;
}
return true;
}
public void next()// 重置棋子
{
wbk1.setEditable(false);
wbk2.setEditable(false);
wbk3.setEditable(false);
b2.setEnabled(true);// 关闭设为可用
b1.setEnabled(false);// 开启设为不可用
b3.setEnabled(true);// 挑战设为可用
b4.setEnabled(false);
b5.setEnabled(false);
b6.setEnabled(false);
xllb.setEnabled(true);// 下拉列表设为可用
for (int i = 0; i < 9; i++) {
for (int j = 0; j < 10; j++) {
arr[i][j] = null;
}
}
this.cshqz();
// this.repaint();
}
public static void main(String[] args) {
mainJM one = new mainJM();
}
}
5、客户端:子线程
package MX;
import jiem.*;
import java.io.*;
import java.net.Socket;
import javax.swing.*;
import java.util.*;
public class lianjie extends Thread {
Socket s;
JTextField wbk;
boolean flag = true;// 线程的标志位
boolean flag1 = true;// 创建Socket 的标志位
DataInputStream dis;
DataOutputStream dos;
mainJM mj;// 声明主界面类对象引用
QP qp;// 声明棋盘类的引用
Vector v;
String tzz = "";// 用于记录发起挑战的名字
String btzz = "";// 用于记录被挑战者的名字
public lianjie(mainJM jm, QP qp) {
this.qp = qp;
this.mj = jm;
}
public DataOutputStream fhyd() {
return dos;
}
public boolean cjsocket() {
try {
s = new Socket("127.0.0.1", 9999);
} catch (Exception e) {
System.out.println("建立socket异常:" + e.toString());
return false;
}
return flag1;
}
public void schl() {
try {
dis = new DataInputStream(s.getInputStream());// 创建输入流
dos = new DataOutputStream(s.getOutputStream());// 创建输出流
wbk = mj.getWbk3();
String name = wbk.getText().trim();
dos.writeUTF("#nc#" + name);// 将昵称发送到服务器
} catch (Exception e) {
System.out.println("建立数据流异常" + e.toString());
}
}
public void run()// run方法
{
this.schl();// 调用创建数据输入输出流的方法
while (flag) {
System.out.println("循环");
try {
String str = dis.readUTF().trim();
if (str.startsWith("#chongming#"))// 收到服务器发来的重名信息
{
this.chongm();// 调用重名的方法
} else if (str.startsWith("#close#"))// 收到服务器关闭的信息
{
this.clse();// 调用服务器关闭是客户端的操作
} else if (str.startsWith("#liebiao#"))// 收到服务器发来的列表
{
this.lj(str);// 调用发来列表的方法
} else if (str.startsWith("#likai#"))// 收到用户离开的信息
{
this.likai(str);// 调用 用户离开的方法
} else if (str.startsWith("#tiaozhan#"))// 收到挑战的信息
{
if (btzz == "")// 收到挑战信息时判断挑战者是否无记录
{
this.tiaozhan(str);
} else // 如果收到挑战信息btzz有记录
{
this.btzzyjl(str);
}
} else if (str.startsWith("#jjtz#"))// 收到拒绝挑战的信息
{
this.jujue(str);
} else if (str.startsWith("#jieshou#"))// 收到对方接受挑战的信息
{
if (btzz == "")// 如果被挑战者没有记录
{
this.jieshou(str);// 调用被挑战者接受的方法
} else {
this.yjjs(str);// 调用挑战者已接受挑战的方法
}
} else if (str.startsWith("#yjjstz#"))// 接受到挑战者发送来的已接受过其他人挑战的消息
{
this.yjjstz(str);// 当知道挑战者已经接受其他人挑战的消息是做的操作
} else if (str.startsWith("#yhfm#"))// 用户忙
{
this.mang(str);
} else if (str.startsWith("#zq#"))// 走棋
{
this.kaiqi();
} else if (str.startsWith("#renshu#"))// 认输
{
this.rens(str);
} else if (str.startsWith("#tishi#"))// 用户上线
{
this.tishi(str);
} else if (str.startsWith("#yidong#"))// 收到用户走棋的信息
{
this.Move(str);
} else if (str.startsWith("#nochongming#"))// 收到用户走棋的信息
{
JOptionPane.showMessageDialog(this.mj, "链接成功");
}
} catch (Exception e) {
System.out.println("客户端读取流 读取异常" + e.toString());
}
}
}
public void chongm() {
JOptionPane.showMessageDialog(this.mj, "该昵称已被玩家占用");
System.out.println("站用户");
try {
this.mj.setGuanbi();// 调用主界面的关闭方法
this.flag = false;// 将本线程的标志位设为false 结束run 方法
this.dis.close();// 关闭输入输出流
this.dos.close();//
this.s.close();// 关闭Socket
} catch (Exception e) {
System.out.println("关闭流异常" + e.toString());
}
}
public void lj(String str)// 刷新列表的方法
{
String aa = str.substring(9);
String bb = this.mj.getWbk3().getText().trim();
v = this.mj.getVector();
if (!aa.equals(bb) && !v.contains(aa))// 当接收的名字不是本玩家名
// 并且不在本类列表中时 添加进来
{
v.add(aa);
this.mj.sxlb();// 刷新列表
}
}
public void clse()// 收到服务器关闭时的具体操作方法
{
try {
this.mj.setGuanbi();// 调用主界面关闭的方法
this.flag = false;// 将本线程的标志位设为false 结束run 方法
this.dis.close();// 关闭输入输出流
this.dos.close();//
this.s.close();// 关闭Socket
} catch (Exception e) {
}
JOptionPane.showMessageDialog(this.mj, "服务器已经关闭!!!");
}
public void likai(String str)// 当收到用户离开时的方法
{
String aa = str.substring(7);
v = this.mj.getVector();
v.remove(aa);
this.mj.sxlb();
JOptionPane.showMessageDialog(this.mj, aa + "用户已离开!");
}
public void yjjs(String str)// 另一个用户发来接受挑战的信息
{
String name = str.substring(9);// 获取另一个接受挑战的玩家名字
try {
this.dos.writeUTF("#yjjstz#" + name);
} catch (Exception e) {
}
}
public void yjjstz(String str)// 挑战者已经接受挑战
{
String name = str.substring(8);
tzz = "";// 将挑战者的名字清空
this.mj.yjjstz();// 调用主界面中挑战者已经在同别人挑战自己不能同发起者挑战
JOptionPane.showMessageDialog(this.mj, name + "正在和其他玩家进行挑战!!");
}
public void tiaozhan(String str)// 对方发来挑战的信息后的操作
{
tzz = str.substring(10);// 记录发起挑战的人
this.mj.tz();// 调用主界面对方发来挑战的方法
JOptionPane.showMessageDialog(this.mj, tzz + "向你发起挑战!!");
}
public void jujue(String str) {
btzz = str.substring(6);
JOptionPane.showMessageDialog(this.mj, btzz + "拒绝了您的挑战 !!");
btzz = "";// 将被挑战者清空
}
public void jieshou(String str) {
btzz = str.substring(9);
this.mj.jieshou1();// 调用主界面点击接受按钮接的方法
JOptionPane.showMessageDialog(this.mj, btzz + "接受您的挑战 !!");
}
public void btzzyjl(String str)// 当被挑战者有记录时
{
String name = str.substring(10);// 记录发起挑战的人
try {
this.dos.writeUTF("#yhfm#" + name);// 告诉发起挑战的人正在挑战中
} catch (Exception e) {
}
}
public void mang(String str) {
String name = str.substring(6);// 获取到被挑战者的名字
JOptionPane.showMessageDialog(this.mj, name + "正在接受挑战!!");
}
public void kaiqi() {
}
public void rens(String str) {
String name = str.substring(8);
JOptionPane.showMessageDialog(this.mj, name + "认输了!您赢得了这局!");
tzz = "";
btzz = "";
System.out.println("对方认输了");
this.mj.renshu1();// 调用主界面对方认输的方法
}
public void tishi(String str)// 提示新用户上线的方法
{
String sss = str.substring(7);
JOptionPane.showMessageDialog(this.mj, sss + "上线了");
}
public void zdlk()// 当客户端主动离开是的方法
{
String aa = this.mj.getWbk3().getText().trim();
try {
this.dos.writeUTF("#likai#" + aa);
this.dis.close();
this.dos.close();
this.s.close();
this.flag = false;
} catch (Exception e) {
}
}
public void fqtz(String str)// 发起挑战的方法
{
try {
tzz = this.getName();// 将自身线程的名字赋值给tzz
this.dos.writeUTF("#tiaozhan#" + str);// 将发起挑战的人和被挑战的人发送到服务器
} catch (Exception e) {
}
}
public void jieshou1()// 被挑战方接受挑战的方法
{
try {
this.btzz = this.getName();
this.dos.writeUTF("#jieshou#" + tzz);
} catch (Exception e) {
}
}
public void jujue1()// 被挑战方拒绝挑战的方法
{
try {
this.dos.writeUTF("#jjtz#" + tzz);// 将挑战者的名字发送到服务器
tzz = "";// 将挑战者的名字清空
} catch (Exception e) {
}
}
public void yhrs()// 主动认输的方法
{
if (this.getName().equals(btzz))// 如果自身是被挑战者
{
try {
this.dos.writeUTF("#renshu#" + tzz);// 将认输的信息发送到对方
} catch (Exception e) {
}
}
if (this.getName().equals(tzz))// 如果自身是挑战者
{
try {
this.dos.writeUTF("#renshu#" + btzz);// 将认输的信息发送到对方
} catch (Exception e) {
}
}
tzz = "";
btzz = "";
}
public String fhmz1() {
if (this.getName().equals(btzz))// 如果自身是被挑战者
{
return tzz;
} else if (this.getName().equals(tzz))// 如果自身是挑战者
{
return btzz;
}
return "aaaaa";
}
public void setfhmz1() {
// if(this.getName().equals(btzz))//如果自身是被挑战者
// {
// btzz="";
// }
// else if(this.getName().equals(tzz))//如果自身是挑战者
// {
// tzz="";
// }
tzz = "";
btzz = "";
}
public void Move(String str)// 走棋的方法
{
System.out.println("进入客户端走棋的方法");
int len = str.length();
int Sx = Integer.parseInt(str.substring(len - 4, len - 3));
int Sy = Integer.parseInt(str.substring(len - 3, len - 2));
int Ex = Integer.parseInt(str.substring(len - 2, len - 1));
int Ey = Integer.parseInt(str.substring(len - 1));
System.out.println("333开始坐标:" + Sx + ":" + Sy + "移动后的坐标" + Ex + ":"
+ Ey);
this.qp.move1(Sx, Sy, Ex, Ey);
// this.qp.aaa();
this.mj.setCaiPan();
System.out.println("客户端走棋的方法完毕");
}
}
6、象棋棋谱
package jiem;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
import java.util.*;
import java.io.*;
public class QP extends JPanel implements MouseListener {
DataOutputStream dos;
private int kuan;// 楚河汉界的宽度
boolean zt = false;// 棋盘的初始状态
int sx = 4;
int sy = 0;
int jx = 4;
int jy = 9;
int Sx = -1;
int Sy = -1;
int Ex = -1;
int Ey = -1;
QZ[][] arr;// 棋子的数组
mainJM jm;
Guize ge;
public QP(QZ[][] arr, int kuan, mainJM jm) {
this.jm = jm;
this.arr = arr;
this.kuan = kuan;
ge = new Guize(arr);
this.addMouseListener(this);
this.setBounds(0, 0, 550, 550);
this.setLayout(null);
}
public void paint(Graphics gg) {
Graphics2D g = (Graphics2D) gg;// 获得2D画笔
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON); //消除线段的锯齿边缘
Color color = g.getColor();// 获得画笔的的颜色
g.setColor(jm.bgColor);// 将画笔的颜色换成棋盘背景颜色
g.fill3DRect(10, 10, 500, 500, false);// 绘制一个矩形棋盘
// g.fill3DRect(0,0,800,700,false);
g.setColor(Color.BLACK);// 将画笔的颜色设置为黑色
for (int i = 35; i <= 485; i = i + 50) {// 绘制棋盘中的横线
g.drawLine(60, i, 460, i);
}
g.drawLine(60, 35, 60, 485);// 绘制左边线
g.drawLine(460, 35, 460, 485);// 绘制右边线
for (int i = 110; i <= 410; i = i + 50) {// 绘制中间的竖线
g.drawLine(i, 35, i, 235);
g.drawLine(i, 285, i, 485);
}
g.drawLine(210, 35, 310, 135);// 绘制两边的斜线
g.drawLine(310, 35, 210, 135);
g.drawLine(210, 385, 310, 485);
g.drawLine(310, 385, 210, 485);
this.smallLine(g, 1, 2);// 绘制红炮所在位置的标志
this.smallLine(g, 7, 2);// 绘制红炮所在位置的标志
this.smallLine(g, 0, 3);// 绘制兵所在位置的标志
this.smallLine(g, 2, 3);// 绘制兵所在位置的标志
this.smallLine(g, 4, 3);// 绘制兵所在位置的标志
this.smallLine(g, 6, 3);// 绘制兵所在位置的标志
this.smallLine(g, 8, 3);// 绘制兵所在位置的标志
this.smallLine(g, 0, 6);// 绘制卒所在位置的标志
this.smallLine(g, 2, 6);// 绘制卒所在位置的标志
this.smallLine(g, 4, 6);// 绘制卒所在位置的标志
this.smallLine(g, 6, 6);// 绘制卒所在位置的标志
this.smallLine(g, 8, 6);// 绘制卒所在位置的标志
this.smallLine(g, 1, 7);// 绘制白炮所在位置的标志
this.smallLine(g, 7, 7);// 绘制白炮所在位置的标志
g.setColor(Color.black);
Font font1 = new Font("宋体", Font.BOLD, 30);// 设置字体
g.setFont(font1);
g.drawString("楚 河", 90, 270);// 绘制楚河汉界
g.drawString("漢 界", 340, 270);
Font font = new Font("宋体", Font.BOLD, 20);
g.setFont(font);// 设置字体
for (int i = 0; i < 9; i++) {
for (int j = 0; j < 10; j++) {// 绘制棋子
if (arr[i][j] != null) {
if (this.arr[i][j].getFlag() != false) {// 被选中
g.setColor(jm.focusbg);// 选中后的背景色
g.fillOval(45 + i * 50, 20 + j * 50, 30, 30);// 绘制该棋子
g.setColor(jm.focuschar);// 字符的颜色
} else {
g.fillOval(45 + i * 50, 20 + j * 50, 30, 30);// 绘制该棋子
g.setColor(arr[i][j].getColor());// 设置画笔颜色
}
g.drawString(arr[i][j].getName(), 50 + i * 50,
42 + j * 50);
g.setColor(Color.black);// 设为黑色
}
}
}
// g.setColor(c);//还原画笔颜色
}
public void smallLine(Graphics2D g, int i, int j) {
int x = 60 + 50 * i;// 计算坐标
int y = 35 + 50 * j;
if (i > 0) {// 绘制左上方的标志
g.drawLine(x - 3, y - 3, x - 20, y - 3);
g.drawLine(x - 3, y - 3, x - 3, y - 20);
}
if (i < 8) {// 绘制右上方的标志
g.drawLine(x + 3, y - 3, x + 20, y - 3);
g.drawLine(x + 3, y - 3, x + 3, y - 20);
}
if (i > 0) {// 绘制左下方的标志
g.drawLine(x - 3, y + 3, x - 20, y + 3);
g.drawLine(x - 3, y + 3, x - 3, y + 20);
}
if (i < 8) {// 绘制右下方的标志
g.drawLine(x + 3, y + 3, x + 20, y + 3);
g.drawLine(x + 3, y + 3, x + 3, y + 20);
}
}
public void mouseClicked(MouseEvent e)// 按下并释放时调用
{
if (this.jm.caiPan == true) {// 判断是否轮到该玩家走棋
int i = -1, j = -1;
int[] pos = getPos(e);
i = pos[0];
j = pos[1];
if (i >= 0 && i <= 8 && j >= 0 && j <= 9) {// 如果在棋盘范围内
if (zt == false) {// 如果棋盘中没有选中棋子
this.noFocus(i, j);
System.out.println("进入没有选中棋子");
} else {// 如果以前选中过棋子
// 以下是判断再次点击的地方是否有棋子
if (arr[i][j] != null) {// 如果该处有棋子
if (arr[i][j].getColor() == arr[Sx][Sy].getColor()) {// 如果是自己的棋子
System.out.println("是自己的棋子");
arr[Sx][Sy].setFlag(false);
arr[i][j].setFlag(true);// 更改选中对象
Sx = i;
Sy = j;// 保存修改
} else {// 如果是对方棋子
Ex = i;// 保存该点
Ey = j;
System.out.println("不是自己的棋子");
String name = arr[Sx][Sy].getName();// 获得该棋子的名字
// 看是否可以移动
boolean canMove = ge.canMove(Sx, Ex, Sy, Ey, name);
System.out.println("不是自己的棋子判断是否可以移动:" + canMove
+ "己方的棋子是" + name);
// canMove=true;
System.out.println("canmove:" + canMove);
if (canMove)// 如果可以移动
{
try {// 将该移动信息发送给对方
dos = this.jm.lj.fhyd();// 获取用户输出流
String name1 = this.jm.lj.fhmz1();// 获取对方得名字
dos.writeUTF("#yidong#" + name1 + Sx + Sy
+ Ex + Ey);
System.out.println("#yidong#" + name1 + Sx
+ Sy + Ex + Ey);
this.jm.caiPan = false;
if (arr[Ex][Ey].getName().equals("帥")
|| arr[Ex][Ey].getName()
.equals("將")) {// 如果终点处是对方的"将"
this.success();
} else {// 如果终点不是对方的"将"
this.noJiang();
}
} catch (Exception ee) {
ee.printStackTrace();
}
}
}
} else {// 如果没有棋子
System.out.println("进入走棋");
Ex = i;
Ey = j;// 保存终点
System.out.print("111开始坐标:" + Sx + ":" + Sy + "移动后的X坐标"
+ Ex + ":" + Ey);
String name = arr[Sx][Sy].getName();// 获得该棋的名字
boolean canMove = ge.canMove(Sx, Ex, Sy, Ey, name);// 判断是否可走
System.out.println(canMove);
if (canMove) {// 如果可以移动
this.noQiZi();
}
}
}
}
this.jm.repaint();// 重绘
}
}
public void mouseEntered(MouseEvent e)// 进入到组件上调用
{
}
public void mouseExited(MouseEvent e)// 离开是调用
{
}
public void mousePressed(MouseEvent e) // 按下时调用
{
}
public void mouseReleased(MouseEvent e) // 松开是调用
{
}
public int[] getPos(MouseEvent e) {
System.out.println("进入获取X,Y坐标方法");
int[] pos = new int[2];
pos[0] = -1;
pos[1] = -1;
Point p = e.getPoint();// 获得事件发生的坐标点
double x = p.getX();
double y = p.getY();
if (Math.abs((x - 60) / 1 % 50) <= 15) {// 获得对应于数组x下标的位置
pos[0] = Math.round((float) (x - 60)) / 50;
} else if (Math.abs((x - 60) / 1 % 50) >= 35) {
pos[0] = Math.round((float) (x - 60)) / 50 + 1;
}
if (Math.abs((y - 35) / 1 % 50) <= 15) {// 获得对应于数组y下标的位置
pos[1] = Math.round((float) (y - 35)) / 50;
} else if (Math.abs((y - 35) / 1 % 50) >= 35) {
pos[1] = Math.round((float) (y - 35)) / 50 + 1;
}
System.out.println("点击坐标:("+pos[0]+","+pos[1]+")");
return pos;
}
public void noFocus(int i, int j) {
if (this.arr[i][j] != null)// 如果该位置有棋子
{
if (this.jm.color == 0)// 如果是红方
{
if (this.arr[i][j].getColor().equals(jm.color1))// 如果棋子是红色
{
this.arr[i][j].setFlag(true);// 将该棋子设为选中状态
zt = true;// 将focus设为true
Sx = i;// 保存该坐标点
Sy = j;
}
} else// 如果是白方
{
if (this.arr[i][j].getColor().equals(jm.color2))// 如果该棋子是白色
{
this.arr[i][j].setFlag(true);// 将该棋子设为选中状态
zt = true;// 将focus设为true
Sx = i;// 保存该坐标点
Sy = j;
}
}
}
}
public void success() {
System.out.println("进入成功吃掉对方得将或帅");
arr[Ex][Ey] = arr[Sx][Sy];// 吃掉该棋子
arr[Sx][Sy] = null;// 将原来的位置设为空
this.jm.repaint();// 重绘
JOptionPane.showMessageDialog(this.jm, "恭喜您,您获胜了", "提示",
JOptionPane.INFORMATION_MESSAGE);// 给出获胜信息
this.jm.lj.setfhmz1();
this.jm.color = 0;
this.jm.caiPan = false;
this.jm.next();// 还原棋盘,进入下一盘
Sx = -1;// 还原保存点
Sy = -1;
Ex = -1;
Ey = -1;
sx = 4;// "帥"的i坐标
sy = 0;// "帥"的j坐标
jx = 4;// "將"的i坐标
jy = 9;// "將"的j坐标
zt = false;
this.jm.repaint();
}
public void noJiang() {
arr[Ex][Ey] = arr[Sx][Sy];
arr[Sx][Sy] = null;// 走棋
arr[Ex][Ey].setFlag(false);// 将该棋设为非选中状态
this.jm.repaint();// 重绘
if (arr[Ex][Ey].getName().equals("帥")) {// 如果移动的是"帥"
sx = Ex;// 更新"帥"的位置坐标
sy = Ey;
} else if (arr[Ex][Ey].getName().equals("將")) {// 如果移动的是"將"
jx = Ex;// 更新"將"的位置坐标
jy = Ey;
}
if (jx == sx) {// 如果"將"和"帥"在一条竖线上
int count = 0;
for (int i = sy + 1; i < jy; i++) {// 遍历这条竖线
if (arr[jx][i] != null) {
count++;
break;
}
}
if (count == 0) {// 如果等于零则照将
JOptionPane.showMessageDialog(this.jm, "照将!!!你失败了!!!", "提示",
JOptionPane.INFORMATION_MESSAGE);// 给出失败信息
this.jm.lj.setfhmz1();
this.jm.color = 0;// 还原棋盘,进入下一盘
this.jm.caiPan = false;
this.jm.next();// 进入下一盘
sx = 4;// "帥"的i坐标
sy = 0;// "帥"的j坐标
jx = 4;// "將"的i坐标
jy = 9;// "將"的j坐标
}
}
Sx = -1;
Sy = -1;// 还原保存点
Ex = -1;
Ey = -1;
zt = false;
}
public void noQiZi() {
System.out.println("进入终点没有棋子的方法");
try {// 将该移动信息发送给对方
dos = this.jm.lj.fhyd();
String nnn = this.jm.lj.fhmz1();
dos.writeUTF("#yidong#" + nnn + Sx + Sy + Ex + Ey);
System.out.print("222开始坐标:" + Sx + ":" + Sy + "移动后的X坐标" + Ex + ":"
+ Ey);
this.jm.caiPan = false;
arr[Ex][Ey] = arr[Sx][Sy];
arr[Sx][Sy] = null;// 走棋
arr[Ex][Ey].setFlag(false);// 将该棋设为非选中状态.
System.out.println("重绘棋子");
this.jm.repaint();// 重绘
if (arr[Ex][Ey].getName().equals("帥")) {// 如果移动的是"帥"
sx = Ex;// 更新"帥"的位置坐标
sy = Ey;
} else if (arr[Ex][Ey].getName().equals("將")) {// 如果移动的是"將"
jx = Ex;// 更新"將"的位置坐标
jy = Ey;
}
if (jx == sx)// 如果"將"和"帥"在一条竖线上
{
int count = 0;
for (int i = sy + 1; i < jy; i++) {// 遍历这条竖线
if (arr[jx][i] != null) {
count++;
break;
}
}
if (count == 0) {// 如果等于零则照将
JOptionPane.showMessageDialog(this.jm, "照将!!!你失败了!!!",
"提示", JOptionPane.INFORMATION_MESSAGE);// 给出失败信息
this.jm.lj.setfhmz1();
this.jm.color = 0;// 还原棋盘,进入下一盘
this.jm.caiPan = false;
this.jm.next();// 进入下一盘
sx = 4;// "帥"的i坐标
sy = 0;// "帥"的j坐标
jx = 4;// "將"的i坐标
jy = 9;// "將"的j坐标
}
}
Sx = -1;
Sy = -1;// 还原保存点
Ex = -1;
Ey = -1;
zt = false;
} catch (Exception ee) {
System.out.println("走棋为成功" + ee.toString());
}
this.jm.repaint();
}
public void move1(int Sx, int Sy, int Ex, int Ey) {
System.out.println("进入棋盘移动的方法");
if (arr[Ex][Ey] != null
&& (arr[Ex][Ey].getName().equals("帥") || arr[Ex][Ey].getName()
.equals("將"))) {// 如果"将"被吃了
arr[Ex][Ey] = arr[Sx][Sy];
arr[Sx][Sy] = null;// 走棋
this.jm.repaint();// 重绘
JOptionPane.showMessageDialog(this.jm, "很遗憾,您失败了!!!", "提示",
JOptionPane.INFORMATION_MESSAGE);// 给出失败信息
System.out.println("进入重新开始的地点");
this.jm.lj.setfhmz1();
this.jm.color = 0;// 还原棋盘,进入下一盘
this.jm.caiPan = false;
this.jm.next();// 进入下一盘
sx = 4;// "帥"的i坐标
sy = 0;// "帥"的j坐标
jx = 4;// "將"的i坐标
jy = 9;// "將"的j坐标
} else {// 如果不是"将"
arr[Ex][Ey] = arr[Sx][Sy];
arr[Sx][Sy] = null;// 走棋
this.jm.repaint();// 重绘
if (arr[Ex][Ey].getName().equals("帥")) {
sx = Ex;// 如果是"帥"
sy = Ey;
} else if (arr[Ex][Ey].getName().equals("將")) {
jx = Ex;// 如果是"將"
jy = Ey;
}
if (sx == jx) {// 如果两将在一条线上
int count = 0;
for (int i = sy + 1; i < jy; i++) {
if (arr[sx][i] != null) {// 有棋子
count++;
break;
}
}
if (count == 0) {
JOptionPane.showMessageDialog(this.jm, "对方照将!!!你胜利了!!!",
"提示", JOptionPane.INFORMATION_MESSAGE);// 给出失败信息
this.jm.lj.setfhmz1();
this.jm.color = 0;// 还原棋盘,进入下一盘
this.jm.caiPan = false;
this.jm.next();// 进入下一盘
sx = 4;// "帥"的i坐标
sy = 0;// "帥"的j坐标
jx = 4;// "將"的i坐标
jy = 9;// "將"的j坐标
}
}
}
this.zt = false;
this.jm.repaint();// 重绘
}
}
7、象棋棋子类
package jiem;
import java.awt.*;
public class QZ {
private Color color;// 棋子的颜色
private String name;// 棋子的名字
private int x;// 棋子的X轴
private int y;// 棋子的Y轴
private boolean flag = false;
public QZ(Color color, String name, int x, int y) {
this.color = color;
this.name = name;
this.x = x;
this.y = y;
}
public Color getColor() {
return color;
}
public void setColor(Color color) {
this.color = color;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getX() {
return x;
}
public void setX(int x) {
this.x = x;
}
public int getY() {
return y;
}
public void setY(int y) {
this.y = y;
}
public void setFlag(boolean a) {
this.flag = a;
}
public boolean getFlag() {
return this.flag;
}
}
8、象棋规则
package jiem;
public class Guize {
QZ[][] arr;// 声明棋子的数组
int x;// 棋子的起始X坐标
int y;// 棋子的起始Y坐标
boolean canmove = false;// 判断棋子是否能移动的标志位
public Guize(QZ[][] arr)// 构造函数 参数QZ类
{
this.arr = arr;
}
// 棋子移动时判断的方法,参数:起始XY,终止XY,棋子的名字
public boolean canMove(int Sx, int Ex, int Sy, int Ey, String name) {
int maxX;// 辅助变量
int minX;
int maxY;
int minY;
canmove = true;// 将判断棋子能否移动的标志位改为true
if (Sx >= Ex)// 如果起始的X坐标大于等于终止的X坐标
{
maxX = Sx;// 将起始的X坐标赋值给maxX
minX = Ex;// 将终止的X坐标赋值给minX
} else // 如果起始的X坐标小于终止的X坐标
{
maxX = Ex;// 将终止的X坐标赋值给maxX;
minX = Sx;// 将起始的X坐标赋值给minX;
}
if (Sy >= Ey)// 判断起始的Y坐标是否大于等于终止的Y坐标
{
maxY = Sy;
minY = Ey;
} else {
maxY = Ey;
minY = Sy;
}
System.out.println("进入判断能否移动的方法中" + "最大" + maxX + "最小X" + minX);
if (name.equals("車")) {
this.ju(maxX, minX, maxY, minY);
} else if (name.equals("馬")) {
this.ma(maxX, minX, maxY, minY, Sx, Ex, Sy, Ey);
} else if (name.equals("相")) {
this.xiang(maxX, minX, maxY, minY, Sx, Ex, Sy, Ey);
} else if (name.equals("象")) {
this.xiang1(maxX, minX, maxY, minY, Sx, Ex, Sy, Ey);
} else if (name.equals("士") || name.equals("仕")) {
this.shi(maxX, minX, maxY, minY, Sx, Ex, Sy, Ey);
} else if (name.equals("帥") || name.equals("將")) {
this.shuai(maxX, minX, maxY, minY, Sx, Ex, Sy, Ey);
} else if (name.equals("炮") || name.equals("砲")) {
this.pao(maxX, minX, maxY, minY, Sx, Ex, Sy, Ey);
} else if (name.equals("兵")) {
this.bing(maxX, minX, maxY, minY, Sx, Ex, Sy, Ey);
} else if (name.equals("卒")) {
this.zu(maxX, minX, maxY, minY, Sx, Ex, Sy, Ey);
}
return canmove;
}
public void ju(int maxX, int minX, int maxY, int minY)// 車的走棋规则
{
System.out.println("进入車的方法中" + "最大" + maxX + "最小X" + minX);
if (maxX == minX || minX == maxX)// 如果移动前后在一条竖线上
{
System.out.println("在一条竖线上");
for (int i = minY + 1; i < maxY; i++)// 让X不变Y移动看是否两点之间有棋子
{
if (arr[maxX][i] != null) {
canmove = false;
break;
}
}
} else if (maxY == minY)// 如果移动前后在一条竖线上
{
System.out.println("在一条横线上");
for (int i = minX + 1; i < maxX; i++)// 让Y不变 X移动 看是否已有棋子
{
if (arr[i][maxY] != null)// 如果有棋子那么将能否移动改为false;
{
canmove = false;
break;
}
}
} else if (maxX != minX && maxY != minY)// 移动前后不在一条直线上
{
canmove = false;
}
}
public void ma(int maxX, int minX, int maxY, int minY, int Sx, int Ex,
int Sy, int Ey)// 馬的走棋规则
{
int a = maxX - minX;// 判断两点坐标之差
int b = maxY - minY;
if (a == 1 && b == 2)// 竖着走
{
if (Sy > Ey)// 如果起始的坐标大于终止的坐标证明是从上往下走
{
if (arr[Sx][Sy - 1] != null)// 判断马腿处是否有棋子
{
canmove = false;// 证明棋子不可以移动
}
} else {
if (arr[Sx][Sy + 1] != null)// 判断马腿处是否有棋子
{
canmove = false;// 不可以移动
}
}
} else if (a == 2 && b == 1)// 横着走
{
if (Sx > Ex)// 从右往左走
{
if (arr[Sx - 1][Sy] != null) {
canmove = false;
}
} else {
if (arr[Sx + 1][Sy] != null) {
canmove = false;
}
}
} else if (!(a == 1 && b == 2 || a == 2 && b == 1)) {
canmove = false;
}
}
public void xiang(int maxX, int minX, int maxY, int minY, int Sx, int Ex,
int Sy, int Ey)// 相的走棋规则
{
int a = maxX - minX;
int b = maxY - minY;
if (a == 2 && b == 2)// 证明是田字
{
if (Ey > 4)// 过界了
{
canmove = false;
}
if (arr[(maxX + minX) / 2][(maxY + minY) / 2] != null) {
canmove = false;
}
} else {
canmove = false;
}
}
public void xiang1(int maxX, int minX, int maxY, int minY, int Sx, int Ex,
int Sy, int Ey)// 象的走棋规则
{
int a = maxX - minX;
int b = maxY - minY;
if (a == 2 && b == 2)// 证明是田字
{
if (Ey < 5)// 过界了
{
canmove = false;
}
if (arr[(maxX + minX) / 2][(maxY + minY) / 2] != null) {
canmove = false;
}
} else {
canmove = false;
}
}
public void shi(int maxX, int minX, int maxY, int minY, int Sx, int Ex,
int Sy, int Ey)// 士的走棋规则
{
int a = maxX - minX;
int b = maxY - minY;
if (a == 1 && b == 1)// 如果走的是斜线
{
if (Sy < 4)// 如果是下方的士
{
if (Ey > 2)// 越界
{
canmove = false;
}
} else// 如果是上方的士
{
if (Ey < 7)// 越界
{
canmove = false;
}
}
if (Ex > 5 || Ex < 3) {
canmove = false;
}
} else // 如果走的不是斜线
{
canmove = false;
}
}
public void shuai(int maxX, int minX, int maxY, int minY, int Sx, int Ex,
int Sy, int Ey)// 帅的走棋规则
{
int a = maxX - minX;
int b = maxY - minY;
if ((a == 0 && b == 1) || (a == 1 && b == 0))// 判断是否走的是一小格
{
if (Sy > 7)// 如果是上面的帅
{
if (Ey < 7) {
canmove = false;
}
} else {
if (Ey > 2) {
canmove = false;
}
}
if (Ex < 3 || Ex > 5) {
canmove = false;
}
} else {
canmove = false;
}
}
public void pao(int maxX, int minX, int maxY, int minY, int Sx, int Ex,
int Sy, int Ey)// 炮的移动规则
{
if (maxX == minX)// 如果在同一条竖线上
{
if (arr[Ex][Ey] != null)// 判断终点有棋子的情况下
{
int sum = 0;
for (int i = minY + 1; i < maxY; i++) {
if (arr[minX][i] != null) {
sum += 1;
}
}
if (sum != 1)// 如果之间的棋子不是一个
{
canmove = false;
}
} else if (arr[Ex][Ey] == null)// 判断终点没有棋子
{
for (int i = minY + 1; i < maxY; i++) {
if (arr[maxX][i] != null)// 判断起始点之间是否有棋子
{
canmove = false;
break;
}
}
}
} else if (maxY == minY)// 如果在一条横线上
{
if (arr[Ex][Ey] != null)// 如果终点有棋子
{
int sum = 0;
for (int i = minX + 1; i < maxX; i++)// 判断始终两点之间是否有棋子
{
if (arr[i][maxY] != null) {
sum += 1;
}
}
if (sum != 1) {
canmove = false;
}
} else if (arr[Ex][Ey] == null) {
for (int i = minX + 1; i < maxX; i++) {
if (arr[i][maxY] != null) {
canmove = false;
break;
}
}
}
} else if (maxX != minX && maxY != minY)// 既不是竖线也不是横线
{
canmove = false;
}
}
public void bing(int maxX, int minX, int maxY, int minY, int Sx, int Ex,
int Sy, int Ey)// 兵的走棋规则
{
System.out.println("进入兵的方法");
if (Ey < 5)// 没过河
{
if (Sx != Ex)// 横着走
{
canmove = false;
System.out.println("1");
}
if (Ey - Sy != 1) {
canmove = false;
System.out.println("2");
}
} else// 过河
{
if (Ey == Sy)// 横着走
{
if (maxX - minX != 1) {
canmove = false;
System.out.println("3");
}
} else if (Ex == Sx)// 竖着走
{
if (Ey < Sy) {
canmove = false;
} else {
if (maxY - minY != 1) {
canmove = false;
System.out.println("4");
}
}
} else if (Sx != Ex && Sy != Ey) {
canmove = false;
System.out.println("5");
}
}
}
public void zu(int maxX, int minX, int maxY, int minY, int Sx, int Ex,
int Sy, int Ey)// 卒的走棋规则
{
if (Ey > 4)// 没过河
{
if (Ex != Sx)// 如果不是竖着走
{
canmove = false;
}
if (Sy - Ey != 1)// 如果走的不是一格
{
canmove = false;
}
} else// 过河
{
if (Sx == Ex)// 如果走的是竖线
{
if (Ey > Sy) {
canmove = false;
} else {
if (maxY - minY != 1) {
canmove = false;
}
}
} else if (Sy == Ey)// 如果走的横线
{
if (maxX - minX != 1) {
canmove = false;
}
} else if (Sx != Ex && Sy != Ey) {
canmove = false;
}
}
}
}
参考