Java实践(十二)——中国象棋

一、实践目的:

1.鼠标点击、拖动等事件的应用与区别

2.棋谱文件的保存与读取

3.完善象棋的规则。

二、实践内容:

中国象棋历史悠久,吸引了无数的人研究,现对中国象棋的对战和实现棋谱的制作做如下的设计和说明,供大家参考学习。

1、机机对弈,红方先手。在符合规则的情况下拖动棋子到目的地,松鼠标落子。


人人对弈图

2、制作棋谱,选择制作棋谱菜单后,对弈开始,并记录了下棋过程。


选择“制作棋谱”菜单




棋谱制作完毕红方胜出

一方胜出后弹出胜利消息对话框。点击确定后,选择“保存棋谱”菜单,弹出保存文件对话框。


保存棋谱对话框

3.演示棋谱,选择演示棋谱菜单后,弹出打开对话框,选择保存好的棋谱,开始演示。


演示棋谱对话框



演示棋谱过程(自动和手动两种)

三、参考代码:

1.象棋主类 文件ChineseChess.java

package cn.edu.ouc.chineseChess;

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.util.LinkedList;

/**
 * 象棋主类
 * 
 * @author cnlht
 */
public class ChineseChess extends JFrame implements ActionListener {
	ChessBoard board = null;
	Demon demon = null;
	MakeChessManual record = null;
	Container con = null;
	JMenuBar bar;
	JMenu fileMenu;
	JMenuItem 制作棋谱, 保存棋谱, 演示棋谱;
	JFileChooser fileChooser = null;
	LinkedList 棋谱 = null;

	public ChineseChess() {
		bar = new JMenuBar();
		fileMenu = new JMenu("中国象棋");
		制作棋谱 = new JMenuItem("制作棋谱");
		保存棋谱 = new JMenuItem("保存棋谱");
		保存棋谱.setEnabled(false);
		演示棋谱 = new JMenuItem("演示棋谱");
		fileMenu.add(制作棋谱);
		fileMenu.add(保存棋谱);
		fileMenu.add(演示棋谱);
		bar.add(fileMenu);
		setJMenuBar(bar);
		setTitle(制作棋谱.getText());
		制作棋谱.addActionListener(this);
		保存棋谱.addActionListener(this);
		演示棋谱.addActionListener(this);
		board = new ChessBoard(45, 45, 9, 10);
		record = board.record;
		con = getContentPane();
		JSplitPane split = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, true,
				board, record);
		split.setDividerSize(5);
		split.setDividerLocation(460);
		con.add(split, BorderLayout.CENTER);
		addWindowListener(new WindowAdapter() {
			public void windowClosing(WindowEvent e) {
				System.exit(0);
			}
		});
		setVisible(true);
		setBounds(60, 20, 690, 540);
		fileChooser = new JFileChooser();
		con.validate();
		validate();
	}

	public void actionPerformed(ActionEvent e) {
		if (e.getSource() == 制作棋谱) {
			con.removeAll();
			保存棋谱.setEnabled(true);
			this.setTitle(制作棋谱.getText());
			board = new ChessBoard(45, 45, 9, 10);
			record = board.record;
			JSplitPane split = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT,
					true, board, record);
			split.setDividerSize(5);
			split.setDividerLocation(460);
			con.add(split, BorderLayout.CENTER);
			validate();
		}
		if (e.getSource() == 保存棋谱) {
			int state = fileChooser.showSaveDialog(null);
			File saveFile = fileChooser.getSelectedFile();
			if (saveFile != null && state == JFileChooser.APPROVE_OPTION) {
				try {
					FileOutputStream outOne = new FileOutputStream(saveFile);
					ObjectOutputStream outTwo = new ObjectOutputStream(outOne);
					outTwo.writeObject(record.获取棋谱());
					outOne.close();
					outTwo.close();
				} catch (IOException event) {
				}
			}
		}
		if (e.getSource() == 演示棋谱) {
			con.removeAll();
			con.repaint();
			con.validate();
			validate();
			保存棋谱.setEnabled(false);

			int state = fileChooser.showOpenDialog(null);
			File openFile = fileChooser.getSelectedFile();
			if (openFile != null && state == JFileChooser.APPROVE_OPTION) {
				try {
					FileInputStream inOne = new FileInputStream(openFile);
					ObjectInputStream inTwo = new ObjectInputStream(inOne);
					棋谱 = (LinkedList) inTwo.readObject();
					inOne.close();
					inTwo.close();
					ChessBoard board = new ChessBoard(45, 45, 9, 10);
					demon = new Demon(board);
					demon.set棋谱(棋谱);
					con.add(demon, BorderLayout.CENTER);
					con.validate();
					validate();
					this.setTitle(演示棋谱.getText() + ":" + openFile);
				} catch (Exception event) {
					JLabel label = new JLabel("不是棋谱文件");
					label.setFont(new Font("隶书", Font.BOLD, 60));
					label.setForeground(Color.red);
					label.setHorizontalAlignment(SwingConstants.CENTER);
					con.add(label, BorderLayout.CENTER);
					con.validate();
					this.setTitle("没有打开棋谱");
					validate();
				}
			} else {
				JLabel label = new JLabel("没有打开棋谱文件呢");
				label.setFont(new Font("隶书", Font.BOLD, 50));
				label.setForeground(Color.pink);
				label.setHorizontalAlignment(SwingConstants.CENTER);
				con.add(label, BorderLayout.CENTER);
				con.validate();
				this.setTitle("没有打开棋谱文件呢");
				validate();
			}
		}
	}

	public static void main(String args[]) {
		new ChineseChess();
	}
}

2.象棋棋盘类文件ChessBoard.java

package cn.edu.ouc.chineseChess;

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

/**
 * 棋盘类
 * 
 * @author cnlht
 */
public class ChessBoard extends JPanel implements MouseListener,
		MouseMotionListener {
	public ChessPoint point[][];
	public int unitWidth, unitHeight;
	private int x轴长, y轴长;
	private int x, y;
	private Image img;
	protected Image pieceImg;
	private boolean move = false;
	public String 红方颜色 = "红方", 黑方颜色 = "黑方";
	ChessPiece 红车1, 红车2, 红马1, 红马2, 红相1, 红相2, 红帅, 红士1, 红士2, 红兵1, 红兵2, 红兵3, 红兵4,
			红兵5, 红炮1, 红炮2;
	ChessPiece 黑车1, 黑车2, 黑马1, 黑马2, 黑将, 黑士1, 黑士2, 黑卒1, 黑卒2, 黑卒3, 黑卒4, 黑卒5, 黑象1,
			黑象2, 黑炮1, 黑炮2;

	int startX, startY;
	int startI, startJ;
	public boolean 红方走棋 = true, 黑方走棋 = false;
	Rule rule = null;
	public MakeChessManual record = null;

	public ChessBoard(int w, int h, int r, int c) {
		setLayout(null);
		addMouseListener(this);
		addMouseMotionListener(this);
		Color bc = getBackground();
		unitWidth = w;
		unitHeight = h;
		x轴长 = r;
		y轴长 = c;

		point = new ChessPoint[r + 1][c + 1];

		for (int i = 1; i <= r; i++) {
			for (int j = 1; j <= c; j++) {
				point[i][j] = new ChessPoint(i * unitWidth, j * unitHeight,
						false);
			}
		}

		rule = new Rule(this, point);
		record = new MakeChessManual(this, point);

		img = Toolkit.getDefaultToolkit().getImage("board.jpg");
		pieceImg = Toolkit.getDefaultToolkit().getImage("piece.gif");
		
		红车1 = new ChessPiece("車", Color.red, bc, w - 4, h - 4, this);
		红车1.set棋子类别(红方颜色);
		红车2 = new ChessPiece("車", Color.red, bc, w - 4, h - 4, this);
		红车2.set棋子类别(红方颜色);
		红马1 = new ChessPiece("馬", Color.red, bc, w - 4, h - 4, this);
		红马1.set棋子类别(红方颜色);
		红马2 = new ChessPiece("馬", Color.red, bc, w - 4, h - 4, this);
		红马2.set棋子类别(红方颜色);
		红炮1 = new ChessPiece("炮", Color.red, bc, w - 4, h - 4, this);
		红炮1.set棋子类别(红方颜色);
		红炮2 = new ChessPiece("炮", Color.red, bc, w - 4, h - 4, this);
		红炮2.set棋子类别(红方颜色);
		红相1 = new ChessPiece("相", Color.red, bc, w - 4, h - 4, this);
		红相1.set棋子类别(红方颜色);
		红相2 = new ChessPiece("相", Color.red, bc, w - 4, h - 4, this);
		红相2.set棋子类别(红方颜色);
		红士1 = new ChessPiece("仕", Color.red, bc, w - 4, h - 4, this);
		红士1.set棋子类别(红方颜色);
		红士2 = new ChessPiece("仕", Color.red, bc, w - 4, h - 4, this);
		红士2.set棋子类别(红方颜色);
		红帅 = new ChessPiece("帅", Color.red, bc, w - 4, h - 4, this);
		红帅.set棋子类别(红方颜色);
		红兵1 = new ChessPiece("兵", Color.red, bc, w - 4, h - 4, this);
		红兵1.set棋子类别(红方颜色);
		红兵2 = new ChessPiece("兵", Color.red, bc, w - 4, h - 4, this);
		红兵2.set棋子类别(红方颜色);
		红兵3 = new ChessPiece("兵", Color.red, bc, w - 4, h - 4, this);
		红兵3.set棋子类别(红方颜色);
		红兵4 = new ChessPiece("兵", Color.red, bc, w - 4, h - 4, this);
		红兵4.set棋子类别(红方颜色);
		红兵5 = new ChessPiece("兵", Color.red, bc, w - 4, h - 4, this);
		红兵5.set棋子类别(红方颜色);

		黑将 = new ChessPiece("将", Color.black, bc, w - 4, h - 4, this);
		黑将.set棋子类别(黑方颜色);
		黑士1 = new ChessPiece("士", Color.black, bc, w - 4, h - 4, this);
		黑士1.set棋子类别(黑方颜色);
		黑士2 = new ChessPiece("士", Color.black, bc, w - 4, h - 4, this);
		黑士2.set棋子类别(黑方颜色);
		黑车1 = new ChessPiece("车", Color.black, bc, w - 4, h - 4, this);
		黑车1.set棋子类别(黑方颜色);
		黑车2 = new ChessPiece("车", Color.black, bc, w - 4, h - 4, this);
		黑车2.set棋子类别(黑方颜色);
		黑炮1 = new ChessPiece("炮", Color.black, bc, w - 4, h - 4, this);
		黑炮1.set棋子类别(黑方颜色);
		黑炮2 = new ChessPiece("炮", Color.black, bc, w - 4, h - 4, this);
		黑炮2.set棋子类别(黑方颜色);
		黑象1 = new ChessPiece("象", Color.black, bc, w - 4, h - 4, this);
		黑象1.set棋子类别(黑方颜色);
		黑象2 = new ChessPiece("象", Color.black, bc, w - 4, h - 4, this);
		黑象2.set棋子类别(黑方颜色);
		黑马1 = new ChessPiece("马", Color.black, bc, w - 4, h - 4, this);
		黑马1.set棋子类别(黑方颜色);
		黑马2 = new ChessPiece("马", Color.black, bc, w - 4, h - 4, this);
		黑马2.set棋子类别(黑方颜色);
		黑卒1 = new ChessPiece("卒", Color.black, bc, w - 4, h - 4, this);
		黑卒1.set棋子类别(黑方颜色);
		黑卒2 = new ChessPiece("卒", Color.black, bc, w - 4, h - 4, this);
		黑卒2.set棋子类别(黑方颜色);
		黑卒3 = new ChessPiece("卒", Color.black, bc, w - 4, h - 4, this);
		黑卒3.set棋子类别(黑方颜色);
		黑卒4 = new ChessPiece("卒", Color.black, bc, w - 4, h - 4, this);
		黑卒4.set棋子类别(黑方颜色);
		黑卒5 = new ChessPiece("卒", Color.black, bc, w - 4, h - 4, this);
		黑卒5.set棋子类别(黑方颜色);
		point[1][10].setPiece(红车1, this);
		point[2][10].setPiece(红马1, this);
		point[3][10].setPiece(红相1, this);
		point[4][10].setPiece(红士1, this);
		point[5][10].setPiece(红帅, this);
		point[6][10].setPiece(红士2, this);
		point[7][10].setPiece(红相2, this);
		point[8][10].setPiece(红马2, this);
		point[9][10].setPiece(红车2, this);
		point[2][8].setPiece(红炮1, this);
		point[8][8].setPiece(红炮2, this);
		point[1][7].setPiece(红兵1, this);
		point[3][7].setPiece(红兵2, this);
		point[5][7].setPiece(红兵3, this);
		point[7][7].setPiece(红兵4, this);
		point[9][7].setPiece(红兵5, this);

		point[1][1].setPiece(黑车1, this);
		point[2][1].setPiece(黑马1, this);
		point[3][1].setPiece(黑象1, this);
		point[4][1].setPiece(黑士1, this);
		point[5][1].setPiece(黑将, this);
		point[6][1].setPiece(黑士2, this);
		point[7][1].setPiece(黑象2, this);
		point[8][1].setPiece(黑马2, this);
		point[9][1].setPiece(黑车2, this);
		point[2][3].setPiece(黑炮1, this);
		point[8][3].setPiece(黑炮2, this);
		point[1][4].setPiece(黑卒1, this);
		point[3][4].setPiece(黑卒2, this);
		point[5][4].setPiece(黑卒3, this);
		point[7][4].setPiece(黑卒4, this);
		point[9][4].setPiece(黑卒5, this);

	}

	public void paintComponent(Graphics g) {
		super.paintComponent(g);

		int imgWidth = img.getWidth(this);
		int imgHeight = img.getHeight(this);// 获得图片的宽度与高度
		int FWidth = getWidth();
		int FHeight = getHeight();// 获得窗口的宽度与高度
		int x = (FWidth - imgWidth) / 2;
		int y = (FHeight - imgHeight) / 2;
		g.drawImage(img, x, y, null);

		for (int j = 1; j <= y轴长; j++) {
			g.drawLine(point[1][j].x, point[1][j].y, point[x轴长][j].x,
					point[x轴长][j].y);
		}
		for (int i = 1; i <= x轴长; i++) {
			if (i != 1 && i != x轴长) {
				g.drawLine(point[i][1].x, point[i][1].y, point[i][y轴长 - 5].x,
						point[i][y轴长 - 5].y);
				g.drawLine(point[i][y轴长 - 4].x, point[i][y轴长 - 4].y,
						point[i][y轴长].x, point[i][y轴长].y);
			} else {
				g.drawLine(point[i][1].x, point[i][1].y, point[i][y轴长].x,
						point[i][y轴长].y);
			}
		}

		g.drawLine(point[4][1].x, point[4][1].y, point[6][3].x, point[6][3].y);
		g.drawLine(point[6][1].x, point[6][1].y, point[4][3].x, point[4][3].y);
		g.drawLine(point[4][8].x, point[4][8].y, point[6][y轴长].x,
				point[6][y轴长].y);
		g.drawLine(point[4][y轴长].x, point[4][y轴长].y, point[6][8].x,
				point[6][8].y);

		for (int i = 1; i <= x轴长; i++) {
			g.drawString("" + i, i * unitWidth, unitHeight / 2);
		}
		int j = 1;
		for (char c = 'A'; c <= 'J'; c++) {
			g.drawString("" + c, unitWidth / 4, j * unitHeight);
			j++;
		}

	}

	/**鼠标按下事件*/
	public void mousePressed(MouseEvent e) {
		ChessPiece piece = null;
		Rectangle rect = null;
		if (e.getSource() == this)
			move = false;
		if (move == false)
			if (e.getSource() instanceof ChessPiece) {
				piece = (ChessPiece) e.getSource();
				startX = piece.getBounds().x;
				startY = piece.getBounds().y;

				rect = piece.getBounds();
				for (int i = 1; i <= x轴长; i++) {
					for (int j = 1; j <= y轴长; j++) {
						int x = point[i][j].getX();
						int y = point[i][j].getY();
						if (rect.contains(x, y)) {
							startI = i;
							startJ = j;
							break;
						}

					}
				}
			}
	}

	public void mouseMoved(MouseEvent e) {
	}

	/**鼠标拖动事件*/
	public void mouseDragged(MouseEvent e) {

		ChessPiece piece = null;
		if (e.getSource() instanceof ChessPiece) {
			piece = (ChessPiece) e.getSource();

			move = true;

			e = SwingUtilities.convertMouseEvent(piece, e, this);
		}

		if (e.getSource() == this) {
			if (move && piece != null) {
				x = e.getX();
				y = e.getY();
				if (红方走棋 && ((piece.棋子类别()).equals(红方颜色))) {
					piece.setLocation(x - piece.getWidth() / 2,
							y - piece.getHeight() / 2);
				}
				if (黑方走棋 && (piece.棋子类别().equals(黑方颜色))) {
					piece.setLocation(x - piece.getWidth() / 2,
							y - piece.getHeight() / 2);
				}
			}
		}
	}

	/**松开鼠标事件*/
	public void mouseReleased(MouseEvent e) {
		ChessPiece piece = null;
		move = false;
		Rectangle rect = null;
		if (e.getSource() instanceof ChessPiece) {
			piece = (ChessPiece) e.getSource();
			rect = piece.getBounds();

			e = SwingUtilities.convertMouseEvent(piece, e, this);
		}
		if (e.getSource() == this) {
			boolean containChessPoint = false;
			int x = 0, y = 0;
			int m = 0, n = 0;
			if (piece != null) {
				for (int i = 1; i <= x轴长; i++) {
					for (int j = 1; j <= y轴长; j++) {
						x = point[i][j].getX();
						y = point[i][j].getY();
						if (rect.contains(x, y)) {

							containChessPoint = true;
							m = i;
							n = j;
							break;
						}

					}
				}
			}
			if (piece != null && containChessPoint) {
				Color pieceColor = piece.获取棋子颜色();
				if (point[m][n].isPiece()) {
					Color c = (point[m][n].getPiece()).获取棋子颜色();
					if (pieceColor.getRGB() == c.getRGB()) {
						piece.setLocation(startX, startY);

						(point[startI][startJ]).set有棋子(true);
					} else {
						boolean ok = rule.movePieceRule(piece, startI, startJ,
								m, n);
						if (ok) {
							ChessPiece pieceRemoved = point[m][n].getPiece();
							point[m][n].reMovePiece(pieceRemoved, this);
							point[m][n].setPiece(piece, this);
							(point[startI][startJ]).set有棋子(false);
							record.记录棋谱(piece, startI, startJ, m, n);
							record.记录吃掉的棋子(pieceRemoved);
							rule.isWine(pieceRemoved);
							if (piece.棋子类别().equals(红方颜色)) {
								红方走棋 = false;
								黑方走棋 = true;
							}
							if (piece.棋子类别().equals(黑方颜色)) {
								黑方走棋 = false;
								红方走棋 = true;
							}
							validate();
							repaint();
						} else {
							piece.setLocation(startX, startY);
							(point[startI][startJ]).set有棋子(true);
						}
					}

				} else {

					boolean ok = rule
							.movePieceRule(piece, startI, startJ, m, n);
					if (ok) {
						point[m][n].setPiece(piece, this);
						(point[startI][startJ]).set有棋子(false);
						record.记录棋谱(piece, startI, startJ, m, n);
						record.记录吃掉的棋子("没吃棋子");

						if (piece.棋子类别().equals(红方颜色)) {
							红方走棋 = false;
							黑方走棋 = true;
						}
						if (piece.棋子类别().equals(黑方颜色)) {
							黑方走棋 = false;
							红方走棋 = true;
						}
					} else {
						piece.setLocation(startX, startY);
						(point[startI][startJ]).set有棋子(true);
					}
				}
			}

			if (piece != null && !containChessPoint) {
				piece.setLocation(startX, startY);
				(point[startI][startJ]).set有棋子(true);
			}
		}
	}

	public void mouseEntered(MouseEvent e) {
	}

	public void mouseExited(MouseEvent e) {
	}

	public void mouseClicked(MouseEvent e) {
	}
}

3.棋子类文件ChessPiece.java

package cn.edu.ouc.chineseChess;

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

/**
 * 棋子类
 * 
 * @author cnlht
 */
public class ChessPiece extends JLabel {
	String name; // 棋子名字
	Color backColor = null, foreColor;// 背景色和前景色
	String 颜色类别 = null;
	ChessBoard board = null;
	int width, height;// 大小

	public ChessPiece(String name, Color fc, Color bc, int width, int height,
			ChessBoard board) {// 构造棋子
		this.name = name;
		this.board = board;
		this.width = width;
		this.height = height;
		foreColor = fc;
		backColor = bc;
		setSize(width, height);
		setBackground(bc);
		addMouseMotionListener(board);
		addMouseListener(board);
	}

	// 绘制棋子
	public void paint(Graphics g) {		
		g.drawImage(board.pieceImg, 2, 2, width-2, height-2, null);
		g.setColor(foreColor);
		g.setFont(new Font("楷体", Font.BOLD, 26));
		g.drawString(name, 7, height - 8);// 在棋子上绘制 “棋子名”
		g.setColor(Color.black);
		//g.drawOval(1, 1, width - 1, height - 1);
		float lineWidth = 2.3f;
	    ((Graphics2D)g).setStroke(new BasicStroke(lineWidth));
	    ((Graphics2D)g).drawOval(2, 2, width-2, height-2);
	}

	public int getWidth() {
		return width;
	}

	public int getHeight() {
		return height;
	}

	public String getName() {
		return name;
	}

	public Color 获取棋子颜色() {
		return foreColor;
	}

	public void set棋子类别(String 类别) {
		颜色类别 = 类别;
	}

	public String 棋子类别() {
		return 颜色类别;
	}
}

4.棋子点坐标类文件

package cn.edu.ouc.chineseChess;

/**
 * 棋点类
 * 
 * @author cnlht
 */
public class ChessPoint {
	/** 棋子坐标 */
	int x, y;
	
	/** 该坐标 是否有子*/
	boolean 有棋子;
	
	/** 改坐标的棋子 */
	ChessPiece piece = null;
	
	/** 坐标所属棋盘 */
	ChessBoard board = null;

	public ChessPoint(int x, int y, boolean boo) {
		this.x = x;
		this.y = y;
		有棋子 = boo;
	}

	public boolean isPiece() {
		return 有棋子;
	}

	public void set有棋子(boolean boo) {
		有棋子 = boo;
	}

	public int getX() {
		return x;
	}

	public int getY() {
		return y;
	}

	// 设置改点棋子
	public void setPiece(ChessPiece piece, ChessBoard board) {
		this.board = board;
		this.piece = piece;
		board.add(piece);
		int w = (board.unitWidth);
		int h = (board.unitHeight);
		piece.setBounds(x - w / 2, y - h / 2, w, h);// 棋子位置,宽度,高度
		有棋子 = true;
		board.validate();
	}

	public ChessPiece getPiece() {
		return piece;
	}

	public void reMovePiece(ChessPiece piece, ChessBoard board) {
		this.board = board;
		this.piece = piece;
		board.remove(piece);
		board.validate();
		有棋子 = false;
	}
}


5.玩法规则类文件Rule.java

package cn.edu.ouc.chineseChess;

import javax.swing.*;

import java.awt.*;
import java.awt.event.*;

/**
 * 走棋规则类
 * 
 * @author cnlht
 */
public class Rule {
	ChessBoard board = null;
	ChessPiece piece = null;
	ChessPoint point[][];
	int startI, startJ, endI, endJ;

	public Rule(ChessBoard board, ChessPoint point[][]) {
		this.board = board;
		this.point = point;
	}

	public void isWine(ChessPiece piece) {
		this.piece = piece;
		if (piece.getName() == "将" || piece.getName() == "帅") {
			if (piece.颜色类别 == "红方") {
				JOptionPane.showMessageDialog(null, "黑方  胜利!");
			} else {
				JOptionPane.showMessageDialog(null, "红方  胜利!");
			}
		}
	}

	public boolean movePieceRule(ChessPiece piece, int startI, int startJ,
			int endI, int endJ) {
		this.piece = piece;
		this.startI = startI;
		this.startJ = startJ;
		this.endI = endI;
		this.endJ = endJ;
		int minI = Math.min(startI, endI);
		int maxI = Math.max(startI, endI);
		int minJ = Math.min(startJ, endJ);
		int maxJ = Math.max(startJ, endJ);
		boolean 可否走棋 = false;
		if (piece.getName().equals("车")) {
			if (startI == endI) {
				int j = 0;
				for (j = minJ + 1; j <= maxJ - 1; j++) {
					if (point[startI][j].isPiece()) {
						可否走棋 = false;
						break;
					}
				}
				if (j == maxJ) {
					可否走棋 = true;
				}
			} else if (startJ == endJ) {
				int i = 0;
				for (i = minI + 1; i <= maxI - 1; i++) {
					if (point[i][startJ].isPiece()) {
						可否走棋 = false;
						break;
					}
				}
				if (i == maxI) {
					可否走棋 = true;
				}
			} else {
				可否走棋 = false;
			}

		} else if (piece.getName().equals("車")) {
			if (startI == endI) {
				int j = 0;
				for (j = minJ + 1; j <= maxJ - 1; j++) {
					if (point[startI][j].isPiece()) {
						可否走棋 = false;
						break;
					}
				}
				if (j == maxJ) {
					可否走棋 = true;
				}
			} else if (startJ == endJ) {
				int i = 0;
				for (i = minI + 1; i <= maxI - 1; i++) {
					if (point[i][startJ].isPiece()) {
						可否走棋 = false;
						break;
					}
				}
				if (i == maxI) {
					可否走棋 = true;
				}
			} else {
				可否走棋 = false;
			}

		}else if (piece.getName().equals("马")) {
			int xAxle = Math.abs(startI - endI);
			int yAxle = Math.abs(startJ - endJ);

			if (xAxle == 2 && yAxle == 1) {
				if (endI > startI) {
					if (point[startI + 1][startJ].isPiece()) {
						可否走棋 = false;
					} else {
						可否走棋 = true;
					}
				}
				if (endI < startI) {
					if (point[startI - 1][startJ].isPiece()) {
						可否走棋 = false;
					} else {
						可否走棋 = true;
					}
				}

			}else if (xAxle == 1 && yAxle == 2) {
				if (endJ > startJ) {
					if (point[startI][startJ + 1].isPiece()) {
						可否走棋 = false;
					} else {
						可否走棋 = true;
					}
				}
				if (endJ < startJ) {
					if (point[startI][startJ - 1].isPiece()) {
						可否走棋 = false;
					} else {
						可否走棋 = true;
					}
				}

			} else {
				可否走棋 = false;
			}
		} else if (piece.getName().equals("馬")) {
			int xAxle = Math.abs(startI - endI);
			int yAxle = Math.abs(startJ - endJ);

			if (xAxle == 2 && yAxle == 1) {
				if (endI > startI) {
					if (point[startI + 1][startJ].isPiece()) {
						可否走棋 = false;
					} else {
						可否走棋 = true;
					}
				}
				if (endI < startI) {
					if (point[startI - 1][startJ].isPiece()) {
						可否走棋 = false;
					} else {
						可否走棋 = true;
					}
				}

			}else if (xAxle == 1 && yAxle == 2) {
				if (endJ > startJ) {
					if (point[startI][startJ + 1].isPiece()) {
						可否走棋 = false;
					} else {
						可否走棋 = true;
					}
				}
				if (endJ < startJ) {
					if (point[startI][startJ - 1].isPiece()) {
						可否走棋 = false;
					} else {
						可否走棋 = true;
					}
				}

			} else {
				可否走棋 = false;
			}
		} else if (piece.getName().equals("象")) {
			int centerI = (startI + endI) / 2;
			int centerJ = (startJ + endJ) / 2;
			int xAxle = Math.abs(startI - endI);
			int yAxle = Math.abs(startJ - endJ);
			if (xAxle == 2 && yAxle == 2 && endJ <= 5) {
				if (point[centerI][centerJ].isPiece()) {
					可否走棋 = false;
				} else {
					可否走棋 = true;
				}
			} else {
				可否走棋 = false;
			}
		} else if (piece.getName().equals("相")) {
			int centerI = (startI + endI) / 2;
			int centerJ = (startJ + endJ) / 2;
			int xAxle = Math.abs(startI - endI);
			int yAxle = Math.abs(startJ - endJ);
			if (xAxle == 2 && yAxle == 2 && endJ >= 6) {
				if (point[centerI][centerJ].isPiece()) {
					可否走棋 = false;
				} else {
					可否走棋 = true;
				}
			} else {
				可否走棋 = false;
			}
		} else if (piece.getName().equals("炮")) {
			int number = 0;
			if (startI == endI) {
				int j = 0;
				for (j = minJ + 1; j <= maxJ - 1; j++) {
					if (point[startI][j].isPiece()) {
						number++;
					}
				}
				if (number > 1) {
					可否走棋 = false;
				} else if (number == 1) {
					if (point[endI][endJ].isPiece()) {
						可否走棋 = true;
					}
				} else if (number == 0 && !point[endI][endJ].isPiece()) {
					可否走棋 = true;
				}
			} else if (startJ == endJ) {
				int i = 0;
				for (i = minI + 1; i <= maxI - 1; i++) {
					if (point[i][startJ].isPiece()) {
						number++;
					}
				}
				if (number > 1) {
					可否走棋 = false;
				} else if (number == 1) {
					if (point[endI][endJ].isPiece()) {
						可否走棋 = true;
					}
				} else if (number == 0 && !point[endI][endJ].isPiece()) {
					可否走棋 = true;
				}
			} else {
				可否走棋 = false;
			}
		} else if (piece.getName().equals("兵")) {
			int xAxle = Math.abs(startI - endI);
			int yAxle = Math.abs(startJ - endJ);

			if (endJ >= 6) {
				if (startJ - endJ == 1 && xAxle == 0) {
					可否走棋 = true;
				}

				else {
					可否走棋 = false;
				}
			} else if (endJ <= 5) {
				if ((startJ - endJ == 1) && (xAxle == 0)) {
					可否走棋 = true;
				} else if ((endJ - startJ == 0) && (xAxle == 1)) {
					可否走棋 = true;
				} else {
					可否走棋 = false;
				}
			}
		} else if (piece.getName().equals("卒")) {
			int xAxle = Math.abs(startI - endI);
			int yAxle = Math.abs(startJ - endJ);

			if (endJ <= 5) {
				if (endJ - startJ == 1 && xAxle == 0) {
					可否走棋 = true;
				} else {
					可否走棋 = false;
				}
			} else if (endJ >= 6) {
				if ((endJ - startJ == 1) && (xAxle == 0)) {
					可否走棋 = true;
				} else if ((endJ - startJ == 0) && (xAxle == 1)) {
					可否走棋 = true;
				} else {
					可否走棋 = false;
				}
			}
		}

		else if (piece.getName().equals("士")) {
			int xAxle = Math.abs(startI - endI);
			int yAxle = Math.abs(startJ - endJ);
			if (endI <= 6 && endI >= 4 && xAxle == 1 && yAxle == 1) {
				可否走棋 = true;
			} else {
				可否走棋 = false;
			}
		} else if (piece.getName().equals("仕")) {
			int xAxle = Math.abs(startI - endI);
			int yAxle = Math.abs(startJ - endJ);
			if (endI <= 6 && endI >= 4 && xAxle == 1 && yAxle == 1) {
				可否走棋 = true;
			} else {
				可否走棋 = false;
			}
		} else if ((piece.getName().equals("帅"))
				|| (piece.getName().equals("将"))) {
			int xAxle = Math.abs(startI - endI);
			int yAxle = Math.abs(startJ - endJ);
			if (endI <= 6 && endI >= 4) {
				if ((xAxle == 1 && yAxle == 0) || (xAxle == 0 && yAxle == 1)) {
					可否走棋 = true;
				} else {
					可否走棋 = false;
				}
			} else {
				可否走棋 = false;
			}
		}

		return 可否走棋;

	}
}

6.走步类文件MoveStep.java

package cn.edu.ouc.chineseChess;

import java.awt.Point;

/**
 * 走步类
 * 
 * @author cnlht
 * 
 */
public class MoveStep implements java.io.Serializable {
	public Point pStart, pEnd;

	public MoveStep(Point p1, Point p2) {
		pStart = p1;
		pEnd = p2;
	}
}


7.制作棋谱类MakeChessManual.java

package cn.edu.ouc.chineseChess;

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.LinkedList;

/**
 * 制作棋谱类
 * 
 * @author cnlht
 */
public class MakeChessManual extends JPanel implements ActionListener {
	JTextArea text = null;
	JScrollPane scroll = null;
	ChessBoard board = null;
	ChessPoint[][] point;
	LinkedList 棋谱 = null;
	LinkedList 吃掉的棋子 = null;
	JButton buttonUndo;
	int i = 0;

	public MakeChessManual(ChessBoard board, ChessPoint[][] point) {
		this.board = board;
		this.point = point;
		text = new JTextArea();
		scroll = new JScrollPane(text);
		棋谱 = new LinkedList();
		吃掉的棋子 = new LinkedList();
		buttonUndo = new JButton("悔棋");
		buttonUndo.setFont(new Font("隶书", Font.PLAIN, 18));
		setLayout(new BorderLayout());
		add(scroll, BorderLayout.CENTER);
		add(buttonUndo, BorderLayout.SOUTH);
		buttonUndo.addActionListener(this);
	}

	public char numberToLetter(int n) {
		char c = '\0';
		switch (n) {
		case 1:
			c = 'A';
			break;
		case 2:
			c = 'B';
			break;
		case 3:
			c = 'C';
			break;
		case 4:
			c = 'D';
			break;
		case 5:
			c = 'E';
			break;
		case 6:
			c = 'F';
			break;
		case 7:
			c = 'G';
			break;
		case 8:
			c = 'H';
			break;
		case 9:
			c = 'I';
			break;
		case 10:
			c = 'J';
			break;
		}
		return c;
	}

	public void 记录棋谱(ChessPiece piece, int startI, int startJ, int endI,
			int endJ) {
		Point pStart = new Point(startI, startJ);
		Point pEnd = new Point(endI, endJ);
		MoveStep step = new MoveStep(pStart, pEnd);
		棋谱.add(step);

		String 棋子类别 = piece.棋子类别();
		String name = piece.getName();
		String m = "#" + 棋子类别 + name + ": " + startI + numberToLetter(startJ)
				+ " 到 " + endI + numberToLetter(endJ);
		text.append(m);
		if (piece.棋子类别().equals(board.黑方颜色))
			text.append("\n");
	}

	public void 记录吃掉的棋子(Object object) {
		吃掉的棋子.add(object);
	}

	public LinkedList 获取棋谱() {
		return 棋谱;
	}

	public void actionPerformed(ActionEvent e) {
		int position = text.getText().lastIndexOf("#");
		if (position != -1)
			text.replaceRange("", position, text.getText().length());
		if (棋谱.size() > 0) {
			MoveStep lastStep = (MoveStep) 棋谱.getLast();
			棋谱.removeLast();
			Object qizi = 吃掉的棋子.getLast();
			吃掉的棋子.removeLast();
			String temp = qizi.toString();
			if (temp.equals("没吃棋子")) {
				int startI = lastStep.pStart.x;
				int startJ = lastStep.pStart.y;
				int endI = lastStep.pEnd.x;
				int endJ = lastStep.pEnd.y;
				ChessPiece piece = point[endI][endJ].getPiece();

				point[startI][startJ].setPiece(piece, board);
				(point[endI][endJ]).set有棋子(false);

				if (piece.棋子类别().equals(board.红方颜色)) {
					board.红方走棋 = true;
					board.黑方走棋 = false;
				}
				if (piece.棋子类别().equals(board.黑方颜色)) {
					board.黑方走棋 = true;
					board.红方走棋 = false;
				}
			} else {
				ChessPiece removedPiece = (ChessPiece) qizi;
				int startI = lastStep.pStart.x;
				int startJ = lastStep.pStart.y;
				int endI = lastStep.pEnd.x;
				int endJ = lastStep.pEnd.y;
				ChessPiece piece = point[endI][endJ].getPiece();
				point[startI][startJ].setPiece(piece, board);
				point[endI][endJ].setPiece(removedPiece, board);
				(point[endI][endJ]).set有棋子(true);

				if (piece.棋子类别().equals(board.红方颜色)) {
					board.红方走棋 = true;
					board.黑方走棋 = false;
				}
				if (piece.棋子类别().equals(board.黑方颜色)) {
					board.黑方走棋 = true;
					board.红方走棋 = false;
				}
			}
		}
	}
}


8.演示棋谱类文件Demon.java

package cn.edu.ouc.chineseChess;

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.*;

/**
 * 演示棋谱类
 * 
 * @author cnlht
 */
public class Demon extends JPanel implements ActionListener, Runnable {
	public JButton replay = null, next = null, auto = null, stop = null;
	LinkedList 棋谱 = null;
	Thread 自动演示 = null;
	int index = -1;
	ChessBoard board = null;
	JTextArea text;
	JTextField 时间间隔 = null;
	int time = 1000;
	String 演示过程 = "";
	JSplitPane splitH = null, splitV = null;

	public Demon(ChessBoard board) {
		this.board = board;
		replay = new JButton("重新演示");
		next = new JButton("下一步");
		auto = new JButton("自动演示");
		stop = new JButton("暂停演示");
		自动演示 = new Thread(this);
		replay.addActionListener(this);
		next.addActionListener(this);
		auto.addActionListener(this);
		stop.addActionListener(this);
		text = new JTextArea();
		时间间隔 = new JTextField("1");
		setLayout(new BorderLayout());
		JScrollPane pane = new JScrollPane(text);
		JPanel p = new JPanel(new GridLayout(3, 2));
		p.add(next);
		p.add(replay);
		p.add(auto);
		p.add(stop);
		p.add(new JLabel("时间间隔(秒)", SwingConstants.CENTER));
		p.add(时间间隔);
		splitV = new JSplitPane(JSplitPane.VERTICAL_SPLIT, pane, p);
		splitH = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, board, splitV);
		splitV.setDividerSize(5);
		splitV.setDividerLocation(400);
		splitH.setDividerSize(5);
		splitH.setDividerLocation(460);
		add(splitH, BorderLayout.CENTER);
		validate();
	}

	public void set棋谱(LinkedList 棋谱) {
		this.棋谱 = 棋谱;
	}

	public char numberToLetter(int n) {
		char c = '\0';
		switch (n) {
		case 1:
			c = 'A';
			break;
		case 2:
			c = 'B';
			break;
		case 3:
			c = 'C';
			break;
		case 4:
			c = 'D';
			break;
		case 5:
			c = 'E';
			break;
		case 6:
			c = 'F';
			break;
		case 7:
			c = 'G';
			break;
		case 8:
			c = 'H';
			break;
		case 9:
			c = 'I';
			break;
		case 10:
			c = 'J';
			break;
		}
		return c;
	}

	public void actionPerformed(ActionEvent e) {
		if (e.getSource() == next) {
			index++;
			if (index < 棋谱.size()) {
				演示一步(index);
			} else {
				演示结束("棋谱演示完毕");
			}
		}
		if (e.getSource() == replay) {
			board = new ChessBoard(45, 45, 9, 10);
			splitH.remove(board);
			splitH.setDividerSize(5);
			splitH.setDividerLocation(460);
			splitH.setLeftComponent(board);
			splitH.validate();
			index = -1;
			text.setText(null);
		}
		if (e.getSource() == auto) {
			next.setEnabled(false);
			replay.setEnabled(false);
			try {
				time = 1000 * Integer.parseInt(时间间隔.getText().trim());
			} catch (NumberFormatException ee) {
				time = 1000;
			}

			if (!(自动演示.isAlive())) {
				自动演示 = new Thread(this);
				board = new ChessBoard(45, 45, 9, 10);
				splitH.remove(board);
				splitH.setDividerSize(5);
				splitH.setDividerLocation(460);
				splitH.setLeftComponent(board);
				splitH.validate();
				text.setText(null);
				自动演示.start();
			}

		}
		if (e.getSource() == stop) {
			if (e.getActionCommand().equals("暂停演示")) {
				演示过程 = "暂停演示";
				stop.setText("继续演示");
				stop.repaint();
			}
			if (e.getActionCommand().equals("继续演示")) {
				演示过程 = "继续演示";
				自动演示.interrupt();
				stop.setText("暂停演示");
				stop.repaint();
			}
		}
	}

	public synchronized void run() {
		for (index = 0; index < 棋谱.size(); index++) {
			try {
				Thread.sleep(time);
			} catch (InterruptedException e) {
			}
			while (演示过程.equals("暂停演示")) {
				try {
					wait();
				} catch (InterruptedException e) {
					notifyAll();
				}
			}
			演示一步(index);
		}
		if (index >= 棋谱.size()) {
			演示结束("棋谱演示完毕");
			next.setEnabled(true);
			replay.setEnabled(true);
		}
	}

	public void 演示一步(int index) {
		MoveStep step = (MoveStep) 棋谱.get(index);
		Point pStart = step.pStart;
		Point pEnd = step.pEnd;
		int startI = pStart.x;
		int startJ = pStart.y;
		int endI = pEnd.x;
		int endJ = pEnd.y;
		ChessPiece piece = (board.point)[startI][startJ].getPiece();
		if ((board.point)[endI][endJ].isPiece() == true) {
			ChessPiece pieceRemoved = (board.point)[endI][endJ].getPiece();
			(board.point)[endI][endJ].reMovePiece(pieceRemoved, board);
			board.repaint();
			(board.point)[endI][endJ].setPiece(piece, board);
			(board.point)[startI][startJ].set有棋子(false);
			board.repaint();
		} else {
			(board.point)[endI][endJ].setPiece(piece, board);
			(board.point)[startI][startJ].set有棋子(false);

		}
		String 棋子类别 = piece.棋子类别();
		String name = piece.getName();
		String m = "#" + 棋子类别 + name + ": " + startI + numberToLetter(startJ)
				+ " 到 " + endI + numberToLetter(endJ);
		text.append(m);
		if (piece.棋子类别().equals(board.黑方颜色))
			text.append("\n");
	}

	public void 演示结束(String message) {
		splitH.remove(board);
		splitH.setDividerSize(5);
		splitH.setDividerLocation(460);
		JLabel label = new JLabel(message);
		label.setFont(new Font("隶书", Font.BOLD, 40));
		label.setForeground(Color.blue);
		label.setHorizontalAlignment(SwingConstants.CENTER);
		splitH.setLeftComponent(label);
		splitH.validate();
	}
}


四、总结与要求

1.理解8个文件,没有太复杂的代码。

2.理解鼠标的MouseListener,MouseMotionListener两个接口的区别,五子棋的实现不需要MouseMotionListener。

3.使用LinkedList记录棋谱的方法。



posted @ 2012-11-20 22:52  涛涌四海  阅读(373)  评论(0编辑  收藏  举报