java web象棋教程_【Java学习笔记】实战——网络象棋

这篇博客介绍了一个使用Java Web技术实现的网络象棋教程。内容包括服务端和客户端的设计,涉及到Socket编程,线程管理和用户交互。服务端通过ServerSocket监听客户端连接,子线程处理客户端请求,实现棋局逻辑。客户端则负责用户界面和输入输出。教程详细解释了各个部分的实现细节,适合Java Web初学者和对网络象棋游戏开发感兴趣的开发者学习。
摘要由CSDN通过智能技术生成

ba9c095fd340

服务端

ba9c095fd340

客户端

ba9c095fd340

项目结构

源码

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;

}

}

}

}

参考

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值