《某学院面向对象程序设计实训报告.docx》由会员分享,可在线阅读,更多相关《某学院面向对象程序设计实训报告.docx(38页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、广西科技大学鹿山学院课程设计报告 广西科技大学鹿山学院面向对象程序设计实训报告题 目: 网络中国象棋 系 别: 电气与计算机工程系 专业班级: 计软141班 姓 名: 邓康言 学 号: 20141409 成绩评定: 指导教师签字: 2016 年 1 月10 日26编号:时间:2021年x月x日书山有路勤为径,学海无涯苦作舟页码:第37页 共38页目录目录1、需求分析11.1 开发的背景11.2 算法11.3 要求12、总体分析与设计12.1 总体设计方案12.2 功能描述22.2.1服务器端22.2.2客户端22.3 算法设计-32.5 系统流程图-43、 数据结构设计43.1 功能模块的设计
2、43.1.1 服务器端框架类设计43.1.2 服务器线程设计83.1.3 服务器代理线程设计83.1.4 棋子的开发类设计133.1.5 客户端的框架类设计143.1.6 客户端的框架类设计163.1.7 棋子的规则类设计193.1.8 棋盘的规则类设计224、系统实现264.1服务器端界面264.2客户端界面264.3 未启动服务器,客户端连接失败274.4服务器启动274.5 服务器启动客户端成功连接284.6 显示在线用户284.7 不允许重名294.8发起挑战294.9拒绝挑战304.10接受挑战304.11 对战走棋314.12 不能向正在下棋的用户发起挑战314.13 赢棋324.
3、14 认输324.15 服务器关闭33总 结33参考文献341、 需求分析1.1 开发的背景中国象棋有着悠久的历史,象棋爱好者更是不计其数,但是由于人们的工作地点从、时间的限制,原始的那种面对面的下棋方式已经不再适应人们的生活,人们已经开始走向网络象棋博弈网络象棋有着很多的优点,通过网络象棋,对弈的双方是网络上任意的两个象棋爱好者,甚至是不认识。网络让对弈的范围更加的广泛,让象棋爱好者可以与更多的象棋爱好者切磋棋艺。1.2 算法指定服务器端口号支持多人同时在线显示在线用户信息显示当前在线所有用户从在线用户列表中选择玩家进行挑战接受或拒绝挑战1.3 要求用Java语言实现系统,源程序要有适当的注
4、释,使程序容易阅读函数功能要划分好(结构化程序设计)可以增加新功能模块2、 总体分析与设计2.1 总体设计方案系统功能模块图: 2.2 功能描述 2.2.1服务器端可以指定服务器端口号。可以支持多人同时在线。可以显示在线用户信息。不允许玩家同名2.2.2客户端 能够通过主机IP号及端口号登陆到服务器。可以显示当前在线所有用户。可以从在线用户列表中选择玩家进行挑战。可以接受或拒绝挑战。如果对方在和其他玩家对弈中,则应该给与相应的提示信息。象棋规则一定要严密。棋子样式采用最普通的橡胶式象棋。棋子为黑色,字为红色和白色2.3 算法设计- 本程序功能模块根据程序设计的需要。综合程序的实用性、智能化的考
5、虑。将程序划分为8个模块来写。(1)服务器端的框架设计类(2)服务器线程类(3)服务器代理线程类(4)棋子类的开发类(5)客户端的框架设计类(6)客户端线程类(7)棋子的规则类(8)棋盘的设计类2.5 系统流程图- 3、 数据结构设计3.1 功能模块的设计3.1.1 服务器端框架类设计import java.util.*;import java.awt.*;/界面包import java.awt.event.*;/事件处理包import javax.swing.*;/图形化界面包import javax.swing.event.*;/图形化界面包事件进行处理import .*;/网络包impo
6、rt java.io.*;/IO流public class Server extends JFrame implements ActionListenerJLabel jlPort=new JLabel(端 口 号);/创建提示输入端口号标签JTextField jtfPort=new JTextField(9457);/用于输入端口号的文本框JButton jbStart=new JButton(启动);/创建启动按钮JButton jbStop=new JButton(关闭);/创建关闭按钮JPanel jps=new JPanel();/创建一个JPanel对象JList jlUserO
7、nline=new JList();/创建用于显示当前用户的JListJScrollPane jspx=new JScrollPane(jlUserOnline);/将显示当前用户的JList放在JScrollPane中JSplitPane jspz=new JSplitPane(JSplitPane.HORIZONTAL_SPLIT,jspx,jps);/创建JSplitPane对象ServerSocket ss;/声明ServerSocket引用ServerThread st;/声明ServerThread引用Vector onlineList=new Vector();/创建存放当前在线
8、用户的Vector对象public Server()this.initialComponent();/初始化控件this.addListener();/为相应的控件注册事件监听器this.initialFrame();/初始化窗体this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);public void initialComponent()jps.setLayout(null);/设为空布局jlPort.setBounds(20,20,50,20);jps.add(jlPort);/添加用于提示输入端口号的标签this.jtfPort.set
9、Bounds(85,20,60,20);jps.add(this.jtfPort);/添加用于输入端口号的文本框this.jbStart.setBounds(18,50,60,20);jps.add(this.jbStart);/添加开始按钮this.jbStop.setBounds(85,50,60,20);jps.add(this.jbStop);/添加关闭按钮this.jbStop.setEnabled(false);/将关闭按钮设为不可用public void addListener()this.jbStart.addActionListener(this);/为开始按钮注册事件监听器
10、this.jbStop.addActionListener(this);/为关闭按钮注册事件监听器public void initialFrame()this.setTitle(象棋-服务器端);/设置窗体标题Image image=new ImageIcon(ico.gif).getImage();this.setIconImage(image);this.add(jspz);/将JSplitPane添加到窗体中jspz.setDividerLocation(250);jspz.setDividerSize(4);/设置分割线的位置和宽度this.setBounds(20,20,420,32
11、0);this.setVisible(true);/设置可见性this.addWindowListener(/为窗体关闭事件注册监听器new WindowAdapter()public void windowClosing(WindowEvent e)if(st=null)/当服务器线程为空时直接退出System.exit(0);/退出return;tryVector v=onlineList;int size=v.size();for(int i=0;isize;i+)/当不为空时,向在线用户发送离线信息ServerAgentThread tempSat=(ServerAgentThread
12、)v.get(i);tempSat.dout.writeUTF();tempSat.flag=false;/终止服务器代理线程st.flag=false;/终止服务器线程st=null;ss.close();/关闭ServerSocketv.clear();/将在线用户列表清空refreshList();/刷新列表catch(Exception ee)ee.printStackTrace();System.exit(0);/退出);public void actionPerformed(ActionEvent e)if(e.getSource()=this.jbStart)/当单击启动按钮时t
13、his.jbStart_event();else if(e.getSource()=this.jbStop)/单击关闭按钮后this.jbStop_event();public void jbStart_event()/单击启动按钮的业务处理代码int port=0;try/获得用户输入的端口号,并转化为整型port=Integer.parseInt(this.jtfPort.getText().trim();catch(Exception ee)/端口号不是整数,给出提示信息JOptionPane.showMessageDialog(this,端口号只能是整数,错误, JOptionPane
14、.ERROR_MESSAGE);return;if(port65535|port0)/断口号不合法,给出提示信息JOptionPane.showMessageDialog(this,端口号只能是0-65535的整数,错误, JOptionPane.ERROR_MESSAGE);return;trythis.jbStart.setEnabled(false);/将开始按钮设为不可用this.jtfPort.setEnabled(false);/将用于输入端口号的文本框设为不可用this.jbStop.setEnabled(true);/将停止按钮设为可用ss=new ServerSocket(p
15、ort);/创建ServerSocket对象st=new ServerThread(this);/创建服务器线程st.start();/启动服务器线程/给出服务器启动成功的提示信息JOptionPane.showMessageDialog(this,服务器启动成功,提示, JOptionPane.INFORMATION_MESSAGE);catch(Exception ee)/给出服务器启动失败的提示信息JOptionPane.showMessageDialog(this,服务器启动失败,错误, JOptionPane.ERROR_MESSAGE);this.jbStart.setEnable
16、d(true);/将开始按钮设为可用this.jtfPort.setEnabled(true);/将用于输入端口号的文本框设为可用this.jbStop.setEnabled(false);/将停止按钮设为不可用public void jbStop_event()/单击关闭按钮的业务处理代码tryVector v=onlineList;int size=v.size();for(int i=0;isize;i+)/向在线用户发送离线信息ServerAgentThread tempSat=(ServerAgentThread)v.get(i);tempSat.dout.writeUTF();te
17、mpSat.flag=false;/关闭服务器代理线程st.flag=false;/关闭服务器线程st=null;ss.close();/关闭ServerSocketv.clear();/将在线用户列表清空refreshList();/刷新列表this.jbStart.setEnabled(true);/将开始按钮设为可用 this.jtfPort.setEnabled(true);/将用于输入端口号的文本框设为可用 this.jbStop.setEnabled(false);/将停止按钮设为不可用catch(Exception ee)ee.printStackTrace();public v
18、oid refreshList()/更新在线用户列表的业务处理代码Vector v=new Vector();int size=this.onlineList.size();for(int i=0;isize;i+)/遍历在线列表ServerAgentThread tempSat=(ServerAgentThread)this.onlineList.get(i);String temps=tempSat.sc.getInetAddress().toString();temps=temps+|+tempSat.getName();/获得所需信息v.add(temps);/添加到Vector中th
19、is.jlUserOnline.setListData(v);/更新列表数据public static void main(String args)new Server();说明:此服务器端类既为服务器的运行类,用户通过该类进入服务器的主界面。进行相应的操作。3.1.2 服务器线程设计/*服务器线程*/import java.util.*;import java.awt.*;import java.awt.event.*;import javax.swing.*;import javax.swing.event.*;import .*;import java.io.*;public class
20、 ServerThread extends ThreadServer father; /声明Server的引用ServerSocket ss;/声明ServerSocket的引用boolean flag=true;/线程存在为truepublic ServerThread(Server father)/构造器this.father=father;ss=father.ss;/和服务器端关联public void run()while(flag)/定义一个死循环。为false时跳出trySocket sc=ss.accept();/等待客户端连接ServerAgentThread sat=new
21、ServerAgentThread(father,sc);sat.start();/创建并启动服务器代理线程catch(Exception e)/try catch捕获异常e.printStackTrace();/打印异常,可有可无类功能说明:服务器线程类在服务器启动后创建并启动的第一个线程,该线程主要用于接收客户端的连接,并为每一个连接分配一个服务器代理线程。3.1.3 服务器代理线程设计【部分代码(过长不适复制完)】:/*服务器代理线程*/先想到需要用什么函数import java.util.*;import java.awt.*;/界面包import java.awt.event.*;/
22、事件处理包import javax.swing.*;/图形化界面包import javax.swing.event.*;/图形化界面包事件进行处理import .*;/网络包import java.io.*;/IO流public class ServerAgentThread extends Thread /同服务器类一样Server father;/声明Server的引用Socket sc;/声明Socket的引用。用他来与客户端一一对应。分配给它资源DataInputStream din;/声明数据输入流与输出流的引用DataOutputStream dout;boolean flag=t
23、rue;/控制线程的标志位public ServerAgentThread(Server father,Socket sc)this.father=father;this.sc=sc;trydin=new DataInputStream(sc.getInputStream();/创建数据输入流dout=new DataOutputStream(sc.getOutputStream();/创建数据输出流catch(Exception e)e.printStackTrace();public void run()while(flag)/线程在存活期。就是死循环。tryString msg=din.
24、readUTF().trim();/接收客户端传来的信息if(msg.startsWith()/收到新用户的信息this.nick_name(msg);else if(msg.startsWith()/收到用户离开的信息this.client_leave(msg);else if(msg.startsWith()/收到用户发出的挑战信息this.tiao_zhan(msg);else if(msg.startsWith()/收到接受挑战的信息this.tong_yi(msg);else if(msg.startsWith()/收到拒绝挑战的信息this.butong_yi(msg);else
25、if(msg.startsWith()/收到被挑战者忙的信息this.busy(msg);else if(msg.startsWith()/收到走棋的信息this.move(msg);else if(msg.startsWith()/收到某用户认输的信息this.renshu(msg);catch(Exception e)e.printStackTrace();public void nick_name(String msg)tryString name=msg.substring(13);/获得用户的昵称this.setName(name);/用该昵称给该线程取名Vector v=fathe
26、r.onlineList;/获得在线用户列表boolean isChongMing=false;int size=v.size();/获得用户列表的大小for(int i=0;isize;i+)/遍历列表,查看是否已经有该用户名ServerAgentThread tempSat=(ServerAgentThread)v.get(i);if(tempSat.getName().equals(name)isChongMing=true;/有重名,将标志位设为truebreak;if(isChongMing=true)/如果重名dout.writeUTF();/将重名信息发送给客户端din.clos
27、e();/关闭数据输入流dout.close();/关闭数据输出流sc.close();/关闭Socketflag=false;/终止该服务器代理线程else/如果不重名v.add(this);/将该线程添加到在线列表father.refreshList();/刷新服务器在线信息列表String nickListMsg=;size=v.size();/获得在线列表大小for(int i=0;isize;i+)ServerAgentThread tempSat=(ServerAgentThread)v.get(i);nickListMsg=nickListMsg+|+tempSat.getNam
28、e();/将在线列表内容住组织成字符串nickListMsg=+nickListMsg;Vector tempv=father.onlineList;size=tempv.size();for(int i=0;isize;i+)/遍历在线列表ServerAgentThread satTemp=(ServerAgentThread)tempv.get(i);satTemp.dout.writeUTF(nickListMsg);/将最新的列表信息发送到各个客户端if(satTemp!=this)/给其他客户端发送新用户上线的信息satTemp.dout.writeUTF(+this.getName
29、()+上线了.);catch(IOException e)e.printStackTrace();服务器代理线程类功能及实现:服务器代理线程主要是用于接收客户端传来的信息,并将该信息转发给相对应的另一个客户端。服务器为所有客户端都分配了一个该类线程,单独为特定客户端进行服务。同时每一个服务器代理线程都有能位移标示其的名称3.1.4 棋子的开发类设计import java.util.*;import java.awt.*;import javax.swing.*;public class QiZi/定义棋子的属性private Color color;/棋子的颜色private String n
30、ame;/棋子的名字,即是什么棋private int x;/所在的x方向位置将用二维数组实现private int y;/所在的y方向位置 将 用二维数组实现private boolean focus=false;/是否被选中,以至于只能选一子走public QiZi()/无参函数public QiZi(Color color,String name,int x,int y)/颜色,名字,坐标/构造器this.color=color;this.name=name;this.x=x;this.y=y;this.focus=false;/为未选中状态public Color getColor()
31、/获得棋子颜色的方法return this.color;public void setColor(Color color)/设置棋子颜色的方法this.color=color;public String getName()/获得棋子名字的方法return this.name;public void setName(String name)/设置棋子名字的方法this.name=name;public int getX()/获得棋子x方向位置的方法return this.x;public void setX(int x)/设置棋子x方向位置的方法this.x=x;public int getY(
32、)/获得棋子y方向位置的方法return this.y;public void setY(int y)/设置棋子y方向位置的方法this.y=y;public boolean getFocus()/判断棋子是否被选中的方法return focus;public void setFocus(boolean focus)/设置棋子选中状态的方法this.focus=focus;棋子类功能实现:该类主要包含有棋子的属性及一些关于属性的小方法3.1.5 客户端的框架类设计部分代码:import java.awt.*;import java.awt.event.*;import javax.swing.
33、*;import javax.swing.event.*;import java.util.*;import java.io.*;import .*;public class XiangQi extends JFrame implements ActionListener/设置控件public static final Color bgColor=new Color(245,250,160);/棋盘的背景色。RGB调色public static final Color focusbg=new Color(242,242,242);/棋子选中后的背景色。RGB调色public static fi
34、nal Color focuschar=new Color(96,95,91);/棋子选中后的字符颜色。RGB调色public static final Color color1=new Color(249,183,173);/红方的颜色。RGB调色public static final Color color2=Color.white;/白方的颜色 直接定义JLabel jlHost=new JLabel(主机IP);/创建提示输入主机名的标签JLabel jlPort=new JLabel(端口号);/创建提示输入端口号标签JLabel jlNickName=new JLabel(昵 称)
35、;/创建提示输入昵称的标签JTextField jtfHost=new JTextField(127.0.0.1);/创建输入主机名的文本框,默认值是127.0.0.1JTextField jtfPort=new JTextField(9457);/创建输入端口号的文本框,默认值是9999JTextField jtfNickName=new JTextField(康言先森);/创建输入昵称的文本框,默认值是Play1JButton jbConnect=new JButton(连 接);/创建连接按钮JButton jbDisconnect=new JButton(断 开);/创建断开按钮JBu
36、tton jbFail=new JButton(认 输);/创建认输按钮JButton jbChallenge=new JButton(挑 战);/创建挑战按钮JComboBox jcbNickList=new JComboBox();/创建存放当前用户的下拉列表框JButton jbYChallenge=new JButton(接受挑战);/创建接受挑战按钮JButton jbNChallenge=new JButton(拒绝挑战);/创建拒绝挑战按钮int width=60;/设置棋盘两线之间的距离QiZi qiZi=new QiZi910;/创建棋子数组QiPan jpz=new QiP
37、an(qiZi,width,this);/创建棋盘/JPanel jpz=new JPanel();/创建一个JPanel,暂时代替棋盘JPanel jpy=new JPanel();/创建一个JPanelJSplitPane jsp=new JSplitPane(JSplitPane.HORIZONTAL_SPLIT,jpz,jpy);/创建一个JSplitPaneboolean caiPan=false;/可否走棋的标志位int color=0;/0 代表红棋,1代表白棋Socket sc;/声明Socket引用ClientAgentThread cat;/声明客户端代理线程的引用publ
38、ic XiangQi()/构造XiangQi方法this.initialComponent();/初始化控件this.addListener();/为相应控件注册事件监听器this.initialState();/初始化状态this.initialQiZi();/初始化棋子this.initialFrame();/初始化窗体public void initialComponent()jpy.setLayout(null);/设为空布局this.jlHost.setBounds(10,10,50,20);jpy.add(this.jlHost);/添加主机IP标签this.jtfHost.setBounds(70,10,80,20);jpy.add(this.jtfHost);/添加用于输入主机名的文本框this.jlPort.setBounds(10,40,50,20);jpy.add(this.jlPort);/添加端口号标签this.jtfPort.setBounds(70,40,80,20);jpy.add(this.jtfPort);/添加用于输入端口号的文本框this.jlNickName.set