java课程设计---中国象棋对弈系统

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

java课程设计---中国象棋对弈系统
⽬录
摘要 (1)
关键字 (1)
正⽂ (2)
1、程序设计说明 (2)
1.1 程序的设计及实现 (2)
1.1.1搜索引擎的实现(engine包) (2)
1.1.2信息传输机制(message包) (3)
1.1.3棋⼦(pieces包) (3)
1.2 主控模块(main包) (3)
2、运⾏结果 (5)
3、设计体会 (6)
附件 (7)
程序代码 (7)
参考⽂献资料 (41)
1
中国象棋对弈系统
Java语⾔程序设计实验报告
实验项⽬名称:中国象棋对弈系统
作者姓名与单位:李⾮计算机101
摘要:
本⽂主要是运⽤java实现具有⼀定功能的中国象棋对弈系统软件,主要功能如下:
a、象棋对弈:红⽅先⾛,然后⿊⽅再⾛,红⿊交替,直到⼀⽅获胜。

b、新游戏:任何时候可以重新开始⼀盘新的对弈。

c、悔棋:当⾛错棋的时候可以悔棋。

d、信息提⽰:提⽰当前信息状态。

e、简单的帮助⽂档:象棋规则介绍、软件的简单介绍和编制说明
关键词:java、中国象棋对弈系统
2
正⽂:
⼀程序设计说明
1.1程序的设计及实现
2、message:⽹络对战过程中各种消息及其传递机制的类实现包。

3、main:主界⾯实现包。

4、pieces:棋⼦及其相关类实现包。

现就各个包中的要点给与说明。

1.1.1 搜索引擎的实现(engine包)
(1) BitBoard.java:位棋盘的实现,见2.4节。

(2) CCEvalue.java:评价函数知识类。

本程序使⽤开源软件“梦⼊神蛋”的快速评价函数。

该函数包含⼦⼒价值和棋⼦所在位置的奖励值。

⼦⼒价值分别是:帅-0, 仕-40, 象-40, 马-88, 车-200, 炮-96, 兵-9。

帅是⽆价的,⽤0表⽰。

以马为例,位置的奖励值如下:
0,-3,5,4,2,2,5,4,2,2,
-3,2,4,6,10,12,20,10,8,2,
2,4,6,10,13,11,12,11,15,2,
0,5,7,7,14,15,19,15,9,8,
2,-10,4,10,15,16,12,11,6,2,
0,5,7,7,14,15,19,15,9,8,
2,4,6,10,13,11,12,11,15,2,
-3,2,4,6,10,12,20,10,8,2,
0,-3,5,4,2,2,5,4,2,2
上⾯的每⾏代表棋盘的⼀条纵线。

其中,-10所在的位置是“窝⼼马”,所以要罚10分。

(3) ChessPosition.java:动态局⾯类
包含对局过程中的动态信息,主要实现的是2.4节的各类位棋盘和移⼦函数。

(4) MoveStruct.java:着法表⽰类。

(5) PreMove.java:伪合法着法⽣成模块,见4.1。

3
中国象棋对弈系统
(6) MoveSortStruct.java:合法着法的⽣成及其排序算法,见4.2。

(7) SearchMove.java:搜索算法,实现如下功能:
1)主置换表及开局库
2)Alpha-Beta搜索算法
3)针对吃⼦着法的静态搜索算法
4)适应性空着裁剪算法:见5.5.2,根据不同情况来调整R值的做法,称
为“适应性空着裁剪”(Adaptive Null-Move Pruning),它⾸先由Ernst Heinz
发表在1999年的ICCA杂志上。

其内容可以概括为:
a. 深度⼩于或等于6时,⽤R = 2的空着裁剪进⾏搜索
否则⽤R = 2。

5)带时间控制的迭代加深搜索算法:每次加深搜索都判断时间是否够⽤。

6)“将军”扩展(加深)搜索算法:当搜索到⼰⽅被“将”时,增加搜
索的深度。

7)主要变例搜索算法
1.1.2 信息传输机制(message包)
在对弈过程中(主要是⽹络对弈)需要在对弈双⽅之间传输各类信息,抽象为各类消息。

如时间规则的协定、各⽅的⾛⼦信息等。

每⽅都有消息接收、消息处理和消息发送程序(OuterMsgReceiver、
LocalMsgReceiver,QzMessageHandler,MessageSender)。

⼰⽅的MessageSender与对⽅的OuterMsgReceiver通过接⼝SrConnection连接。

所有接收的消息放⼊消息队列QzMsgQueue中,等待消息处理进程QzMessageHandler来处理。

所有的消息都封装在QzMessage类对象中,消息的类型通过消息的Header类型(以静态常量存放在MsgHeader类中)来区分。

1.1.3 棋⼦(pieces包)
Qizi.java包含棋⼦的信息,如棋⼦的(在棋盘上的)位置、图⽚、名称、类型、状态等。

PiecesFactory.java以“⼯⼚”模式提供根据棋⼦类型或其他信息⽣成相关Qizi对象的⽅法。

1.2主控模块(main包)
实现了程序界⾯与消息传递、搜索引擎的集成。

(1) NewBoard.java:棋盘坐标系统及其界⾯的实现。

4
(2) CChessApp.java:主界⾯类,以内部类实现了QzMessageHandler接⼝、计时规则TimeRule接⼝以及事件的处理程序,根据需要⽣成其他的并发线程如消息接收、处理和发送,机器思考(启动搜索引擎),计时显⽰等。

(3) SetRuleDialog.java:设置规则的对话框。

(4) SetSysInfoDialog.java:设置系统的⼀些属性如对战模式、连接端⼝等。

(5) Translation.java:提供了⼀系列实⽤⽅法主要有:
1)FEN串与局⾯ChessPosition对象之间的转换
2)不同着法表⽰(见第⼀章)之间的转换。

如“炮⼆平五”与“Ch2-e2”
及“62.5或C2.5“(C和6代表炮)这⼏种表⽰法之间的转换
3)棋谱⽂件的读⼊和存储。

4)开局库的⽣成:将近年实战的棋谱⽂件(可能有⼏种格式)整理⽣成
开局库。

5
中国象棋对弈系统
⼆、运⾏结果:
6
三、设计体会:
本次课程设计主要是运⽤本学期所学到的Java基础知识来设计⼀个符合要求的中国象棋对弈系统,这期间我遇到了很多的困难,发现了很多的问题,正是在解决问题的期间我才慢慢地熟悉了Java的基础知识,才慢慢学会了如何去按照给定的要求设计出合适的java系统。

通过本次课程设计,我明⽩了⼀个道理:⽆论做什么事情,都必需养成严谨,认真,善思的⼯作作风遇到问题最好的办法就是请教别⼈,因为每个⼈掌握的情况都不⼀样,⼀个⼈不可能做到处处都懂,必须发挥群众的⼒量,复杂的事情才能够简单化。

这⼀点我深有体会,在很多时候,我遇到的困难或许别⼈之前就遇到过,向他们请教远⽐⾃⼰在那边摸索来得简单,来得快。

7
中国象棋对弈系统
附件
程序代码:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.util.*;
import java.io.*;
public static void main(String args[]){
new ChessMainFrame("中国象棋:观棋不语真君⼦,棋死⽆悔⼤丈夫");
}
}
class ChessMainFrame extends JFrame implements ActionListener,MouseListener,Runnable{ //玩家
JLabel play[] = new JLabel[32];
//棋盘
JLabel image;
//窗格
Container con;
//⼯具栏
JToolBar jmain;
//重新开始
JButton anew;
//悔棋
JButton repent;
//退出
JButton exit;
//当前信息
JLabel text;
//保存当前操作
Vector Var;
//规则类对象(使于调⽤⽅法)
ChessRule rule;
/**
** 单击棋⼦
** chessManClick = true 闪烁棋⼦并给线程响应
** chessManClick = false 吃棋⼦停⽌闪烁并给线程响应
*/
boolean chessManClick;
8
/**
** 控制玩家⾛棋
** chessPlayClick=2 红棋⾛棋默认红棋
** chessPlayClick=3 双⽅都不能⾛棋
*/
int chessPlayClick=2;
//控制棋⼦闪烁的线程
Thread tmain;
//把第⼀次的单击棋⼦给线程响应
static int Man,i;
ChessMainFrame(){
new ChessMainFrame("中国象棋");
}
/**
** 构造函数
** 初始化图形⽤户界⾯
*/
ChessMainFrame(String Title){
//获⾏客格引⽤
con = this.getContentPane();
con.setLayout(null);
//实例化规则类
rule = new ChessRule();
Var = new Vector();
//创建⼯具栏
jmain = new JToolBar();
text = new JLabel("欢迎使⽤象棋对弈系统");
//当⿏标放上显⽰信息
text.setToolTipText("信息提⽰");
anew = new JButton(" 新游戏");
anew.setToolTipText("重新开始新的⼀局");
exit = new JButton(" 退出");
exit.setToolTipText("退出象棋程序程序"); repent = new JButton(" 悔棋");
repent.setToolTipText("返回到上次⾛棋的位置"); //把组件添加到⼯具栏
jmain.add(anew);
jmain.add(repent);
jmain.add(exit);
jmain.add(text);
jmain.setBounds(0,0,558,30);
con.add(jmain);
9
中国象棋对弈系统
//添加棋⼦标签
drawChessMan();
//注册按扭监听
anew.addActionListener(this);
repent.addActionListener(this);
exit.addActionListener(this);
//注册棋⼦移动监听
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);
//注册窗体关闭监听
this.addWindowListener(
new WindowAdapter() {
public void windowClosing(WindowEvent we){
System.exit(0);
}
}
);
//窗体居中
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); Dimension frameSize = this.getSize();
frameSize.height = screenSize.height;
}
if (frameSize.width > screenSize.width){
frameSize.width = screenSize.width;
}
this.setLocation((screenSize.width - frameSize.width) / 2 - 280 ,(screenSize.height - frameSize.height ) / 2 - 350); //设置
this.setIconImage(new ImageIcon("image\\红将.GIF").getImage());
this.setResizable(false);
this.setTitle(Title);
this.setSize(558,670);
this.show();
}
/**
** 添加棋⼦⽅法
*/
10
public void drawChessMan(){
//流程控制
int i,k;
//图标
Icon in;
//⿊⾊棋⼦
//车
in = new ImageIcon("image\\⿊车.GIF");
for (i=0,k=24;i<2;i++,k+=456){
play[i] = new JLabel(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 JLabel(in);
play[i].setName("马1");
}
//相
in = new ImageIcon("image\\⿊象.GIF"); for (i=8,k=138;i<10;i++,k+=228){
play[i] = new JLabel(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 JLabel(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 JLabel(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){
11
中国象棋对弈系统
play[i] = new JLabel(in);
play[i].setBounds(k,170,55,55);
play[i].setName("炮1" + i);
}
//将
in = new ImageIcon("image\\⿊将.GIF");
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 JLabel(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 JLabel(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 JLabel(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 JLabel(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].setBounds(k,398,55,55);
play[i].setName("卒2" + i);
12
}
//炮
in = new ImageIcon("image\\红炮.GIF"); for (i=28,k=81;i<30;i++,k+=342){
play[i] = new JLabel(in);
play[i].setBounds(k,455,55,55);
play[i].setName("炮2" + i);
}
//帅
in = new ImageIcon("image\\红将.GIF"); play[31] = new JLabel(in);
play[31].setBounds(252,569,55,55); play[31].setName("帅2");
}
/**
** 线程⽅法控制棋⼦闪烁
*/
public void run(){
while (true){
//单击棋⼦第⼀下开始闪烁
if (chessManClick){
play[Man].setVisible(false);
//时间控制
try{
tmain.sleep(200);
}
catch(Exception e){
}
play[Man].setVisible(true);
}
//闪烁当前提⽰信息以免⽤户看不见else {text.setVisible(false);//时间控制
try{tmain.sleep(250);
}
catch(Exception e){
}
text.setVisible(true);
}
try{tmain.sleep(350);
}
catch (Exception e){
13
中国象棋对弈系统
}
}
}
/**
** 单击棋⼦⽅法*/
public void mouseClicked(MouseEvent me){
System.out.println("Mouse");//当前坐标
int Ex=0,Ey=0; //启动线程
if (tmain == null){
tmain = new Thread(this);
tmain.start();
} //单击棋盘(移动棋⼦)
if (me.getSource().equals(image)){//该红棋⾛棋的时候
if (chessPlayClick == 2 && play[Man].getName().charAt(1) == '2'){ Ex = play[Man].getX(); Ey = play[Man].getY();//移动卒、兵
if (Man > 15 && Man < 26){
rule.armsRule(Man,play[Man],me);
} //移动炮
else if (Man > 25 && Man < 30){
rule.cannonRule(play[Man],play,me);
}//移动车
else if (Man >=0 && Man < 4){
rule.cannonRule(play[Man],play,me);
}//移动马
else if (Man > 3 && Man < 8){
rule.horseRule(play[Man],play,me);
}//移动相、象
else if (Man > 7 && Man < 12){
rule.elephantRule(Man,play[Man],play,me);
}//移动仕、⼠
else if (Man > 11 && Man < 16){
rule.chapRule(Man,play[Man],play,me);
}//移动将、帅
else if (Man == 30 || Man == 31){
rule.willRule(Man,play[Man],play,me);
}//是否⾛棋错误(是否在原地没有动)
if (Ex == play[Man].getX() && Ey == play[Man].getY()){
text.setText(" 红棋⾛棋");
chessPlayClick=2;
}
else {text.setText(" ⿊棋⾛棋");
chessPlayClick=1;
}
14
}//if//该⿊棋⾛棋的时候
else if (chessPlayClick == 1 && play[Man].getName().charAt(1) == '1'){ Ex = play[Man].getX();
Ey = play[Man].getY();//移动卒、兵
if (Man > 15 && Man < 26){
rule.armsRule(Man,play[Man],me);
}//移动炮
else if (Man > 25 && Man < 30){
rule.cannonRule(play[Man],play,me);
}//移动车
else if (Man >=0 && Man < 4){
rule.cannonRule(play[Man],play,me);
}//移动马
else if (Man > 3 && Man < 8){
rule.horseRule(play[Man],play,me);
}//移动相、象
else if (Man > 7 && Man < 12){
rule.elephantRule(Man,play[Man],play,me);
}//移动仕、⼠
else if (Man > 11 && Man < 16){
rule.chapRule(Man,play[Man],play,me);
}//移动将、帅
else if (Man == 30 || Man == 31){
rule.willRule(Man,play[Man],play,me);
}//是否⾛棋错误(是否在原地没有动)
if (Ex == play[Man].getX() && Ey == play[Man].getY()){ text.setText(" ⿊棋⾛棋");
chessPlayClick=1;
}
else {text.setText(" 红棋⾛棋");
chessPlayClick=2;
}}//else if //当前没有操作(停⽌闪烁) chessManClick=false;
}//if//单击棋⼦
else{//第⼀次单击棋⼦(闪烁棋⼦)
if (!chessManClick){
for (int i=0;i<32;i++){
//被单击的棋⼦
if (me.getSource().equals(play[i])){
//告诉线程让该棋⼦闪烁
Man=i;
//开始闪烁
chessManClick=true;
15
中国象棋对弈系统
break;
}
}//for
}//if
//第⼆次单击棋⼦(吃棋⼦)
else if (chessManClick){//当前没有操作(停⽌闪烁) chessManClick=false;
for (i=0;i<32;i++){
//找到被吃的棋⼦
if (me.getSource().equals(play[i])){
//该红棋吃棋的时候
if (chessPlayClick == 2 && play[Man].getName().charAt(1) == '2'){ Ex = play[Man].getX();
Ey = play[Man].getY();
//卒、兵吃规则
if (Man > 15 && Man < 26){
rule.armsRule(play[Man],play[i]);
}
//炮吃规则
else if (Man > 25 && Man < 30){
rule.cannonRule(0,play[Man],play[i],play,me);
}
//车吃规则
else if (Man >=0 && Man < 4){
rule.cannonRule(1,play[Man],play[i],play,me);
}
//马吃规则
else if (Man > 3 && Man < 8){
rule.horseRule(play[Man],play[i],play,me);
}
//相、象吃规则
else if (Man > 7 && Man < 12){
rule.elephantRule(play[Man],play[i],play);
}
//⼠、仕吃棋规则
else if (Man > 11 && Man < 16){
rule.chapRule(Man,play[Man],play[i],play);
}
//将、帅吃棋规则
else if (Man == 30 || Man == 31){
rule.willRule(Man,play[Man],play[i],play);
play[Man].setVisible(true);
}
16
//是否⾛棋错误(是否在原地没有动)
if (Ex == play[Man].getX() && Ey == play[Man].getY()){
text.setText(" 红棋⾛棋");
chessPlayClick=2;
break;
}
else{text.setText(" ⿊棋⾛棋");
chessPlayClick=1;break;
}
}//if
//该⿊棋吃棋的时候
else if (chessPlayClick == 1 && play[Man].getName().charAt(1) == '1'){ Ex = play[Man].getX();
Ey = play[Man].getY();
//卒吃规则
if (Man > 15 && Man < 26){
rule.armsRule(play[Man],play[i]);
}
//炮吃规则
else if (Man > 25 && Man < 30){
rule.cannonRule(0,play[Man],play[i],play,me);
}//车吃规则
else if (Man >=0 && Man < 4){
rule.cannonRule(1,play[Man],play[i],play,me);
}//马吃规则
else if (Man > 3 && Man < 8){
rule.horseRule(play[Man],play[i],play,me);
}
//相、象吃规则
else if (Man > 7 && Man < 12){
rule.elephantRule(play[Man],play[i],play);
}
//⼠、仕吃棋规则
else if (Man > 11 && Man < 16){
rule.chapRule(Man,play[Man],play[i],play);
}
//将、帅吃棋规则
else if (Man == 30 || Man == 31){
rule.willRule(Man,play[Man],play[i],play);
play[Man].setVisible(true);
}
//是否⾛棋错误(是否在原地没有动)
17
中国象棋对弈系统
if (Ex == play[Man].getX() && Ey == play[Man].getY()){text.setText(" ⿊棋⾛棋"); chessPlayClick=1;break;
}
else {
text.setText(" 红棋⾛棋");
chessPlayClick=2;
break;
}
}//else if
}//if
}//for
//是否胜利
if (!play[31].isVisible()){
JOptionPane.showConfirmDialog(
this,"⿊棋胜利","玩家⼀胜利",
JOptionPane.DEFAULT_OPTION,JOptionPane.WARNING_MESSAGE);
//双⽅都不可以在⾛棋了
chessPlayClick=3;
text.setText(" ⿊棋胜利");
}//if else if (!play[30].isVisible()){
JOptionPane.showConfirmDialog(
this,"红棋胜利","玩家⼆胜利",
JOptionPane.DEFAULT_OPTION,JOptionPane.WARNING_MESSAGE); chessPlayClick=3;
text.setText(" 红棋胜利");
}//else if
}//else
}//else
}
public void mousePressed(MouseEvent me){}
public void mouseReleased(MouseEvent me){}
public void mouseEntered(MouseEvent me){}
public void mouseExited(MouseEvent me){}
/**
** 定义按钮的事件响应
*/
public void actionPerformed(ActionEvent ae) {//重新开始按钮
if (ae.getSource().equals(anew)){int i,k;
//重新排列每个棋⼦的位置
//⿊⾊棋⼦
//车
for (i=0,k=24;i<2;i++,k+=456){play[i].setBounds(k,56,55,55); }
//马
18
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){ p lay[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);
chessPlayClick = 2;
text.setText(" 红棋⾛棋");
for (i=0;i<32;i++){
play[i].setVisible(true);}//清除Vector中的内容
Var.clear();}//悔棋按钮
else if (ae.getSource().equals(repent)){
try{//获得setVisible属性值
String S = (String)Var.get(Var.size()-4);//获得X坐标
int x = Integer.parseInt((String)Var.get(Var.size()-3));//获得Y坐标int y = Integer.parseInt((String)Var.get(Var.size()-2));//获得索引int M = Integer.parseInt((String)Var.get(Var.size()-1)); //赋给棋⼦play[M].setVisible(true);
play[M].setBounds(x,y,55,55);
if (play[M].getName().charAt(1) == '1'){
text.setText(" ⿊棋⾛棋");
19。

相关文档
最新文档