基于Java的中国象棋对弈系统

请自行按此找一些棋子的图片,main是棋盘

课程设计基本功能描述

实现一个中国象棋对弈的软件,实现中国象棋的规则:棋子共有三十二个,分为红、黑两组,每组十六个,各分七种,其名称和数目如下所述。

红棋子:帅一人,车、马、炮、相、士各两个,兵五个。

黑棋子:将一个,车、马、炮、象、士各两个,卒五个。

在对局时,由执红棋的一方先走,双方轮流各走一着,直至分出胜负为止。轮到走棋的一方,将某个棋子从一个交叉点到另一个空着的交叉点,或者吃掉对方的棋子而占领叉点,都算走了一着。双方各走了一着,称为一个回合。以“将死”或“困毙”对方将(帅)为胜。

  1. 实现棋子的移动:玩家根据象棋规则,进行棋子的移动;

帅(将)

红方为“帅”,黑方为“将”。

帅和将是棋中的首脑,是双方竭力争夺的目标。它只能在"九宫"之内活动,可上可下,可左可右,每次走动只能按竖线或横线走动一格。帅与将不能在同一直线上直接对面,否则走方判负。

仕(士)

仕(士)是将(帅)的贴身保镖,它也只能在九宫内走动。它的行棋路径只能是九宫内的斜线。

象(相)

红方为,黑方为

相(象)的主要作用是防守,保护自己的帅(将)。它的走法是每次循对角线走两格,俗称象飞田。相(象)的活动范围限于"河界"以内的本方阵地,不能过河,且如果它走的""字中央有一个棋子,就不能走,俗称塞象眼

车(jū)

车在象棋中威力最大,无论横线、竖线均可行走,只要无子阻拦,步数不受限制。因此,一车可以控制十七个点,故有一车十子寒之称。

炮在不吃子的时候,走动与车完全相同,但炮在吃子时,必须跳过一个棋子,我方的和敌方的都可以,俗称炮打隔子

马走日与蹩马腿

马走动的方法是一直一斜,即先横着或直着走一格,然后再斜着走一个对角线,俗称马走日。马一次可走的选择点可以达到四周的八个点,故有"八面威风"之说。如果在要去的方向有别的棋子挡住,马就无法走过去,俗称蹩马腿

兵(卒)

红方为,黑方为

兵(卒)在未过河前,只能向前一步步走,过河以后,除不能后退外,允许左右移动,但也只能一次一步,即使这样,兵(卒)的威力也大大增强,故有过河的卒子顶半个车之说。

A.移动棋子需要考虑的共同问题:

起点和终点的位置的坐标是否越界;

起点和终点位置的棋子,是否是同一方的;

棋子移动后,将帅是否会对脸。

B.移动棋子需要考虑的特殊问题:

將(帥)、仕(士)是否走出九宫;

象是否过河,象眼是否被堵;

馬是否别腿;

兵过河前只能前进,过河后可以前进或左右移动;

  1. 棋盘

棋子活动的场所,叫作棋盘。在长方形的平面上,绘有九条平行的竖线和十条平行的横线相交组成,共有九十个交叉

点,棋子就摆在交叉点上。中间部分,也就是棋盘的第五,第六两横线之间末画竖线的空白地带称为河界。两端的中间,也就是两端第四条到第六条竖线之间的正方形部位,以斜交叉线构成字方格的地方,叫作九宫(它恰好有九个交叉点)。

整个棋盘以河界分为相等的两部分。为了比赛记录和学习棋谱方便起见,现行规则规定:按九条竖线从右至左用中文数字一-九来表示红方的每条竖线,用阿拉伯数字‘1’‘9’来表示黑方的每条竖线。对弈开始之前,红黑双方应该把棋子摆放在规定的位置。任何棋子每走一步,进就写,退就写退,如果像车一样横着走,就写

  1. 实现棋子的吃子判断:玩家根据象棋规则,进行吃子;
  1. 吃子需要考虑的问题:

炮需要翻山吃子

  1. 实现悔棋功能:

玩家在游戏中需要悔棋,按下悔棋按钮,退回一步,这里可以退任意步数,也可以一直回退,直至退回游戏开始状态;

  1. 实现重置功能

玩家在游戏进行中或游戏结束,按新游戏按钮,开始新的一局游戏。

程序类图

package com.leox;
public class Chess {

    public static void main(String[] args) {
	// write your code here
        ChessMainFrame chessMainframe = new ChessMainFrame("象棋对弈系统");

    }
}
package com.leox;

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.ArrayList;
import java.util.List;
//ActionListener用于接收操作事件的侦听器接口, 器MouseListener鼠标监听接口 ,Runnable线程启动接口
public class ChessMainFrame extends JFrame implements ActionListener, MouseListener, Runnable {
    ChessManBehavior play[] = new ChessManBehavior[32];
    JLabel image;
    Container con;
    JToolBar jmain;
    JButton anew, repent, exit;
    JLabel text;
    //chessplayClick判断先手 1黑2红
    int chessplayClick = 2;
    //判断有没有点击棋子
    boolean chessManClick;
    //线程变量,棋子的闪烁
    Thread tmain;
    //判断点击的是哪一个棋子
    static int Man;
    //游戏结束
    boolean gameIsOver;
    //判断吃子和走棋
    ChessRule chessRule;
    List<ChessRegret> regretList;

    public ChessMainFrame(String title) {
        //获得窗口内容面板
        con = this.getContentPane();
        //绝对布局
        con.setLayout(null);
        this.setTitle(title);
        jmain = new JToolBar();
        text = new JLabel("欢迎使用象棋对弈系统");
        text.setToolTipText("信息提示");
        anew = new JButton("新游戏");
        anew.setToolTipText("重新开始一局游戏");
        exit = new JButton("退出");
        exit.setToolTipText("退出象棋对弈系统");
        repent = new JButton("悔棋");
        repent.setToolTipText("返回上次走棋的位置");
        //栅格布局,4列
        jmain.setLayout(new GridLayout(0, 4));
        jmain.add(anew);
        jmain.add(repent);
        jmain.add(exit);
        jmain.add(text);
        jmain.setBounds(0, 0, 588, 30);
        con.add(jmain);
        //需要先画棋子,先放的Jlable永远在最前
        drawChessMain();
        for (int i = 0; i < 32; i++) {
            con.add(play[i]);
            play[i].addMouseListener(this);

        }
        con.add(image = new JLabel(new ImageIcon("image/main.gif")));
        image.setBounds(0, 30, 558, 620);
        image.addMouseListener(this);

        //居中
        Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
        this.setLocation(screenSize.width / 2 - 288, screenSize.height / 2 - 350);
        //添加图标
        this.setIconImage(new ImageIcon("image/红将.gif").getImage());
        //窗体大小
        this.setResizable(false);
        //标题栏默认高度26px
        this.setSize(558, 676);
        this.setVisible(true);
        gameIsOver = false;
        regretList = new ArrayList<ChessRegret>();
        chessRule = new ChessRule();
        this.addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent e) {
                super.windowClosing(e);
                System.exit(0);
            }
        });
        anew.addActionListener(this);
        repent.addActionListener(this);
        exit.addActionListener(this);

    }

    //棋盘重置
    public void chessReset() {
        int i, k;
        for (i = 0, k = 24; i < 2; i++, k += 456) {
            play[i].setBounds(k, 56, 55, 55);
        }
        for (i = 4, k = 81; i < 6; i++, k += 342) {
            play[i].setBounds(k, 56, 55, 55);
        }
        for (i = 8, k = 138; i < 10; i++, k += 228) {
            play[i].setBounds(k, 56, 55, 55);
        }
        for (i = 12, k = 195; i < 14; i++, k += 114) {
            play[i].setBounds(k, 56, 55, 55);
        }
        for (i = 16, k = 24; i < 21; i++, k += 114) {
            play[i].setBounds(k, 227, 55, 55);
        }
        for (i = 26, k = 81; i < 28; i++, k += 342) {
            play[i].setBounds(k, 170, 55, 55);
        }
        play[30].setBounds(252, 56, 55, 55);
        //红方
        for (i = 2, k = 24; i < 4; i++, k += 456) {
            play[i].setBounds(k, 569, 55, 55);
        }
        for (i = 6, k = 81; i < 8; i++, k += 342) {
            play[i].setBounds(k, 569, 55, 55);
        }
        for (i = 10, k = 138; i < 12; i++, k += 228) {
            play[i].setBounds(k, 569, 55, 55);
        }
        for (i = 14, k = 195; i < 16; i++, k += 114) {
            play[i].setBounds(k, 569, 55, 55);
        }
        for (i = 21, k = 24; i < 26; i++, k += 114) {
            play[i].setBounds(k, 398, 55, 55);
        }
        for (i = 28, k = 81; i < 30; i++, k += 342) {
            play[i].setBounds(k, 455, 55, 55);
        }
        play[31].setBounds(252, 569, 55, 55);
        for (i = 0; i < 32; i++) {
            System.out.println(i + " " + play[i].getName());
        }
        gameIsOver = false;
        for (i = 0; i < 32; i++) {
            play[i].setVisible(true);
            play[i].died = false;
        }
        text.setText("     红棋走棋");
        chessplayClick=2;
        Man = -1;
        //清空悔棋的list
        regretList.clear();
    }

    //创建棋盘
    public void drawChessMain() {
        int i, k;
        Icon in = null;
        in = new ImageIcon("image/黑车.gif");
        for (i = 0, k = 24; i < 2; i++, k += 456) {
            play[i] = new ChessManBehavior(in);
            play[i].setBounds(k, 56, 55, 55);
            play[i].setName("车1");
        }
        in = new ImageIcon("image/黑马.gif");
        for (i = 4, k = 81; i < 6; i++, k += 342) {
            play[i] = new ChessManBehavior(in);
            play[i].setBounds(k, 56, 55, 55);
            play[i].setName("马1");
        }
        in = new ImageIcon("image/黑象.gif");
        for (i = 8, k = 138; i < 10; i++, k += 228) {
            play[i] = new ChessManBehavior(in);
            play[i].setBounds(k, 56, 55, 55);
            play[i].setName("象1");
        }
        in = new ImageIcon("image/黑士.gif");
        for (i = 12, k = 195; i < 14; i++, k += 114) {
            play[i] = new ChessManBehavior(in);
            play[i].setBounds(k, 56, 55, 55);
            play[i].setName("士1");
        }
        in = new ImageIcon("image/黑卒.gif");
        for (i = 16, k = 24; i < 21; i++, k += 114) {
            play[i] = new ChessManBehavior(in);
            play[i].setBounds(k, 227, 55, 55);
            play[i].setName("卒1" + i);
        }
        in = new ImageIcon("image/黑炮.gif");
        for (i = 26, k = 81; i < 28; i++, k += 342) {
            play[i] = new ChessManBehavior(in);
            play[i].setBounds(k, 170, 55, 55);
            play[i].setName("炮1" + i);
        }
        in = new ImageIcon("image/黑将.gif");
        play[30] = new ChessManBehavior(in);
        play[30].setBounds(252, 56, 55, 55);
        play[30].setName("将1");

        in = new ImageIcon("image/红车.gif");
        for (i = 2, k = 24; i < 4; i++, k += 456) {
            play[i] = new ChessManBehavior(in);
            play[i].setBounds(k, 569, 55, 55);
            play[i].setName("车2");
        }
        in = new ImageIcon("image/红马.gif");
        for (i = 6, k = 81; i < 8; i++, k += 342) {
            play[i] = new ChessManBehavior(in);
            play[i].setBounds(k, 569, 55, 55);
            play[i].setName("马2");
        }
        in = new ImageIcon("image/红象.gif");
        for (i = 10, k = 138; i < 12; i++, k += 228) {
            play[i] = new ChessManBehavior(in);
            play[i].setBounds(k, 569, 55, 55);//定位位置
            play[i].setName("象2");
        }
        in = new ImageIcon("image/红士.gif");
        for (i = 14, k = 195; i < 16; i++, k += 114) {
            play[i] = new ChessManBehavior(in);
            play[i].setBounds(k, 569, 55, 55);
            play[i].setName("士2");
        }
        in = new ImageIcon("image/红卒.gif");
        for (i = 21, k = 24; i < 26; i++, k += 114) {
            play[i] = new ChessManBehavior(in);
            play[i].setBounds(k, 398, 55, 55);
            play[i].setName("卒2" + i);
        }
        in = new ImageIcon("image/红炮.gif");
        for (i = 28, k = 81; i < 30; i++, k += 342) {
            play[i] = new ChessManBehavior(in);
            play[i].setBounds(k, 455, 55, 55);
            play[i].setName("炮2" + i);
        }
        in = new ImageIcon("image/红将.gif");
        play[31] = new ChessManBehavior(in);
        play[31].setBounds(252, 569, 55, 55);
        play[31].setName("将2");
    }

    @Override
    //点击判断函数
    public void actionPerformed(ActionEvent e) {
        if (e.getSource().equals(anew)) {
            System.out.println("click renew");
            chessReset();
        }
        if (e.getSource().equals(repent)) {
            System.out.println("regret");
            if (regretList.isEmpty() == false) {
                //得到栈顶元素
                ChessRegret chessRegret = regretList.get(regretList.size() - 1);
                Man = chessRegret.man;
                play[Man].setBounds(chessRegret.cx, chessRegret.cy, 55, 55);
                if (chessRegret.eatMan != -1) {
                    play[chessRegret.eatMan].setVisible(true);
                    //play[chessRegret.eatMan].died = false;
                }
                if (play[Man].getName().charAt(1) == '2') {
                    chessplayClick = 2;
                    text.setText("    红棋走棋");
                } else {
                    chessplayClick = 1;
                    text.setText("    黑棋走棋");
                }
                //删除栈顶元素
                regretList.remove(regretList.size() - 1);
            }
        }
        if (e.getSource().equals(exit)) {
            int j = JOptionPane.showConfirmDialog(this, "真的要退出吗?", "退出", JOptionPane.YES_OPTION, JOptionPane.QUESTION_MESSAGE);
            if (j == JOptionPane.YES_OPTION) {
                System.exit(0);
            }
        }
    }

    @Override
    //鼠标点击判断
    public void mouseClicked(MouseEvent e) {
        int ex = 0;
        int ey = 0;


        if (tmain == null) {
            tmain = new Thread(this);
            tmain.start();
        }
        if (gameIsOver)
            return;
        if (e.getSource().equals(image)) {
            if (chessplayClick == 2 && play[Man].getName().charAt(1) == '2') {
                ex = play[Man].getX();
                ey = play[Man].getY();
                if (Man >= 0 && Man < 4) {
                    System.out.println("移动红车");
                    chessRule.carRule(play[Man]
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值