《网络对弈课程设计说明书分解.doc》由会员分享,可在线阅读,更多相关《网络对弈课程设计说明书分解.doc(58页珍藏版)》请在三一办公上搜索。
1、编号: 计算机网络课程设计说明书题 目:网络对弈程序设计 系 别:计算机科学与工程学院 专 业:计算机科学与技术 学生姓名: 学 号: 指导教师: 王虎寅 2013 年 3 月 20 日目 录1 设计任务及目标11.1 开发背景以及设计目标11.2设计任务12 需求分析22.1系统需求22.2用户需求22.2.1服务端需求22.2.2客户端需求22.2.3技术上可行性分析32.3.系统运行环境43 总体设计43.1系统结构设计43.2服务器设计53.3客户端设计73.4棋类设计84 详细设计94.1 服务器94.1.1服务器主类的设计开发94.1.2服务器线程的设计开发134.2 客户端234
2、.3棋盘以及规则265 软件实现以及使用说明465.1服务器运行使用及测试4652 客户端运行使用及测试496 总结536.1任务完成情况536.2特色与不足536.2.1特色536.2.2不足536.3所遇到的问题536.4体会547 参考文献551 设计任务及目标1.1 开发背景以及设计目标五子棋有着悠久的历史,五子棋爱好者更是不计其数,但是由于人们工作地点,时间的限制,生活节奏的加快,人们之间的交流越来越少,面对面下五子棋的机会更是少了很多,那种面对面的下棋的方式已经不再适应人们的生活,但网络给了人们一个交流的平台,因此人们开始转向网络五子棋。网络五子棋有很多优点,通过网络五子棋,对弈双
3、方可以是网络上任意两个五子棋的爱好者,甚至从不认识。网络五子棋让对弈的范围更加的广泛,让玩家可以与更多的五子棋爱好者切磋棋艺。所以我此次网络课程设计综合运用计算机网络、JAVA语言程序设计、网络编程等课程知识;从需求分析入手,系统地掌握计算机网络编程初级技术,独立、合理地完成网络五子棋对弈程序设计任务。设计目标主要包括:(1)实现需求分析阶段所要求的服务器端以及客户端的功能。(2)游戏界面朴素美观。(3)棋子样式采用传统样式,黑色和白色。(4)客户端的信息交流完全通过服务器传递完成。1.2设计任务 完成一个网络五子棋对弈程序设计工作。 根据自身多年来进行网络对弈的经验,以及了解,对网络五子棋对
4、弈的设计进行需求分析。根根设计目标以及需求分析对五子棋游戏界面总体规划和设计,游戏界面设计好以后进行服务器端和客户端的规划设计,最后进行棋盘以及棋子的设计。设计阶段要进行服务器端框架设计与业务代码开发,客户端框架设计与业务代码的开发,棋子以及棋盘类的设计开发,规则类的设计开发等。2 需求分析 2.1系统需求(1) 满足客户端连接到服务器的基本要求。(2) 服务器满足记录客户端游戏动作的基本要求。(3) 满足服务器实时获得客户端游戏状态的基本要求。2.2用户需求2.2.1服务端需求(1)可以有一个显示服务器状态的界面,用于记录各个客户端的连接状态。服务器是用于连接各个客户端的通信,如果独立地创建
5、一个直观的服务器,将有力地显示客户端的每个状态,直观地向用户反应各类信息。(2)可以支持多人同时在线。一个服务器能够你能够接受来自其他多个客户端的请求,提供相应的响应服务,是网络对弈的基本要求。(3)可以显示在线用户的信息。显示在线用户的信息,比如主机名,IP地址,以及连接断的状态,有利于用户随时监控客户端的通信状态。(4)不允许玩家同名。不允许客户端同名即是不允许客户端的端口号相同,如果相同,将会造成游戏登陆用户的管理混乱。(5)服务器界面节约大方。服务器是用于监控客户端的连接情况,没用必要做得繁杂,用户只需要直观的状态显示,所以我们的服务器不需要设计太多按钮,只需要有显示服务器状态,关闭服
6、务器,清空列表的按钮,方便用户操作。2.2.2客户端需求 (1) 能够通过主机IP及端口号登陆到服务器。 (2) 可以显示当前所有用户。游戏客户端应设计一个可以显示当前 所有在线用户的列表,有助于用户随意选择玩家挑战。(3) 可以从在线用户列表中选择玩家进行挑战。(4) 可以创建以及接受挑战。(5) 如果对方正在与其他玩家对弈,则应给出相应提示。(6) 五子棋规则一定要严密。其中五子棋游戏的规则如下: 棋盘,棋子:a) 棋盘为十五路,正中一点为“天元”,周围四点为小星。b) 棋子分黑白两色,黑子113枚,白子112枚,共225枚。 比赛规则:a) 黑先白后,从天元开始落子。然后执白棋的一方在黑
7、棋周围的交叉点上落子,白第二着棋应布在自己河界的一侧。此后,执黑方在以天元为中心的25个交叉点的范围内布盘面的第三着棋。b) 最先在横向,竖向,斜向形成连续的相同色五个棋子的一方为胜。c) 黑棋禁手判负,白棋无禁手。黑棋禁手包括“三三”,“四四”,“长连”。黑方只能“四三”胜。所谓禁手,是指黑方一子落下同时形成两个或两个以上的活三,冲四及长连禁手。长连禁手是指黑方形成六个或六个以上的连续棋子。d) 双方均不能形成五连为和棋。e) 对局中拔子,中途退场均判为负。f) 五连与禁手同时形成,先五为胜。因黑方已形成五连,故禁手失效,黑方胜。g) 黑方禁手形成时,白方应立即指出禁手点,黑方即负。若白方继
8、续应子,则黑方禁手不成立。h) 高段位职业比赛的特殊规定:“三手可交换”:黑下完第手,执白者可提出交换。即执白方变为执黑方。“五手两打法”:执黑下第五手时,必须下两手棋,执白者从这两手棋中任选一步。i) 本文所论述的联机五子棋系统就是依照这种方式进行的。2.2.3技术上可行性分析对需求分析阶段的结果进行总结,对软件的可行性分析如下:(1) 网络对弈需要两个客户端进行通信,而利用服务器的线程开发,进行中间中介连接正好可以完成。(2) 五子棋的规则虽然严密,但是通过各种情况分析,然后将每个情况分析设计出来。(3) 本系统的设计运行环境只用到MyEclipse的编程软件,无需借用到其它的软件,比较容
9、易实现。2.3.系统运行环境系统运行环境:MyEclipse 6.63 总体设计3.1系统结构设计该游戏主要分为服务器端与客户端两部分。服务器端的功能主要是建立与客户端的连接,监控客户端的连接及断开的状态,接收客户端发送的信息以及向客户端发送信息。客户端的功能主要是连接服务器端,创建游戏用户,创建游戏,加入游戏,选择玩家挑战,向服务器发送信息,接收服务器端发送来的信息。其具体的功能模块如图所示:网络五子棋服务器端客户端启动服务器维护在线用户信息接收客户端信息向客户端发送信息连接服务器创建游戏选择玩家挑战向服务器发送信息接收服务器传来的信息3.2服务器设计服务器的设计主要分为服务器主界面,服务器
10、线程,服务器主机面板三个部分。服务器主界面的设计主要包括界面大小,界面背景,界面上的按钮,比如清空列表,服务器状态,关闭服务器的设计,以及启动对客户端的监听,启动服务器线程。服务器线程的设计主要包括接受多个客户端的连接,接受客户端信息,向客户端发送信息。服务器主机面板的设计主要包括客户端信息板的设计,包括板的大小,背景颜色。其具体的功能模块如图所示:服务器端服务器主界面服务器线程服务器主机面板监听客户端启动服务器线程清空,显示,关闭服务器信息接收客户端信息向客户端发送信息信息板的显示3.3客户端设计客户端的设计主要分为客户端界面,客户端线程两部分。客户端界面的设计主要包括客户端界面大小,背景颜
11、色,主要按钮:创建游戏,加入游戏,连接到服务器,放弃游戏,退出游戏的设计以及它们对应事件的处理。客户端线程的设计主要包括连接到服务器,向服务器发送信息,接受服务器信息的设计以及它们对应的事件处理,比如收到服务器发送来的游戏胜利,信息错误,信息有效等的处理。其具体功能模块如图所示:客户端客户端界面客户端线程创建游戏加入游戏连接到游戏连接到服务器向服务器发送信息放弃游戏退出游戏接收服务器信息3.4棋类设计五子棋类的设计主要分为棋盘,棋子,五子棋动作线程,规则四部分。棋盘的设计主要包括画棋子,捕获下棋事件,画网络棋盘。棋子的设计包括黑棋以及白旗的设计,其中有大小,颜色,所属棋盘的设计。五子棋动作线程
12、的设计包括处理捕获下棋信息,发送当前下棋信息,这一部分的设计是五子棋类设计的重点。规则的设包括取得指定棋子的位置,判断当前棋子是否取得胜利,当前棋子各个方向的判断,当前所要下的棋子是否越界。五子棋棋盘棋子画棋子捕获下棋事件黑棋白棋五子棋线程画网络棋盘处理捕获的下棋信息发送当前下棋信息规则方向判断胜利判断越界判断4 详细设计4.1 服务器4.1.1服务器主类的设计开发服务器主类即服务器端的运行类,用户通过运行该类进入服务器的主界面。其中包括创建服务器端用到的控件以及声明用到的对象引用,完成对控件的初始化:设置窗体的标题,图标,大小以及可见性,将各个控件添加到各面板的相应位置FIRServer.j
13、ava类:/ 服务器界面类public class FIRServer extends Frame implements ActionListenerJButton clearMsgButton = new JButton(清空列表);JButton serverStatusButton = new JButton(服务器状态);JButton closeServerButton = new JButton(关闭服务器);Panel buttonPanel = new Panel();ServerMsgPanel serverMsgPanel = new ServerMsgPanel();Se
14、rverSocket serverSocket;Hashtable clientDataHash = new Hashtable(50); /将客户端套接口和输出流绑定Hashtable clientNameHash = new Hashtable(50); /将客户端套接口和客户名绑定Hashtable chessPeerHash = new Hashtable(50); /将游戏创建者和游戏加入者绑定public FIRServer()super(Java 五子棋服务器);setBackground(Color.LIGHT_GRAY);buttonPanel.setLayout(new F
15、lowLayout();clearMsgButton.setSize(60, 25);buttonPanel.add(clearMsgButton);clearMsgButton.addActionListener(this);serverStatusButton.setSize(75, 25);buttonPanel.add(serverStatusButton);serverStatusButton.addActionListener(this);closeServerButton.setSize(75, 25);buttonPanel.add(closeServerButton);clo
16、seServerButton.addActionListener(this);add(serverMsgPanel, BorderLayout.CENTER);add(buttonPanel, BorderLayout.SOUTH);addWindowListener(new WindowAdapter()public void windowClosing(WindowEvent e)System.exit(0););pack();setVisible(true);setSize(400, 400);setResizable(false);validate();trycreateServer(
17、4331, serverMsgPanel);catch (Exception e)e.printStackTrace();/ 用指定端口和面板创建服务器public void createServer(int port, ServerMsgPanel serverMsgPanel) throws IOExceptionSocket clientSocket; / 客户端套接口long clientAccessNumber = 1; / 连接到主机的客户数量this.serverMsgPanel = serverMsgPanel; / 设定当前主机tryserverSocket = new Se
18、rverSocket(port);serverMsgPanel.msgTextArea.setText(服务器启动于:+ InetAddress.getLocalHost() + : /djr+ serverSocket.getLocalPort() + n);while (true)/ 监听客户端套接口的信息clientSocket = serverSocket.accept();serverMsgPanel.msgTextArea.append(已连接用户: + clientSocket + n);/ 建立客户端输出流DataOutputStream outputData = new Da
19、taOutputStream(clientSocket.getOutputStream();/ 将客户端套接口和输出流绑定clientDataHash.put(clientSocket, outputData);/ 将客户端套接口和客户名绑定clientNameHash.put(clientSocket, (新玩家 + clientAccessNumber+);/ 创建并运行服务器端线程FIRServerThread thread = new FIRServerThread(clientSocket,clientDataHash, clientNameHash, chessPeerHash,
20、serverMsgPanel);thread.start();catch (IOException ex)ex.printStackTrace();public void actionPerformed(ActionEvent e)if (e.getSource() = clearMsgButton) / 清空服务器信息serverMsgPanel.msgTextArea.setText();if (e.getSource() = serverStatusButton) / 显示服务器信息tryserverMsgPanel.msgTextArea.append(服务器信息:+ InetAddr
21、ess.getLocalHost() + :+ serverSocket.getLocalPort() + n);catch (Exception ee)ee.printStackTrace();if (e.getSource() = closeServerButton) / 关闭服务器System.exit(0);public static void main(String args)FIRServer firServer = new FIRServer();4.1.2服务器线程的设计开发服务器线程是服务器启动后创建并启动的第一个线程,该线程主要用于接收客户端的连接,并未每个连接分配一个服务
22、器代理线程。服务器代理线程主要用于接收客户端传来的消息,并将该消息转发给另一个客户端。服务器为所有客户端都分配了一个该类线程实例,单独为特定客户端进行服务。同时每一个服务器代理线程都有能唯一标识的名称。FIRServerThead.java类:public class FIRServerThread extends ThreadSocket clientSocket; / 保存客户端套接口信息Hashtable clientDataHash; / 保存客户端端口与输出流对应的HashHashtable clientNameHash; / 保存客户端套接口和客户名对应的HashHashtable
23、 chessPeerHash; / 保存游戏创建者和游戏加入者对应的HashServerMsgPanel serverMsgPanel;boolean isClientClosed = false;public FIRServerThread(Socket clientSocket, Hashtable clientDataHash,Hashtable clientNameHash, Hashtable chessPeerHash,ServerMsgPanel server)this.clientSocket = clientSocket;this.clientDataHash = clien
24、tDataHash;this.clientNameHash = clientNameHash;this.chessPeerHash = chessPeerHash;this.serverMsgPanel = server;public void dealWithMsg(String msgReceived)String clientName;String peerName;if (msgReceived.startsWith(/)if (msgReceived.equals(/list) / 收到的信息为更新用户列表Feedback(getUserList();else if (msgRece
25、ived.startsWith(/creatgame inchess) / 收到的信息为创建游戏String gameCreaterName = msgReceived.substring(20); /取得服务器名synchronized (clientNameHash) / 将用户端口放到用户列表中clientNameHash.put(clientSocket, msgReceived.substring(11);synchronized (chessPeerHash) / 将主机设置为等待状态chessPeerHash.put(gameCreaterName, wait);Feedback
26、(/yourname + clientNameHash.get(clientSocket);sendGamePeerMsg(gameCreaterName, /OK);sendPublicMsg(getUserList();else if (msgReceived.startsWith(/joingame ) / 收到的信息为加入游戏时StringTokenizer userTokens = new StringTokenizer(msgReceived, );String userToken;String gameCreatorName;String gamePaticipantName;S
27、tring playerNames = 0, 0 ;int nameIndex = 0;while (userTokens.hasMoreTokens()userToken = (String) userTokens.nextToken( );if (nameIndex = 1 & nameIndex + msgReceived;serverMsgPanel.msgTextArea.append(msgReceived + n);sendPublicMsg(msgReceived);serverMsgPanel.msgTextArea.setCaretPosition(serverMsgPan
28、el.msgTextArea.getText().length();/ 发送公开信息public void sendPublicMsg(String publicMsg)synchronized (clientDataHash)for (Enumeration enu = clientDataHash.elements(); enu.hasMoreElements();)DataOutputStream outputData = (DataOutputStream) enu.nextElement();tryoutputData.writeUTF(publicMsg);catch (IOExc
29、eption es)es.printStackTrace();/ 发送信息给指定的游戏中的用户public boolean sendGamePeerMsg(String gamePeerTarget, String gamePeerMsg)for (Enumeration enu = clientDataHash.keys(); enu.hasMoreElements();) / 遍历以取得游戏中的用户的套接口Socket userClient = (Socket) enu.nextElement();if (gamePeerTarget.equals(String) clientNameHa
30、sh.get(userClient)& !gamePeerTarget.equals(String) clientNameHash.get(clientSocket) / 找到要发送信息的用户时synchronized (clientDataHash)/ 建立输出流DataOutputStream peerOutData = (DataOutputStream) clientDataHash.get(userClient);try/ 发送信息peerOutData.writeUTF(gamePeerMsg);catch (IOException es)es.printStackTrace();
31、return false;return true;/ 发送反馈信息给连接到主机的人public void Feedback(String feedBackMsg)synchronized (clientDataHash)DataOutputStream outputData = (DataOutputStream) clientDataHash.get(clientSocket);tryoutputData.writeUTF(feedBackMsg);catch (Exception eb)eb.printStackTrace();/ 取得用户列表public String getUserLi
32、st()String userList = /userlist;for (Enumeration enu = clientNameHash.elements(); enu.hasMoreElements();)userList = userList + + (String) enu.nextElement();return userList;/ 根据value值从Hashtable中取得相应的keypublic Object getHashKey(Hashtable targetHash, Object hashValue)Object hashKey;for (Enumeration enu
33、 = targetHash.keys(); enu.hasMoreElements();)hashKey = (Object) enu.nextElement();if (hashValue.equals(Object) targetHash.get(hashKey)return hashKey;return null;/ 刚连接到主机时执行的方法public void sendInitMsg()sendPublicMsg(getUserList();Feedback(/yourname + (String) clientNameHash.get(clientSocket);Feedback(
34、Java 五子棋客户端);Feedback(/list -更新用户列表);Feedback(/ -私聊);Feedback(注意:命令必须对所有用户发送);public void closeClient()serverMsgPanel.msgTextArea.append(用户断开连接: + clientSocket + n);synchronized (chessPeerHash) /如果是游戏客户端主机if (chessPeerHash.containsKey(clientNameHash.get(clientSocket)chessPeerHash.remove(String) clientNameHash.get(clientSocket);if (chessPeerHa