Java课程设计报告(汉诺塔)_第1页
Java课程设计报告(汉诺塔)_第2页
Java课程设计报告(汉诺塔)_第3页
Java课程设计报告(汉诺塔)_第4页
Java课程设计报告(汉诺塔)_第5页
已阅读5页,还剩51页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

Java课程设计报告(汉诺塔)东华理工大学理学院信计Java课程设计PAGE20-东华理工大学Java课程设计报告题目:汉诺塔所在院系:理学院学生姓名:漆俊、朱学曼、颜瑶专业:信息与计算科学班级:1223201-2指导老师:黄国辉2014年12月29日目录概述题目概述题目分析课程设计1.课程设计目的2.课程设计内容3.课程设计环境4.课程设计要求三.系统需求分析1.系统目标2.主体功能3.开发环境四.系统概要设计1.系统功能模块划分2.流程图3.自定义类说明五.系统详细设计六.测试测试方案测试结果七.小结八.参考文献程序代码一.概述题目概述:Hannoi塔:

设计GUI界面的Hannoi塔,用户可以通过拖动鼠标移动各个塔上的盘子,程序也可以自动演示盘子的移动过程。

设计要求

1.有三个表示塔的对象,分别命名为A、B和C。A塔上有若干个盘子,盘子的大小不等,并按着大小顺序依次摆放在A塔上,大盘在下,小盘在上。用户可以用鼠标拖动盘子,把A

塔上的盘子全部移动到另外两个塔中的任何一个塔上。要求每次只能移动一个盘子,在任何时候不允许大盘压在小盘的上面。

2.用户也可以选择让程序自动演示。选择自动演示后,程序将以动画形式演示把A塔上的盘子全部移到C塔的过程,并将移动过程以文本形式显示在一个文本区中。2.题目分析:(1)在窗口中画出初始时塔和碟子的状态。(2)可以以自动或手动两种方式搬移碟子。(3)自动搬移可以通过定时器或多线程的方法,每一次移动的时间间隔可以自定,以人眼观察比较舒服为宜,每一次的移动过程如能实现动画最好。(4)定义塔的描述类和碟子的描述类。(5)在程序中,碟子的数目及每次移动的时间间隔可以通过对话框设置(也应该有默认值)。(6)支持暂停功和继续的功能(在自动搬移过程中可以暂停,并继续)。(7)暂停后,可以将当前的状态保存(碟子和塔的组合关系)。(8)可以从7中保存的文件中读出某个状态,并继续移动。二.课程设计1.课程设计目的《JAVA程序设计》是计算机相关专业的选修专业基础课程,其实践性、应用性很强。实践教学环节是必不可少的一个重要环节。本课程的程序设计专题实际是计算机相关专业学生学习完《JAVA程序设计》课程后,进行的一次全面的综合训练,JAVA程序设计的设计目的是加深对理论教学内容的理解和掌握,使学生较系统地掌握程序设计及其在网络开发中的广泛应用,基本方法及技巧,为学生综合运用所学知识,利用软件工程为基础进行软件开发、并在实践应用方面打下一定基础。课程设计内容我设计的Hannoi塔,除了要编写的6个java文件所给出的类外,还需要java系统提供的一些重要的类,如JButton,JCheckBox等。汉诺塔中有三个座,名字分别为A,B,C。刚开始的时候A塔上有3个大小不等的盘子,这些盘子从座底到座顶按着大小顺序依次摆放在A座上。用户可以用鼠标选中盘子,然后通过拖动鼠标来移动盘子。释放鼠标来放置该盘子。程序要求用户在移动盘子的过程中,不允许吧大盘子放置在小盘子的上面,用户最终要完成的是把A座上的全部盘子移动到B座或C座上。用户可以通过Hannoi塔界面的提供的改变盘子数目功能来改变盘子的数目,同时可以改变盘子的大小以及改变盘子和界面的背景颜色,而且还可以选择控制背景音乐的播放。用户可以通过单击Hannoi塔界面上提供的按钮,让程序自动完成把A座上的盘子全部移动到C座上。用户在移动盘子的过程中,可以随时单击Hannoi塔界面上提供的按钮,重新开始。课程设计环境硬件要求能运行Windows9.X操作系统的微机系统。JAVA程序设计语言及相应的集成开发环境,J2SDK和ECLIPSE开发工具。课程设计要求按课程设计指导书提供的课题,要求学生在自行完成各个操作环节,并能实现且达到举一反三的目的,完成一个项目解决一类问题。要求学生能够全面、深入理解和熟练掌握所学内容,并能够用其分析、设计和解答类似问题;对此能够较好地理解和掌握,能够进行简单分析和判断;能编写出具有良好风格的程序;掌握JAVA程序设计的基本技能和面向对象的概念和方法;了解多线程、安全和网络等编程技术。同时培养学生进行分析问题、解决问题的能力;培养学生进行设计分析、设计方法、设计操作与测试、设计过程的观察、理解和归纳能力的提高。三.系统需求分析系统目标所设计代码可以正常运行程序,并且按照设计目的预想的完成具体功能。主体功能(1)设计GUI界面的Hannoi塔。Hannoi塔中有三个座,名字分别是A、B和C。初始状态是A座上有五个大小不等的盘子,这些盘子从座底到座顶按着大小顺序依次摆放在A座上。用户可以用鼠标选中盘子,然后通过拖动鼠标来移动该盘子、释放鼠标来放置该盘子。(2)程序要求用户在移动盘子过程中,不允许把大盘子放在小盘子的上面,用户最终要完成的是把A座上的全部盘子移动到B座或C座上。(3)用户可以通过单击Hannoi塔界面上提供的按钮,让程序自动完成把A座上的盘子全部移动到B座或C座上。(4)用户在移动盘子的过程中,可以随时单击Hannoi塔界面上提供的按钮,重新开始游戏。3.开发环境JAVA程序设计语言及相应的集成开发环境,JDK1.6。四.系统概要设计主要要实现的功能有:完成汉诺塔的“手工移动演示”;完成汉诺塔的“自动移动演示”;增加计时功能,即显示用户完成移动盘子所花费的时间;用户可以设置最大和最小盘子的大小;用户可以选择播放和暂停背景音乐;用户可以设置盘子的数目;用户可以设置盘子的颜色以及背景颜色;用户可以将自动移动盘子的文本信息保存到文件。系统功能模块划分(1)Tower.java(主类)Tower类负责创建Hannoi塔的主窗口,该类含有main方法,Hannoi塔从类开始执行。Tower类的成员变量中有两种重要类型的对象:一个int基本型数据和一个char型数组。两种类型的对象分别是:HannoiTower和Button对象。(2)HannoiTower.javaHannoiTower类是javax.swing包中JPanel容器的子类,创建的容器被添加到Tower窗口的中心。HannoiTower类的成员变量有两种重要类型的对象、一个int基类型数据和一个char型数组。两种类型的对象分别是:Disk、TowerPoint。(3)TowerPoint.javaTowerPoint类负责在HannoiTower中创建表示位置的塔点对象。(4)Disk.javaDisk类是Button的一个子类,创建的对象是HannoiTower容器中的一个按钮,用来表示HannoiTower中的盘子。流程图(图4-1)自定义类说明(1)自定义类类名:JButton作用:自定义主类,实现圆盘的类Disc继承JButton类继承的父类:Disc类实现的接口:没有(2)成员变量JButton成员变量成员变量描述变量类型名称控制盘子数目StringJLabel重新开始Stringrenew.setText开始游戏Stringrenew.setText背景颜色Stringbgcolor盘子颜色Stringpzcolor(3)方法表Chesspad方法方法名功能备注fillRect()绘制出矩形区域构造方法g.fillOval()绘制相同数目点构造方法drawString()绘制出A、B、C座

构造方法setBackground()设置背景颜色和盘子颜色构造方法Timer(inta,Objectb)创建一个计时器

构造方法stop()停止计时器计时

接口方法write保存文件

接口方法actionPerformed事件处理

evaluate评估

五.系统详细设计Tower类Tower类是javax.swing包中Frame的一个子类,标明该类的主要成员变量和方法:成员变量tower是HannoiTower创建的对象。tower对象是一个容器,刻画了Hannoi塔的结构,该对象被添加到窗口的中心。盘子数目是int型数据,它的默认值是5。盘子数目的值是用来确定tower对象中“盘子”的数目。towerName是char型数组,长度为3,其三个单元的默认取值依次是A、B和C。towerName数组的单元的值用来确定tower中三个塔的名字。renew和auto是Button创建的按钮对象,名字依次为“重新开始”和“自动演示搬盘子”,renew和auto都将当前窗口注册为自己的ActionEvent事件监视器。方法取消起始塔定义,并将塔顶盘设为黄色取消起始塔定义,并将塔顶盘设为黄色是否自动搬移退出开始是否正在移动退出是否点中某个塔退出是否已定义起始塔塔上是否有盘退出定义当前塔为起始塔,并将塔顶盘设为蓝色是否起始塔消息框报错退出该塔顶盘是否比欲移动盘大消息框报错退出定义为目标塔,调MovePlate函数,将起始塔顶的金盘移动到目标塔顶。退出是否是否否是是否退出否是是否否是图4-1Tower()是构造方法,负责完成窗口的初始化。main方法是Hannoi塔程序运行的入口方法。actionPerformed(ActionEvent)方法是HannoiTower类实现的ActionListener接口中的方法。HannoiTower创建的窗口是renew和auto两个按钮的ActionEvent事件监视器。当用户单击按钮时,窗口将执行actionPerformed(ActionEvent)方法进行相应的操作。当用户单击renew按钮时,actionPerformed(ActionEvent)方法所进行的操作是保持当前的盘子数目的值,并让tower对象根据盘子数目的值设置其初始状态。当用户单击auto按钮时,actionPerformed(ActionEvent)方法所进行的操作是让tower对象返回其中的AutoMoveDisc对象,该对象是一个对话框,用户可以通过对话框让程序自动地移动“盘子”。六.测试1.测试方案本程序的初始状态是A塔上有五个大小不等的盘子,这些盘子从座底到座顶按着大小顺序依次摆放在A塔上。用户可以用鼠标选中盘子,然后通过拖动鼠标来移动该盘子、释放鼠标来放置该盘子。程序要求用户在移动盘子过程中,不允许把大盘子放在小盘子的上面,用户最终要完成的是把A塔上的全部盘子移动到B塔或C塔上。用户可以通过单击Hannoi塔界面上提供的按钮,让程序自动完成把A塔上的盘子全部移动到B塔或C塔上。用户在移动盘子的过程中,可以随时单击Hannoi塔界面上提供的按钮,重新开始游戏。2.测试结果七.小结通过着为期两天的时间,我学到了很多,自然在这期间遇到的困难数不胜数,开始最让我没辙的是题目不知道该订什么好,想过很多个题目但往往跟其他同学重复了,为了避免做出来的东西雷同了,只能继续想其他方面的,想过去做些复杂的,但实在是能力有限,,最后我们小组终于决定做这个Hannoi塔游戏.这个Hannoi塔游戏就是在原有的程序基础上增加了改变盘子数目功能、改变盘子大小功能、改变背景颜色功能、改变盘子颜色功能、计时器功能以及保存信息到文件功能,由于是在原有的基础上修改的,虽然理论上那个来讲这应该很简单,不会太难,但当我真正着手做起来得时候才发现,原来自己还是太嫩,刚开始什么都不懂,于是我们就去网上参阅了大量的资料,也不停的向同学们请教,终于渐渐的让我从刚开始连如何运行程序,甚至类的作用等一些罪基本的东西都不清楚到最后通过努力终于把这个程序成功搞定.自然这期间除了辛苦也让我明白了很多,有些小问题也是不容忽视的,就如公共类只能有一个,而且必须要有.及类名必须要同公共类名相同.否则程序就无法运行.经过编写这个Hannoi塔游戏,我们认识到应该注意细节问题,虽然是很小的问题,但可以提高自己编程的能力,而且还可以培养自己编程的严谨性,同时还可以为以后的编程积累经验。除此之外让我们对java变成语言又有了更深一步的了解,曾经对于一些类名的似是而非,现在通过编写这个程序让我逐渐变得明朗一些了,至少可以分清父类子类,以及一些类和方法的用途,当然这些都离不开小组成员的分工合作,总之通过这次课程设计,我们真的学到了很多.八.参考文献[1]苏仕民.数据结构课程设计北京:机械工业出版社.2005参考书:[2]SartajSahni.DataStructure,Algorithms,andApplicationinC++.TheMcGraw-HillCompanyInc.1998[M](第一版)(数据结构、算法与应用——C++语言描述.北京:机械工业出版社.1999[3]WillanFord,WillianTopp.DataStructureswithC++.NewJersey:PrenticeHallInc,AdivisionSimon&SchusterCompany,1996[M](第一版)(数据结构——C++语言描述.北京:清华大学出版社,1997[4]徐孝凯.数据结构实用教程(C/C++描述)[M].(第一版)北京:清华大学出版社.1999[5]陈慧南.数据结构(使用C++语言描述)[M].(第一版)南京:东南大学出版社.2001[6]殷人昆,陶永雷,谢若阳等.数据结构(用面向对象方法与C++描述)[M].(第一版)北京:清华大学出版社.1999九.程序代码1.主类/***@(#)Tower.java***@author*@version1.002014/12/29*/importjavax.swing.*;importjava.awt.*;importjava.awt.event.*;publicclassTowerextendsFrameimplementsActionListener,Runnable{HannoiTowertower=null;Buttonrenew,auto=null;chartowerName[]={'A','B','C'};int盘子数目,盘宽,盘高;Threadthread;TextArea信息条=null;publicTower(){thread=newThread(this);盘子数目=5;盘宽=80;盘高=18;信息条=newTextArea(12,12);信息条.setText(null);tower=newHannoiTower(盘子数目,盘宽,盘高,towerName,信息条);renew=newButton("重新开始");auto=newButton("自动演示搬盘子");renew.addActionListener(this);auto.addActionListener(this);add(tower,BorderLayout.CENTER);add(renew,BorderLayout.SOUTH);add(auto,BorderLayout.NORTH);add(信息条,BorderLayout.EAST);addWindowListener(newWindowAdapter(){ publicvoidwindowClosing(WindowEvente){ System.exit(0);}});setVisible(true);setBounds(60,20,670,540);validate();}publicvoidactionPerformed(ActionEvente){if(e.getSource()==renew){if(!(thread.isAlive())){this.remove(tower);信息条.setText(null);tower=newHannoiTower(盘子数目,盘宽,盘高,towerName,信息条);add(tower,BorderLayout.CENTER);validate();}else{}}if(e.getSource()==auto){if(!(thread.isAlive())){thread=newThread(this);}try{thread.start();}catch(Exceptioneee){}}}publicvoidrun(){this.remove(tower);信息条.setText(null);tower=newHannoiTower(盘子数目,盘宽,盘高,towerName,信息条);add(tower,BorderLayout.CENTER);validate();tower.自动演示搬运盘子(盘子数目,towerName[0],towerName[1],towerName[2]);}publicstaticvoidmain(Stringargs[]){newTower();}}2./***@(#)HannoiTower.java***@author*@version1.002014/12/29*/importjavax.swing.*;importjava.awt.*;importjava.awt.event.*;publicclassHannoiTowerextendsJPanelimplementsMouseListener,MouseMotionListener{TowerPointpoint[];intx,y;booleanmove=false;Disk盘子[];intstartX,startY;intstartI;int盘子数目=0;intwidth,height;chartowerName[]={'A','B','C'};TextArea信息条=null;publicHannoiTower(intnumber,intw,inth,char[]name,TextAreatext){towerName=name;盘子数目=number;width=w;height=h;信息条=text;setLayout(null);addMouseListener(this);addMouseMotionListener(this);盘子=newDisk[盘子数目];point=newTowerPoint[3*盘子数目];intspace=20;for(inti=0;i<盘子数目;i++){point[i]=newTowerPoint(40+width,100+space,false);space=space+height;}space=20;for(inti=盘子数目;i<2*盘子数目;i++){point[i]=newTowerPoint(160+width,100+space,false);space=space+height;}space=20;for(inti=2*盘子数目;i<3*盘子数目;i++){point[i]=newTowerPoint(280+width,100+space,false);space=space+height;}inttempWidth=width;intsub=(int)(tempWidth*0.2);for(inti=盘子数目-1;i>=0;i--){盘子[i]=newDisk(i,this);盘子[i].setSize(tempWidth,height);tempWidth=tempWidth-sub;}for(inti=0;i<盘子数目;i++){point[i].放置盘子(盘子[i],this);if(i>=1)盘子[i].set上方有盘(true);}}publicvoidpaintComponent(Graphicsg){super.paintComponent(g);g.drawLine(point[0].getX(),point[0].getY(),point[盘子数目-1].getX(),point[盘子数目-1].getY());g.drawLine(point[盘子数目].getX(),point[盘子数目].getY(),point[2*盘子数目-1].getX(),point[2*盘子数目-1].getY());g.drawLine(point[2*盘子数目].getX(),point[2*盘子数目].getY(),point[3*盘子数目-1].getX(),point[3*盘子数目-1].getY());g.drawLine(point[盘子数目-1].getX()-width,point[盘子数目-1].getY(),point[3*盘子数目-1].getX()+width,point[3*盘子数目-1].getY());intleftx=point[盘子数目-1].getX()-width;intlefty=point[盘子数目-1].getY();intw=(point[3*盘子数目-1].getX()+width)-(point[盘子数目-1].getX()-width);inth=height/2;g.setColor(Color.orange);g.fillRect(leftx,lefty,w,h);g.setColor(Color.red);intsize=4;for(inti=0;i<3*盘子数目;i++){g.fillOval(point[i].getX()-size/2,point[i].getY()-size/2,size,size);}g.drawString(""+towerName[0]+"塔",point[盘子数目-1].getX(),point[盘子数目-1].getY()+30);g.drawString(""+towerName[1]+"塔",point[2*盘子数目-1].getX(),point[盘子数目-1].getY()+30);g.drawString(""+towerName[2]+"塔",point[3*盘子数目-1].getX(),point[盘子数目-1].getY()+30);g.drawString("将全部盘子从"+towerName[0]+"塔搬运到"+towerName[1]+"塔或"+towerName[2]+"塔",point[盘子数目-1].getX(),point[盘子数目-1].getY()+80);}publicvoidmousePressed(MouseEvente){Disk盘子=null;Rectanglerect=null;if(e.getSource()==this)move=false;if(move==false)if(e.getSource()instanceofDisk){盘子=(Disk)e.getSource();startX=盘子.getBounds().x;startY=盘子.getBounds().y;rect=盘子.getBounds();for(inti=0;i<3*盘子数目;i++){intx=point[i].getX();inty=point[i].getY();if(rect.contains(x,y)){startI=i;break;}}}}publicvoidmouseMoved(MouseEvente){}publicvoidmouseDragged(MouseEvente){Diskdisk=null;if(e.getSource()instanceofDisk){disk=(Disk)e.getSource();move=true;e=SwingUtilities.convertMouseEvent(disk,e,this);}if(e.getSource()==this){if(move&&disk!=null){x=e.getX();y=e.getY();if(disk.get上方有盘()==false)disk.setLocation(x-disk.getWidth()/2,y-disk.getHeight()/2);}}}publicvoidmouseReleased(MouseEvente){Diskdisk=null;move=false;Rectanglerect=null;if(e.getSource()instanceofDisk){disk=(Disk)e.getSource();rect=disk.getBounds();e=SwingUtilities.convertMouseEvent(disk,e,this);}if(e.getSource()==this){booleancontainTowerPoint=false;intx=0,y=0;intendI=0;if(disk!=null){for(inti=0;i<3*盘子数目;i++){x=point[i].getX();y=point[i].getY();if(rect.contains(x,y)){containTowerPoint=true;endI=i;break;}}}if(disk!=null&&containTowerPoint){if(point[endI].是否有盘子()==true){disk.setLocation(startX,startY);}else{if(endI==盘子数目-1||endI==2*盘子数目-1||endI==3*盘子数目-1){point[endI].放置盘子(disk,this);if(startI!=盘子数目-1&&startI!=2*盘子数目-1&&startI!=3*盘子数目-1){(point[startI+1].获取盘子()).set上方有盘(false);point[startI].set有盘子(false);}else{point[startI].set有盘子(false);}}else{if(point[endI+1].是否有盘子()==true){DisktempDisk=point[endI+1].获取盘子();if((tempDisk.getNumber()-disk.getNumber())>=1){point[endI].放置盘子(disk,this);if(startI!=盘子数目-1&&startI!=2*盘子数目-1&&startI!=3*盘子数目-1){(point[startI+1].获取盘子()).set上方有盘(false);point[startI].set有盘子(false);tempDisk.set上方有盘(true);}else{point[startI].set有盘子(false);tempDisk.set上方有盘(true);}}else{disk.setLocation(startX,startY);}}else{disk.setLocation(startX,startY);}}}}if(disk!=null&&!containTowerPoint){disk.setLocation(startX,startY);}}}publicvoidmouseEntered(MouseEvente){}publicvoidmouseExited(MouseEvente){}publicvoidmouseClicked(MouseEvente){}publicvoid自动演示搬运盘子(int盘子数,charone,chartwo,charthree){if(盘子数==1){信息条.append(""+one+"到:"+three+"塔\n");Diskdisk=在塔中获取最上面的盘子(one);intstartI=在塔中获取最上面盘子的位置(one);intendI=在塔中获取最上面盘子的上方位置(three);if(disk!=null){point[endI].放置盘子(disk,this);point[startI].set有盘子(false);try{Thread.sleep(1000);}catch(Exceptionee){}}}else{自动演示搬运盘子(盘子数-1,one,three,two); 信息条.append(""+one+"到:"+three+"塔\n");Diskdisk=在塔中获取最上面的盘子(one);intstartI=在塔中获取最上面盘子的位置(one);intendI=在塔中获取最上面盘子的上方位置(three);if(disk!=null){point[endI].放置盘子(disk,this);point[startI].set有盘子(false);try{Thread.sleep(1000);}catch(Exceptionee){}} 自动演示搬运盘子(盘子数-1,two,one,three);}}publicDisk在塔中获取最上面的盘子(char塔名){Diskdisk=null;if(塔名==towerName[0]){for(inti=0;i<盘子数目;i++){if(point[i].是否有盘子()==true){disk=point[i].获取盘子();break;}}}if(塔名==towerName[1]){for(inti=盘子数目;i<2*盘子数目;i++){if(point[i].是否有盘子()==true){disk=point[i].获取盘子();break;}}}if(塔名==towerName[2]){for(inti=2*盘子数目;i<3*盘子数目;i++){if(point[i].是否有盘子()==true){disk=point[i].获取盘子();break;}}}returndisk;}publicint在塔中获取最上面盘子的上方位置(char塔名){intposition=0;if(塔名==towerName[0]){inti=0;for(i=0;i<盘子数目;i++){if(point[i].是否有盘子()==true){position=Math.max(i-1,0);break;}}if(i==盘子数目){position=盘子数目-1;}}if(塔名==towerName[1]){inti=0;for(i=盘子数目;i<2*盘子数目;i++){if(point[i].是否有盘子()==true){position=Math.max(i-1,0);break;}}if(i==2*盘子数目){position=2*盘子数目-1;}}if(塔名==towerName[2]){inti=0;for(i=2*盘子数目;i<3*盘子数目;i++){if(point[i].是否有盘子()==true){position=Math.max(i-1,0);break;}}if(i==3*盘子数目){position=3*盘子数目-1;}}returnposition;}publicint在塔中获取最上面盘子的位置(char塔名){intposition=0;if(塔名==towerName[0]){inti=0;for(i=0;i<盘子数目;i++){if(point[i].是否有盘子()==true){position=i;

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论