中国象棋CS版.docx
《中国象棋CS版.docx》由会员分享,可在线阅读,更多相关《中国象棋CS版.docx(47页珍藏版)》请在冰豆网上搜索。
中国象棋CS版
中国象棋(C/S版)
1.设计内容及要求
1.1中国象棋的基本要求
设计C/S网络版中国象棋,也就是客户端与服务器端都是java应用程序。
具体要求如下:
(1)中国象棋是双方在有着9调竖线和10条横线的棋盘上对弈,竖线和横线的交叉称为棋点或对弈点,每个棋子都是在棋点上行走,而不是在方格中行走。
(2)河界将棋盘分成两等份,每一边都有一块有9个点组成的九宫,棋子“将”,“帅”和“士”只能在九宫内移动,并且“将”和“帅”每一步只可以水平或垂直移动一个棋点;“士”只能在九宫内移动,并且它每一步只可以沿着对角线移动一个棋点;“象”必须一次沿着对角线方向走两个棋点,但它不能过河也不能跳过或穿越障碍,即“象”不能别眼,“马”没一步只可以水平或垂直移动两个棋点,但必须按对角线向左或向右移动。
中国象棋的“马”不能跳过障碍,即马不能别腿。
“车”可以水平或垂直方向移动人一个无障碍的点。
“炮”移动起来和车类似,但它必须跳过一个棋子来吃掉对方的一个棋子,被跳过的那个棋子称为桥或者屏风。
“兵”每步只能向前移动一个棋子过河以后,它便增加了向左右移动的能力,并不允许向后移动。
(3)用户开始运行程序后,进入用户登录界面,用户输入正确的用户名和密码才可以进入中国象棋主界面。
(4)用户进入主界面后,单击“建立主机”按钮,就把该计算机作为主机,等待其他用户登录到这台主机后,才可以进行对弈。
(5)当有用户登录到这台主机上士,用户单击“开始”按钮就可以开始想起对弈了,在对弈过程中,用户可以单击“悔棋”按钮,就可以实现悔棋,用户还可以单击“认输”按钮,向对方认输。
(6)如果用户赢了,用户的积分就会增加。
(7)用户在对弈过程中可以聊天。
1.2需实现的主要功能
(1)用户登录验证功能。
(2)每一个用户可以把自己的计算机做为主机。
(3)每一个用户可以寻找主机,并且与主机建立连接。
(4)用户在对弈过程中,可以悔棋,而且可以认输。
(5)没一个用户都用积分,当赢了比赛后,用户的积分就会增加。
(6)有聊天室功能,即用户在对弈过程中可以与对方聊天。
(7)在线用户显示功能。
2.需求分析
2.1数据库设计
2.1.1数据库及表结构的建立
中国象棋系统共创建了一个dengluzhuce数据库,在该数据库中创建了一个login表。
数据库是用Access创建的,创建方法是:
新建—>空数据库。
login表是用来存储用户信息的,login数据表的创建如下表所示:
字段名称
数据类型
说明
用户名
文本
密码
文本
积分
文本
是否在线
数字
表2-1login数据表
2.1.2JDBC-ODBC的建立
为了同dengluzhuce数据库建立连接,首先要创建一个ODBC数据源,打开Windows中的控制面板,对于WindowsXP选择“性能和维护”—>“管理工具”—>“数据源(ODBC)”;创建好user数据源。
现在有了数据源,这个数据源就是一个数据库。
为了要连接到这个数据库,首先要建立一个JDBC-ODBC桥接器;Class.forName(“sun.jdbc.odbc.JdbcOdbcDriver”);这里,Class是包java.lang中的一个类,该类通过调用静态方法forName加载sun.jdbc.odbc包中的JdbcOdbcDriver来建立桥接器。
2.1.3JAVA数据库的连接
首先使用java.sql包中的Connection类声明一个对象,然后在使用DriverManager调用它的静态方法getConnection创建这个连接对象,建立连接时应捕捉SQLException异常:
Try{
Connectioncon=DriverManager.getConnection(“jdbc:
odbc:
user”,””,””)
}
Catch(SQLException){}
这样就建立到数据库dengluzhuce的连接。
2.2服务器端和客户端的数据传输方式
服务器端和客户端的数据时用套接字来传输的。
IP地址表示Internet上的计算机,端口号标识正在计算机运行的进程。
端口号与IP地址的组合得出一个网络套接字。
客户端使用Socket类建立到服务器的套接字连接,具体实现:
try{
Socketsock=newSocket(Stringhost,intport);
}catch(IOExceptione){}
当套接字连接sock建立后,sock使用getInputStream()方法获得一个输入流,然后把获得的输入流接到另一个数据流上,然后就可以从这个数据流读取服务器来的信息,同样sock使用getOutputStream()方法获得一个输出流,然后把获得的输出流接到另一个DataOutputStram()数据流上,然后向这个数据流写入信息,发送给服务器。
客户负责建立客户端到服务器的套接字连接,即客户端负责呼叫,因此服务器必须建立一个等待接收客户的套接字的ServerSocket对象,具体实现:
try{
ServerSocketserver_socket=newServerSocket(intport);
}catch(IOExceptione){}
当服务器的ServerSocket对象建立后,就可以使用accept()方法接收客户的套接字。
2.3服务器端功能设计
本课程设计—中国象棋(C/S)网络版,服务器端与客户端采用的时套接字连接,服务器端有一个是数据库文件,数据库中有一个表,该表时用来存在用户信息的,服务器端最主要的功能时用户登陆验证,客户端输入用户名和密码,客户端会通过套接字把信息发送给服务器端,服务器端条用数据库中的用户信息对用户的信息进行验证,然后把正确信息发送给客户端。
2.4客户端功能设计
客户端最主要的功能时实现象棋棋盘和棋子的绘制,还有一些棋子的走棋规则,本中国象棋棋盘棋子的绘制是采用图片最为背景的,只要应用Graphics的对象g调用drawImage()方法绘制棋盘,棋子的走棋规则是应用一些棋点数组记录棋子的位置,在棋子走动的时候判断棋子是否符合棋子的走棋规则。
3.总体设计
3.1总体功能图
根据对需求所做的分析,中国象棋游戏需要实现的基本功能应包括以下几个方面:
(1)用户登录验证功能
(2)提供棋盘和棋子;
(3)设定棋子的走棋规则;
(4)可以悔棋;
(5)可以聊天;
(6)判断胜负;
(7)建立主机和与主机建立连接;
(8)显示所有在线用户;
游戏可以再任何装有java运行环境的电脑中运行,界面简洁,大方,操作简单,方便,容易上手,满足中国象棋游戏爱好者智力娱乐的需求。
根据系统功能需求,其总体功能图如图2-1所示:
图2-1总体功能图
3.2总体流程图
根据对中国象棋游戏的功能分析,设计得到中国象棋游戏的总流程图如图2-2所示:
图2-2总体流程图
4.详细设计
4.1功能分析和描述
中国象棋游戏包括三大功能模块:
即用户登陆注册模块、中国象棋模块、,用户聊天模块。
具体实现的功能又下棋、悔棋、求和,认输、建立主机、建立连接、用户登陆、聊天、游戏音效等。
4.2中国象棋功能模块
中国象棋模块是《中国象棋》游戏额核心部分,它实现了游戏的最基本也是最重要的功能。
该模块中含有连接、退出系统和开始游戏功能三项功能。
功能模块结构图:
图2-3中国象棋功能模块结构图
4.2.1开始游戏
该功能为本游戏的最核心的部分,它实现了中国象棋游戏的最主要的操作,是其他功能的基础。
主要功能包括:
1.下棋
2.提示下棋方
3.悔棋
4.认输
5.求和
开始游戏流程图如图2-4所示:
图2-4开始游戏流程图
4.2.2连接功能
连接功能是开始游戏前必须进行的步骤,连接有建立主机、刷新主机、建立连接。
用户正确登陆系统后,进入中国象棋主界面,用户可以点击建立主机,把自己的电脑作为主机,然后等待其他用户连入就可以开始游戏了,用户还可以刷新主机,找到一个主机然后连入就可以开始游戏了。
连接功能流程图如图2-5所示:
图2-5连接功能流程图
4.2.3退出系统
该功能模块是为游戏者提供一种退出本游戏的方法,点击“退出系统”按钮退出
4.3用户登陆注册模块
用户登陆注册模块提供用户登陆和注册功能,用户运行客户端程序后,首先进入的是用户登陆界面,用户只要输入用户名和密码就可以进入中国象棋界面,如果用户没有用户名,就点击“注册”按钮进行注册,注册完成后就可以输入刚才申请的用户名和密码进入中国象棋界面。
用户登陆功能流程图如图2-6所示:
图2-6用户登陆功能流程图
用户注册功能流程图如图2-7所示:
图2-7用户注册功能流程图
4.4聊天模块
聊天模块提供给用户聊天,用户进入中国象棋界面后,开始游戏就可以与对方聊天了,用户发送信息给服务器,然后服务器把信息发送给对方,在对方界面显示。
聊天模块流程图如图2-8所示:
图2-8聊天模块流程图
5.算法设计
5.1算法概述
算法是指解决问题的一种方法或过程。
它是由若干条指令组成的由穷序列,并且满足下述5条性质:
(1)输入:
有零个或多个有外部提供的量作为算法的输入;
(2)输出:
算法产生至少一个量作为输出;
(3)可行性:
一个算法是能行的,即算法中描述的操作都是可以通过已经实现的基本运算执行有限次来实现的;
(4)确定性:
组成算法的每条指令是清晰的,无歧义的;
(5)有限性:
算法中每条指令的执行次数是有限的,执行每条的时间也是有限的
在中国象棋游戏中,涉及到多种算法。
例如象棋棋盘、棋子的绘制;象棋棋
种走棋规则的设置;象棋棋子拖动规则的设置;象棋棋子的悔棋设置等方面都利用到了算法。
这些算法的具体设计如下:
5.2棋盘、棋子绘制的算法设计
本中国象棋有限的棋盘和棋子采用的都是图片,采用图片比较简单,不用绘制那么多条线,用图片来代替棋盘和棋子,只要用Graphics对象g调用drawImage()方法就可以把突变加载进去。
棋盘的实现如下图2-9所示:
图2-9棋盘实现的相关代码
棋子的实现如下图2-10所示:
图2-10棋子实现的相关代码
5.3棋种走棋规则的算法设计
象棋的每种棋种都有它们自己的走棋规则的,例如,车走直线,中间不能有棋子;马走“日”;象走“田”等等。
下面我们就拿象棋棋子车,马,炮,象、士、卒、将的走棋规则算法分别来进行详细的说明:
5.3.1“车”的走棋规则的算法设计
“车”,它只能走直线,且中间不能有任何棋子,设计时分为两种情况来考虑,一种是纵向行走;一种是横向行走。
用if语句来判断实现,例如车纵向行走,首先,用if(startI==endI)来判断棋子是否纵向行走,接着再用判断语句if(point[startI][j].isPiece())来判断中间有没别的棋子。
横向行走同理。
如果棋子车符合以上的走棋规则,则可以走动,否则棋子强制放回原处。
现在假设车的棋点坐标为(i,j),i为横坐标,j为纵坐标,再设x,y为棋盘内任意值。
算法设计流程图如图2-11所示:
图2-11“车”的走棋规则算法设计流程图
5.3.2“马”的走棋规则的算法设计
“马”,它只能走“日”字格,而且马腿不能被其它的棋子压到。
设计时可
两种情况来考虑,一种是横向走两个棋点,纵向走一个棋点;一种是纵向走两个棋点,横向走一个棋点。
用if语句来判断,例如马横向走“日”,首先,用if(xAxle==2&&yAxle==1)来判断棋子是否横向走两个棋点,纵向走一个棋点,接着再用判断语句if(point[startI+1][startJ].isPiece())来判断马腿是否被其它棋子压着。
纵向走“日”同理。
如果棋子马符合以上的走棋规则,则可以走动,否则棋子强制放回原处。
现在假设马的棋点坐标为(a,b),a为横坐标,b为纵坐标,再设x,y为棋盘内任意值。
算法设计流程图如图2-12所示:
图2-12“马”的走棋规则算法设计流程图
5.3.3“卒”的走棋规则的算法设计
“卒”,它的行走规则分两种情况。
一种是棋子没过河界,另一种是棋子过了河界。
用if语句来判断,首先,用if(endJ<=5)语句来设定棋子没过河界,接着设定棋子在没过河界的情况下只能向前行走一个棋点;然后用if(endJ>=6)语句来设定棋子过了河界,紧接着设定棋子在过了河界的情况下只能向前、向左、向右行走一个棋点。
如果棋子卒符合以上的走棋规则,则可以走动,否则棋子强制放回原处。
现在假设卒的棋点坐标为(i,j),i为横坐标,j为纵坐标,再设x,y为棋盘内任意值。
算法设计流程图如图2-13所示:
图2-13“卒”的走棋规则算法设计流程图
5.3.4“将”的走棋规则的算法设计
“将”,它只能在“九宫”中行走,而且每次只能横着或者纵着行走一棋点。
直接用if语句来判断,首先,用if(endI<=6&&endI>=4)来判断棋子是否是在“九宫”里行走,接着判断棋子是否是横向或纵向只走一个棋点。
如果棋子将符合以上的走棋规则,则可以走动,否则棋子强制放回原处。
现在假设将的棋点坐标为(i,j),i为横坐标,j为纵坐标,再设x,y为棋盘内任意值。
算法设计流程图如图2-14所示:
图2-14“将”的走棋规则算法设计流程图
5.3.5“炮”的走棋规则的算法设计
“炮”,它只能走直线,且中间有且只能有一个棋子。
算法设计流程图如图2-15所示:
图2-15“炮”的走棋规则算法设计流程图
5.3.6“象”的走棋规则的算法设计
“象”,它只能走“田”字格,而且不能过河,象腿不能被其它的棋子压到。
这样只有一种情况考虑,那就是纵向走两个棋点,横向也走两个棋点。
用if语句来判断,首先,用if(xAxle==2&&yAxle==2&&endJ<=5)来判断棋子是否走"田"字格,而且不能过河,接着再用判断语句if(point[centerI][centerJ].isPiece())来判断象腿是否被其它棋子压着。
如果棋子象走动符合以上的走棋规则,则可以走动,否则棋子强制放回原处。
现在假设象的棋点坐标为(i,j),i为横坐标,j为纵坐标,再设x,y为棋盘内任意值。
算法设计流程图如图2-16所示:
图2-16“象”的走棋规则算法设计流程图
5.3.7“士”的走棋规则的算法设计
“士”,它只能在“九宫”中行走,而且每次只能斜着行走一格。
这样只有一种情况来考虑,即纵向走一个棋点,横向走一个棋点。
if语句来判断,if(endI<=6&&endI>=4&&endJ<=3&&xAxle==1&&yAxle==1)。
如果棋子士符合以上的走棋规则,则可以走动,否则棋子强制放回原处。
现在假设士的棋点坐标为(i,j),i为横坐标,j为纵坐标,再设x,y为棋盘内任意值。
算法设计流程图如图2-17所示:
图2-17“士”的走棋规则算法设计流程图
5.4棋子拖动规则的算法设计
在拖动象棋棋子的时候,首先要检查棋子当前覆盖的区域是否包含有一个棋点,接着判断该棋点上是否有棋子,这时,如果当前棋点上有棋子,我们还得判断,棋点上有棋子且棋子的颜色是否和所拖动的棋子颜色相同,如果相同,则将拖动的棋子放回原处;否则,就将拖动的棋子防止在当前位置上并将当前棋子上的对方棋子吃掉。
如果当前棋点上没有棋子,那就将棋子防止在棋点上即可。
算法设计流程图如图2-18所示:
图2-18棋子拖动规则算法设计流程图
5.5悔棋的算法设计
在悔棋的实现中,要考虑两种情况,一种是所悔的棋步没吃棋子,另一种是所悔的棋步吃了棋子。
如果是没吃棋子,只需将移动的棋子放回原处:
point[startI][startJ].setPiece(piece,board)即可;
如果是吃了棋子,就要先将悔棋方的棋子放回起始棋点point[startI][startJ].setPiece(piece,board),接着还得将被吃掉的棋子放回原处point[endI][endJ].setPiece(removedPiece,board)。
算法设计流程图如图2-19所示:
、图2-19悔棋算法设计流程图
6.代码实现
6.1类之间关系图
中国象棋程序包含22个java文件,其中包含DengluPanel.java、ZhucePanel.java、Start.java、Chessboard.java、Chess.java、NetSocket.java、StartServer.java、UdpServer.java、ChatServer.java等,其中ChatServer.java是在服务器端,服务器端就是一个文件,其他的是客户端的java文件,由于服务器就只有一个类,所以不用画类之间的关系图,客户端的类之间的关系图如图2-20所示:
图2-20客户端类之间的关系图
6.2运行效果图
用户登录界面:
图2-21用户登陆界面
用户注册界面:
图2-22用户注册界面
中国象棋主界面:
图2-23中国象棋主界面
中国象棋对弈一方界面:
图2-24中国象棋对弈一方界面
中国象棋对弈另一方界面:
图2-25中国象棋对弈另一方界面
服务器端界面:
图2-26服务器端界面
6.3程序打包发布过程
1.服务器端
服务器端程序在命令行窗口运行,不需要打包。
2.客户端
可以使用jar.exe命令制作JAR文件来发布编写软件。
(1)首先用文本编辑器,如Windows下的“记事本”,编写一个清单文件:
mymoon.mf
Manifest-Version:
1.0
Main-Class:
Main
Created-By:
1.5(SunMicrosystemsInc.)
将mymoon.Mf保存到D:
\中国象棋中,即和应用程序所用的字节码文件保存在相同的目录中。
注意:
清单文件中的“Manifest-Version:
”和1.0之间,“Main-Class:
”和主类Main之间以及“Created-By:
”和1.2之间必须有且只有一个空格。
(2)生成JAR文件
D:
\中国象棋\jarcfm中国象棋.jarmymoon.mf*.Class
其中,参数c表示要生成一个新的JAR文件,f表示要生成的JAR文件的名字,m表示清单文件的名字。
7.总结与说明
我做的是中国象棋(C/S)网络版,其实把中国象棋改成网络版并不难,最难的中国象棋中涉及的算法,比如“车”、“马”、“卒”、“将”、“炮”、“象”、“士”的走棋规则算法,它士用棋点数组来存储各个棋子的位置,当用户移动一个棋子后,就用棋点数组来判断棋是否符合棋子的走棋规则,这种算法设计很精妙,我在以后涉及到这种的算法,我就可以用这种方法。
附录:
程序源代码:
网络部分:
Start.java
importjava.awt.Dimension;
importjava.awt.Graphics;
import.URL;
importjavax.swing.ImageIcon;
importjavax.swing.JFrame;
importjavax.swing.JPanel;
importjavax.swing.*;
importjava.awt.*;
importjava.awt.event.*;
importjava.util.*;
importjava.sql.*;
publicclassStart{
staticJSplitPanerightPanel,rightPanel1;
//表示是否已连接,0表示未连接,1表示已连接
publicstaticintisCollection=0;
//表示是主机还是客户端,0表示客户端,1表示主机
publicstaticintisServer=0;
//下棋状态,0表示未开始,1表示我下,2表示对方下
publicstaticintchessState=0;
publicstaticintchessCount=0;
publicstaticintchessConfirm=0;
publicStart()
{
frame=newJFrame("中国象棋");
listTable=newHashtable();
chessboard=newChessboard(newImageIcon(getdir("images/main.jpg")).getImage());
frame.getContentPane().setLayout(null);
chessboard.setLocation(0,0);
frame.getContentPane().add(chessboard);
c=newUserName();
collection=newCollection();
JPanelpanel1=newJPanel();
panel1.setLayout(null);
panel1.add(c);
panel1.add(collection);
c.setBounds(10,15,220,30);
collection.setBounds(5,50,225,180);
panel1.setBorder(BorderFactory.createTitledBorder("连接"));
msg=newMessage();
JPanelpanel2=newJPanel();
panel2.setLayout(null);
panel2.add(msg);
msg.setBounds(5,15,220,250);
panel2.setBorder(BorderFactory.createTitledBorder("聊天区"));
//在线用户
zx=newZaiXian();
zx.setBounds(10,15,220,100);
zx.setBorder(BorderFactory.createTitledBorder("在线用户"));
rightPanel=newJSplitPane(JSplitPane.VERTICAL_SPLIT,true,panel1,zx);
rightPanel.setDividerLocation(225);
rightPanel1=newJSplitPane(JSplitPane.VERTICAL_SPLIT,true,rightPanel,panel2);
rightPanel1.setDividerLocation(360);
frame.getContentPane().add(rightPanel1);
rightPanel1.setBounds(554,0,235,678);
chess=newChess();
chess.setLocation(0,616);
frame.getContentPane().add(chess);
handlingMsg=