服務端
客戶端
項目結構
源碼
1、服務端:主函數(shù)
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("端口號");// 創(chuàng)建標簽 用于顯示文本框中的內容表示的是什么
JTextField wbk = new JTextField("9999");// 創(chuàng)建文本框 并初始化文本框中的內容
JButton b1 = new JButton("開啟");// 創(chuàng)建 開始 按鈕
JButton b2 = new JButton("關閉");// 創(chuàng)建 關閉 按鈕
JPanel p1 = new JPanel();// 創(chuàng)建面板用于添加 按鈕 標簽 文本框
Vector online = new Vector();// 用于存儲在線用戶的集合
JList lis = new JList();// 創(chuàng)建列表
JScrollPane gd = new JScrollPane(lis);
JSplitPane fg = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, gd, p1);
ZThread zt;// 創(chuàng)建主線程對象
public static void main(String[] args) {
jiemian1 one = new jiemian1();
}
public jiemian1()// 構造函數(shù)
{
this.cskj();// 初始化控件
this.sjjt();// 初始化監(jiān)聽scrollPane.getViewport().setView(myList);
this.csct();// 初始化窗體
}
public void cskj()// 初始化組件的函數(shù)
{
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()// 初始化窗體的函數(shù)
{
this.add(fg);
this.setTitle("網(wǎng)絡象棋服務器");
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()// 為組件做監(jiān)聽的函數(shù)
{
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, "端口號填寫錯誤,為整數(shù)(0-65535)");
return;
}
if (ii < 0 || ii > 65535) {
JOptionPane.showMessageDialog(this, "端口號填寫錯誤,為整數(shù)(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()// 刷新列表的函數(shù)
{
// 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)// 構造函數(shù)
{
this.jm = jm;
this.cjss();// 對ServerSocket 進行初始化
}
public void cjss()// ServerSocket 初始化的函數(shù)
{
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);// 創(chuàng)建分線程的對象
zh.start();// 啟動分線程
} catch (Exception e) {
System.out.println(e.toString());
}
System.out.println("主線程接收到客戶端的鏈接 Socket 對象創(chuàng)建成功");
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;// 創(chuàng)建Socket 引用
Vector v = new Vector();// 建立Vector 集合
boolean sm = true;// 初始化輔助線程的生命
DataInputStream din;// 聲明數(shù)據(jù)輸入流對象引用
DataOutputStream dou;// 聲明數(shù)據(jù)輸出流對象引用
jiemian1 jm;// 聲明主界面的類引用
public FThread(jiemian1 jm, Socket s)// 構造方法 參數(shù) 從主線程傳入的 Socket 對象
{
this.jm = jm;
this.s = s;
this.cjfzxc();// 初始化數(shù)據(jù)流
}
public void cjfzxc()// 創(chuàng)建數(shù)據(jù)流的方法
{
try {
din = new DataInputStream(s.getInputStream());
dou = new DataOutputStream(s.getOutputStream());
} catch (Exception e) {
System.out.println("輔助線程 數(shù)據(jù)流的創(chuàng)建異常:" + 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("客戶端發(fā)來的昵稱:" + str);
if (str.startsWith("#nc#"))// 客戶端新用戶上線
{
this.xyh(str);// 用戶上線的方法
} else if (str.startsWith("#likai#"))// 客戶端離開
{
this.yhlk(str);// 用戶離開的方法
} else if (str.startsWith("#tiaozhan#"))// 客戶端發(fā)送挑戰(zhàn)的信息
{
this.yhfqtz(str);
} else if (str.startsWith("#jieshou#"))// 客戶端接受挑戰(zhàn)
{
this.yhjstz(str);
} else if (str.startsWith("#jjtz#"))// 客戶端拒絕挑戰(zhàn)
{
this.yhjjtz(str);// 被挑戰(zhàn)者拒絕挑戰(zhàn)的方法
} else if (str.startsWith("#yjjstz#"))// 客戶端已經接受了挑戰(zhàn)(第一種情況)
{
this.yjjstz(str);
} else if (str.startsWith("#yhfm#"))// 客戶端已經接受了挑戰(zhàn) (第二種情況)
{
this.yhfm(str);
} else if (str.startsWith("#renshu#"))// 客戶端認輸?shù)姆椒? {
this.renshu(str);
} else if (str.startsWith("#yidong#"))// 收到客戶端發(fā)來移動棋子的信息
{
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)// 如果出現(xiàn)重名
{
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();// 更新主界面列表中的集合數(shù)據(jù)
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 {
// 讓每一個線程把所有線程的名字都發(fā)送到每個客戶端
na.dou.writeUTF("#liebiao#" + ft.getName());
} catch (Exception e) {
}
}
if (!na.getName().equals(name)) {// 將新上線的用戶名字發(fā)給每個在線用戶
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)))// 將離開的用戶發(fā)送給每個在線用戶
{
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)// 用戶發(fā)起挑戰(zhàn)的方法
{
String name1 = this.getName();// 發(fā)起挑戰(zhàn)的人
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))// 得到被挑戰(zhàn)人的線程
{
try {
ff.dou.writeUTF("#tiaozhan#" + name1);
} catch (Exception e) {
}
}
}
}
public void yhjstz(String str)// 用戶接受挑戰(zhàn)的方法
{
String name = str.substring(9);// 接收到挑戰(zhàn)者的名字
v = this.jm.getVector();
for (Iterator it = v.iterator(); it.hasNext();) {
FThread ff = (FThread) it.next();
if (ff.getName().equals(name))// 遍歷取得被挑戰(zhàn)者的線程
{
try {
ff.dou.writeUTF("#jieshou#" + this.getName());// 將接受挑戰(zhàn)的人名字發(fā)送給挑戰(zhàn)者
} catch (Exception e) {
}
}
}
}
public void yhjjtz(String str)// 用戶拒絕挑戰(zhàn)的方法
{
String name = str.substring(6);// 獲取挑戰(zhàn)者的名字
v = this.jm.getVector();
for (Iterator it = v.iterator(); it.hasNext();) {
FThread ff = (FThread) it.next();
if (ff.getName().equals(name))// 遍歷得到挑戰(zhàn)者的線程
{
try {
ff.dou.writeUTF("#jjtz#" + this.getName());// 將被挑戰(zhàn)者的名字發(fā)送給挑戰(zhàn)者
} catch (Exception e) {
}
}
}
}
public void yjjstz(String str)// 自己已經接受挑戰(zhàn)了 發(fā)送給另一個接受挑戰(zhàn)的玩家一個信息
{
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)// 用戶繁忙不能接受挑戰(zhàn)
{
String name = str.substring(6);// 獲取發(fā)起挑戰(zhàn)的人
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());// 將被挑戰(zhàn)者繁忙的信息發(fā)送給挑戰(zhàn)者
} catch (Exception e) {
}
}
}
}
public void renshu(String str)// 用戶認輸?shù)姆椒? {
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();)// 給每個線程發(fā)送服務器關閉的信息
{
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、客戶端:主函數(shù)
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];// 創(chuàng)建一個用于添加棋子的二維數(shù)組
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();// 初始化監(jiān)聽
this.cshzt();// 初始化組件的狀態(tài)
this.cjct();// 初始化窗體
this.cshqz();// 初始化棋子
}
public void cjzj()// 創(chuàng)建組件的方法
{
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("挑戰(zhàn)");
b3.setBounds(15, 230, 90, 20);
p1.add(b3);
b4 = new JButton("認輸");
b4.setBounds(115, 230, 90, 20);
p1.add(b4);
b5 = new JButton("接受挑戰(zhàn)");
b5.setBounds(15, 260, 90, 20);
p1.add(b5);
b6 = new JButton("拒絕挑戰(zhàn)");
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()// 創(chuàng)建窗體
{
this.add(fg);
this.setTitle("網(wǎng)絡象棋客戶端");
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()// 創(chuàng)建監(jiān)聽的方法
{
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);// 創(chuàng)建連接類對象 查看是否鏈接成功
if (lj.cjsocket()) {
wbk1.setEditable(false);
wbk2.setEditable(false);
wbk3.setEditable(false);
b2.setEnabled(true);// 關閉設為可用
b1.setEnabled(false);// 開啟設為不可用
b3.setEnabled(true);// 挑戰(zhàn)設為可用
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);// 挑戰(zhàn)設為不可用
b4.setEnabled(false);// 認輸設為不可用
b6.setEnabled(false);// jieshou挑戰(zhàn)設為不可用
b5.setEnabled(false);// 拒絕挑戰(zhàn)設為不可用
xllb.setEnabled(false);// 下拉列表設為不可用
lj.zdlk();// 調用客戶端線程的主動離開方法
// JOptionPane.showMessageDialog(this,"關閉鏈接");
}
public void tiaozhan()// 挑戰(zhàn)
{
String str = (String) xllb.getSelectedItem();// 獲取玩家姓名
if (str == null || str == "") {// 判斷是否取到了玩家姓名
JOptionPane.showMessageDialog(this, "請選中一名玩家!");
} else {
lj.fqtz(str);// 調用發(fā)起挑戰(zhàn)的方法并將選中的玩家做參數(shù)傳進去
this.caiPan = true;
this.color = 0;// 將自己設為紅旗
JOptionPane.showMessageDialog(this, "已發(fā)出挑戰(zhàn)! 請稍等!!");
}
}
public void renshu()// 主動認輸
{
wbk1.setEditable(false);
wbk2.setEditable(false);
wbk3.setEditable(false);
b2.setEnabled(true);// 關閉設為可用
b1.setEnabled(false);// 開啟設為不可用
b3.setEnabled(true);// 挑戰(zhàn)設為可用
b4.setEnabled(false);
b5.setEnabled(false);
b6.setEnabled(false);
xllb.setEnabled(true);// 下拉列表設為可用
lj.yhrs();// 調用連接里的主動認輸?shù)姆椒? // JOptionPane.showMessageDialog(this,"認輸");
}
public void renshu1()// 對方認輸調用的方法
{
wbk1.setEditable(false);
wbk2.setEditable(false);
wbk3.setEditable(false);
b2.setEnabled(true);// 關閉設為可用
b1.setEnabled(false);// 開啟設為不可用
b3.setEnabled(true);// 挑戰(zhàn)設為可用
b4.setEnabled(false);
b5.setEnabled(false);
b6.setEnabled(false);
xllb.setEnabled(true);// 下拉列表設為可用
}
public void setCaiPan() {
caiPan = true;
}
public void jieshou()// 接受挑戰(zhàn)
{
this.caiPan = true;
this.color = 1;// 將自己設為白棋
wbk1.setEditable(false);// 主機設為可用
wbk2.setEditable(false);// 端口設為可用
wbk3.setEditable(false);// 設為可用戶
b2.setEnabled(false);// 關閉設為不可用
b1.setEnabled(false);// 開啟設為可用
b3.setEnabled(false);// 挑戰(zhàn)設為不可用
b4.setEnabled(true);// 認輸設為不可用
b6.setEnabled(false);// 發(fā)起挑戰(zhàn)設為不可用
b5.setEnabled(false);// 拒絕挑戰(zhàn)設為不可用
xllb.setEnabled(false);// 下拉列表設為不可用
lj.jieshou1();// 調用鏈接類中被挑戰(zhàn)者接受挑戰(zhàn)的方法
JOptionPane.showMessageDialog(this, "請走白棋!!");
}
public void jieshou1()// 挑戰(zhàn)者接收到被挑戰(zhàn)者同意的放啊
{
wbk1.setEditable(false);// 主機設為可用
wbk2.setEditable(false);// 端口設為可用
wbk3.setEditable(false);// 設為可用戶
b2.setEnabled(false);// 關閉設為不可用
b1.setEnabled(false);// 開啟設為可用
b3.setEnabled(false);// 挑戰(zhàn)設為不可用
b4.setEnabled(true);// 認輸設為不可用
b6.setEnabled(false);// 發(fā)起挑戰(zhàn)設為不可用
b5.setEnabled(false);// 拒絕挑戰(zhàn)設為不可用
xllb.setEnabled(false);// 下拉列表設為不可用
JOptionPane.showMessageDialog(this, "請走紅旗!!");
}
public void yjjstz()// 對方已經接受了挑戰(zhàn)自己不能同對方挑戰(zhàn)
{
wbk1.setEditable(false);
wbk2.setEditable(false);
wbk3.setEditable(false);
b2.setEnabled(true);// 關閉設為可用
b1.setEnabled(false);// 開啟設為不可用
b3.setEnabled(true);// 挑戰(zhàn)設為可用
b4.setEnabled(false);
b5.setEnabled(false);
b6.setEnabled(false);
xllb.setEnabled(true);// 下拉列表設為可用
// lj.start();//啟動客戶端線程
}
public void jujue()// 拒絕挑戰(zhàn)
{
wbk1.setEditable(false);
wbk2.setEditable(false);
wbk3.setEditable(false);
b2.setEnabled(true);// 關閉設為可用
b1.setEnabled(false);// 開啟設為不可用
b3.setEnabled(true);// 挑戰(zhàn)設為可用
b4.setEnabled(false);
b5.setEnabled(false);
b6.setEnabled(false);
xllb.setEnabled(true);// 下拉列表設為可用
lj.jujue1();// 調用連接類中的被挑戰(zhàn)方拒絕挑戰(zhàn)的方法
}
public void tz()// 對方發(fā)來挑戰(zhàn)后講接受和拒絕按鈕設為可用
{
wbk1.setEditable(false);// 主機設為可用
wbk2.setEditable(false);// 端口設為可用
wbk3.setEditable(false);// 設為可用戶
b2.setEnabled(false);// 關閉設為不可用
b1.setEnabled(false);// 開啟設為可用
b3.setEnabled(false);// 挑戰(zhàn)設為不可用
b4.setEnabled(false);// 認輸設為不可用
b6.setEnabled(true);// 發(fā)起挑戰(zhàn)設為可用
b5.setEnabled(true);// 拒絕挑戰(zhàn)設為可用
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, "請輸入整數(shù)(0-65535)");
return false;
}
if (port < 0 || port > 65535) {
JOptionPane.showMessageDialog(this, "請輸入整數(shù)(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);// 挑戰(zhàn)設為可用
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;// 創(chuàng)建Socket 的標志位
DataInputStream dis;
DataOutputStream dos;
mainJM mj;// 聲明主界面類對象引用
QP qp;// 聲明棋盤類的引用
Vector v;
String tzz = "";// 用于記錄發(fā)起挑戰(zhàn)的名字
String btzz = "";// 用于記錄被挑戰(zhàn)者的名字
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());// 創(chuàng)建輸入流
dos = new DataOutputStream(s.getOutputStream());// 創(chuàng)建輸出流
wbk = mj.getWbk3();
String name = wbk.getText().trim();
dos.writeUTF("#nc#" + name);// 將昵稱發(fā)送到服務器
} catch (Exception e) {
System.out.println("建立數(shù)據(jù)流異常" + e.toString());
}
}
public void run()// run方法
{
this.schl();// 調用創(chuàng)建數(shù)據(jù)輸入輸出流的方法
while (flag) {
System.out.println("循環(huán)");
try {
String str = dis.readUTF().trim();
if (str.startsWith("#chongming#"))// 收到服務器發(fā)來的重名信息
{
this.chongm();// 調用重名的方法
} else if (str.startsWith("#close#"))// 收到服務器關閉的信息
{
this.clse();// 調用服務器關閉是客戶端的操作
} else if (str.startsWith("#liebiao#"))// 收到服務器發(fā)來的列表
{
this.lj(str);// 調用發(fā)來列表的方法
} else if (str.startsWith("#likai#"))// 收到用戶離開的信息
{
this.likai(str);// 調用 用戶離開的方法
} else if (str.startsWith("#tiaozhan#"))// 收到挑戰(zhàn)的信息
{
if (btzz == "")// 收到挑戰(zhàn)信息時判斷挑戰(zhàn)者是否無記錄
{
this.tiaozhan(str);
} else // 如果收到挑戰(zhàn)信息btzz有記錄
{
this.btzzyjl(str);
}
} else if (str.startsWith("#jjtz#"))// 收到拒絕挑戰(zhàn)的信息
{
this.jujue(str);
} else if (str.startsWith("#jieshou#"))// 收到對方接受挑戰(zhàn)的信息
{
if (btzz == "")// 如果被挑戰(zhàn)者沒有記錄
{
this.jieshou(str);// 調用被挑戰(zhàn)者接受的方法
} else {
this.yjjs(str);// 調用挑戰(zhàn)者已接受挑戰(zhàn)的方法
}
} else if (str.startsWith("#yjjstz#"))// 接受到挑戰(zhàn)者發(fā)送來的已接受過其他人挑戰(zhàn)的消息
{
this.yjjstz(str);// 當知道挑戰(zhàn)者已經接受其他人挑戰(zhàn)的消息是做的操作
} 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)// 另一個用戶發(fā)來接受挑戰(zhàn)的信息
{
String name = str.substring(9);// 獲取另一個接受挑戰(zhàn)的玩家名字
try {
this.dos.writeUTF("#yjjstz#" + name);
} catch (Exception e) {
}
}
public void yjjstz(String str)// 挑戰(zhàn)者已經接受挑戰(zhàn)
{
String name = str.substring(8);
tzz = "";// 將挑戰(zhàn)者的名字清空
this.mj.yjjstz();// 調用主界面中挑戰(zhàn)者已經在同別人挑戰(zhàn)自己不能同發(fā)起者挑戰(zhàn)
JOptionPane.showMessageDialog(this.mj, name + "正在和其他玩家進行挑戰(zhàn)!!");
}
public void tiaozhan(String str)// 對方發(fā)來挑戰(zhàn)的信息后的操作
{
tzz = str.substring(10);// 記錄發(fā)起挑戰(zhàn)的人
this.mj.tz();// 調用主界面對方發(fā)來挑戰(zhàn)的方法
JOptionPane.showMessageDialog(this.mj, tzz + "向你發(fā)起挑戰(zhàn)!!");
}
public void jujue(String str) {
btzz = str.substring(6);
JOptionPane.showMessageDialog(this.mj, btzz + "拒絕了您的挑戰(zhàn) !!");
btzz = "";// 將被挑戰(zhàn)者清空
}
public void jieshou(String str) {
btzz = str.substring(9);
this.mj.jieshou1();// 調用主界面點擊接受按鈕接的方法
JOptionPane.showMessageDialog(this.mj, btzz + "接受您的挑戰(zhàn) !!");
}
public void btzzyjl(String str)// 當被挑戰(zhàn)者有記錄時
{
String name = str.substring(10);// 記錄發(fā)起挑戰(zhàn)的人
try {
this.dos.writeUTF("#yhfm#" + name);// 告訴發(fā)起挑戰(zhàn)的人正在挑戰(zhàn)中
} catch (Exception e) {
}
}
public void mang(String str) {
String name = str.substring(6);// 獲取到被挑戰(zhàn)者的名字
JOptionPane.showMessageDialog(this.mj, name + "正在接受挑戰(zhàn)!!");
}
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();// 調用主界面對方認輸?shù)姆椒? }
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)// 發(fā)起挑戰(zhàn)的方法
{
try {
tzz = this.getName();// 將自身線程的名字賦值給tzz
this.dos.writeUTF("#tiaozhan#" + str);// 將發(fā)起挑戰(zhàn)的人和被挑戰(zhàn)的人發(fā)送到服務器
} catch (Exception e) {
}
}
public void jieshou1()// 被挑戰(zhàn)方接受挑戰(zhàn)的方法
{
try {
this.btzz = this.getName();
this.dos.writeUTF("#jieshou#" + tzz);
} catch (Exception e) {
}
}
public void jujue1()// 被挑戰(zhàn)方拒絕挑戰(zhàn)的方法
{
try {
this.dos.writeUTF("#jjtz#" + tzz);// 將挑戰(zhàn)者的名字發(fā)送到服務器
tzz = "";// 將挑戰(zhàn)者的名字清空
} catch (Exception e) {
}
}
public void yhrs()// 主動認輸?shù)姆椒? {
if (this.getName().equals(btzz))// 如果自身是被挑戰(zhàn)者
{
try {
this.dos.writeUTF("#renshu#" + tzz);// 將認輸?shù)男畔l(fā)送到對方
} catch (Exception e) {
}
}
if (this.getName().equals(tzz))// 如果自身是挑戰(zhàn)者
{
try {
this.dos.writeUTF("#renshu#" + btzz);// 將認輸?shù)男畔l(fā)送到對方
} catch (Exception e) {
}
}
tzz = "";
btzz = "";
}
public String fhmz1() {
if (this.getName().equals(btzz))// 如果自身是被挑戰(zhàn)者
{
return tzz;
} else if (this.getName().equals(tzz))// 如果自身是挑戰(zhàn)者
{
return btzz;
}
return "aaaaa";
}
public void setfhmz1() {
// if(this.getName().equals(btzz))//如果自身是被挑戰(zhàn)者
// {
// btzz="";
// }
// else if(this.getName().equals(tzz))//如果自身是挑戰(zhàn)者
// {
// 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;// 棋盤的初始狀態(tài)
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;// 棋子的數(shù)組
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 {// 將該移動信息發(fā)送給對方
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();// 獲得事件發(fā)生的坐標點
double x = p.getX();
double y = p.getY();
if (Math.abs((x - 60) / 1 % 50) <= 15) {// 獲得對應于數(shù)組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) {// 獲得對應于數(shù)組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);// 將該棋子設為選中狀態(tài)
zt = true;// 將focus設為true
Sx = i;// 保存該坐標點
Sy = j;
}
} else// 如果是白方
{
if (this.arr[i][j].getColor().equals(jm.color2))// 如果該棋子是白色
{
this.arr[i][j].setFlag(true);// 將該棋子設為選中狀態(tài)
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);// 將該棋設為非選中狀態(tài)
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 {// 將該移動信息發(fā)送給對方
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);// 將該棋設為非選中狀態(tài).
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、象棋規(guī)則
package jiem;
public class Guize {
QZ[][] arr;// 聲明棋子的數(shù)組
int x;// 棋子的起始X坐標
int y;// 棋子的起始Y坐標
boolean canmove = false;// 判斷棋子是否能移動的標志位
public Guize(QZ[][] arr)// 構造函數(shù) 參數(shù)QZ類
{
this.arr = arr;
}
// 棋子移動時判斷的方法,參數(shù):起始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)// 車的走棋規(guī)則
{
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)// 馬的走棋規(guī)則
{
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)// 相的走棋規(guī)則
{
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)// 象的走棋規(guī)則
{
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)// 士的走棋規(guī)則
{
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)// 帥的走棋規(guī)則
{
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)// 炮的移動規(guī)則
{
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)// 兵的走棋規(guī)則
{
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)// 卒的走棋規(guī)則
{
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;
}
}
}
}
參考
我要自學網(wǎng): http://www.51zxw.net/list.aspx?cid=446