Java课程设计报告(汉诺塔)

更新时间:2024-05-09 12:15:01 阅读量: 综合文库 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

东华理工大学理学院信计Java课程设计

东华理工大学

Java课程设计报告

题 目 : 汉诺塔

所在院系: 理学院

学生姓名: 漆俊、朱学曼、颜瑶

专 业: 信息与计算科学

班 级:1223201-2

指导老师:黄国辉

2014年 12月29日

- 1 -

东华理工大学理学院信计Java课程设计

目录

一. 概述

1. 题目概述 2. 题目分析

二. 课程设计

1.课程设计目的 2.课程设计内容 3.课程设计环境 4.课程设计要求

三.系统需求分析

1.系统目标

2.主体功能 3.开发环境

四.系统概要设计

1.系统功能模块划分2.流程图

3.自定义类说明

五.系统详细设计 六.测试

1. 测试方案 2. 测试结果

七.小结 八.参考文献 九. 程序代码

- 2 -

东华理工大学理学院信计Java课程设计

一.概述

1. 题目概述:

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程序设计的设计目的是加深对理论教学内容的理解和掌握,使学生较系

- 3 -

东华理工大学理学院信计Java课程设计

统地掌握程序设计及其在网络开发中的广泛应用,基本方法及技巧,为学生综合运用所学知识,利用软件工程为基础进行软件开发、并在实践应用方面打下一定基础。

2. 课程设计内容

我设计的Hannoi塔,除了要编写的6个java文件所给出的类外,还需要java系统提供的一些重要的类,如JButton,JCheckBox等。汉诺塔中有三个座,名字分别为A,B,C。刚开始的时候A塔上有3个大小不等的盘子,这些盘子从座底到座顶按着大小顺序依次摆放在A座上。用户可以用鼠标选中盘子,然后通过拖动鼠标来移动盘子。释放鼠标来放置该盘子。程序要求用户在移动盘子的过程中,不允许吧大盘子放置在小盘子的上面,用户最终要完成的是把A座上的全部盘子移动到B座或C座上。用户可以通过Hannoi塔界面的提供的改变盘子数目功能来改变盘子的数目,同时可以改变盘子的大小以及改变盘子和界面的背景颜色,而且还可以选择控制背景音乐的播放。用户可以通过单击Hannoi塔界面上提供的按钮,让程序自动完成把A座上的盘子全部移动到C座上。用户在移动盘子的过程中,可以随时单击Hannoi塔界面上提供的按钮,重新开始。 3. 课程设计环境

硬件要求能运行Windows 9.X操作系统的微机系统。JAVA程序设计语言及相应的集成开发环境,J2SDK和ECLIPSE开发工具。

4. 课程设计要求

按课程设计指导书提供的课题,要求学生在自行完成各个操作环节,并能实现且达到举一反三的目的,完成一个项目解决一类问题。要求学生能够全面、深入理解和熟练掌握所学内容,并能够用其分析、设计和解答类似问题;对此能够较好地理解和掌握,能够进行简单分析和判断;能编写出具有良好风格的程序;掌握JAVA程序设计的基本技能和面向对象的概念和方法;了解多线程、安全和网络等编程技术。同时培养学生进行分析问题、解决问题的能力;培养学生进行设计分析、设计方法、设计操作与测试、设计过程的观察、理解和归纳能力的提高。

三.系统需求分析

- 4 -

东华理工大学理学院信计Java课程设计

1. 系统目标

所设计代码可以正常运行程序,并且按照设计目的预想的完成具体功能。

2. 主体功能

(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. 系统功能模块划分

(1)Tower.java(主类)

Tower类负责创建Hannoi塔的主窗口,该类含有main方法,Hannoi塔从类开始执行。Tower类的成员变量中有两种重要类型的对象:一个int基本型数据和一个char型数组。两种类型的对象分别是:HannoiTower和Button对象 。 (2)HannoiTower.java

HannoiTower类是javax.swing包中JPanel容器的子类,创建的容器被添加到

- 5 -

东华理工大学理学院信计Java课程设计

Tower窗口的中心。HannoiTower类的成员变量有两种重要类型的对象、一个int基类型数据和一个char型数组。两种类型的对象分别是:Disk、TowerPoint。 (3)TowerPoint.java

TowerPoint类负责在HannoiTower中创建表示位置的塔点对象。 (4)Disk.java

Disk类是Button的一个子类,创建的对象是HannoiTower容器中的一个按钮,用来表示HannoiTower中的盘子。

2. 流程图(图4-1) 3. 自定义类说明

(1)自定义类 类名: JButton

作用: 自定义主类, 实现圆盘的类Disc继承JButton类 继承的父类: Disc类 实现的接口: 没有

(2)成员变量 JButton成员变量 成员变量描述 控制盘子数目 重新开始 开始游戏 背景颜色 盘子颜色

(3)方法表

- 6 -

变量类型 String String String String String JLabel 名称 renew.setText renew.setText bgcolor pzcolor 东华理工大学理学院信计Java课程设计

Chesspad方法 方法名 fillRect() g.fillOval() drawString() setBackground() Timer(int a,Object b) stop() write actionPerformed evaluate 功能 绘制出矩形区域 绘制相同数目点 绘制出A、B、C座 创建一个计时器 停止计时器计时 保存文件 事件处理 评估 设置背景颜色和盘子颜色 备注 构造方法 构造方法 构造方法 构造方法 构造方法 接口方法 接口方法 五.系统详细设计

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事件监视器。 ② 方法

- 7 -

东华理工大学理学院信计Java课程设计

开始 是否自动搬移 否 是 是否正在移动 否 是否点中某个塔 是 否 是否已定义起始塔 是 退出 退出 否 退出 是 否 塔上是否有盘 是 是否起始塔 否 是 该塔顶盘是否比欲移动盘大 是 消息框报错 定义当前塔为起始塔,并将塔顶盘设为蓝色 取消起始塔定义,并将塔顶盘设为黄色 退出 退出 否 消息框报错 定义为目标塔,调MovePlate函数,将起始塔顶的金盘移动到目标塔顶。 退出 退出 退出 图4-1

- 8 -

东华理工大学理学院信计Java课程设计

Tower()是构造方法,负责完成窗口的初始化。 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.测试结果

- 9 -

东华理工大学理学院信计Java课程设计

- 10 -

东华理工大学理学院信计Java课程设计

int space=20;

for(int i=0;i<盘子数目;i++)

{ point[i]=new TowerPoint(40+width,100+space,false); space=space+height; }

space=20;

for(int i=盘子数目;i<2*盘子数目;i++)

{ point[i]=new TowerPoint(160+width,100+space,false); space=space+height; }

space=20;

for(int i=2*盘子数目;i<3*盘子数目;i++)

{ point[i]=new TowerPoint(280+width,100+space,false); space=space+height; }

int tempWidth=width;

int sub=(int)(tempWidth*0.2); for(int i=盘子数目-1;i>=0;i--) { 盘子[i]=new Disk(i,this);

盘子[i].setSize(tempWidth,height); tempWidth=tempWidth-sub; }

for(int i=0;i<盘子数目;i++)

{ point[i].放置盘子(盘子[i],this); if(i>=1)

盘子[i].set上方有盘(true); } }

public void paintComponent(Graphics g) { 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()); int leftx=point[盘子数目-1].getX()-width;

- 16 -

东华理工大学理学院信计Java课程设计

int lefty=point[盘子数目-1].getY();

int w=(point[3*盘子数目-1].getX()+width)-(point[盘子数目-1].getX()-width); int h=height/2;

g.setColor(Color.orange); g.fillRect(leftx,lefty,w,h); g.setColor(Color.red); int size=4;

for(int i=0;i<3*盘子数目;i++)

{ g.fillOval(point[i].getX()-size/2,point[i].getY()-size/2,size,size); }

g.drawString(\塔\盘子数目-1].getX(),point[盘子数目-1].getY()+30);

g.drawString(\塔\盘子数目-1].getX(),point[盘子数目-1].getY()+30);

g.drawString(\塔\盘子数目-1].getX(),point[盘子数目-1].getY()+30);

g.drawString(\将全部盘子从\塔搬运到\塔或\塔\盘子数目-1].getX(),point[盘子数目-1].getY()+80); }

public void mousePressed(MouseEvent e) { Disk 盘子=null; Rectangle rect=null; if(e.getSource()==this) move=false; if(move==false)

if(e.getSource() instanceof Disk) { 盘子=(Disk)e.getSource(); startX=盘子.getBounds().x; startY=盘子.getBounds().y; rect=盘子.getBounds();

for(int i=0;i<3*盘子数目;i++) { int x=point[i].getX(); int y=point[i].getY(); if(rect.contains(x,y)) { startI=i; break; } } }

- 17 -

东华理工大学理学院信计Java课程设计

}

public void mouseMoved(MouseEvent e) { }

public void mouseDragged(MouseEvent e) { Disk disk=null;

if(e.getSource() instanceof Disk) { 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); } } }

public void mouseReleased(MouseEvent e) { Disk disk=null; move=false;

Rectangle rect=null;

if(e.getSource() instanceof Disk) { disk=(Disk)e.getSource(); rect=disk.getBounds();

e=SwingUtilities.convertMouseEvent(disk,e,this); }

if(e.getSource()==this)

{ boolean containTowerPoint=false; int x=0,y=0; int endI=0; if(disk!=null)

{ for(int i=0;i<3*盘子数目;i++) { x=point[i].getX(); y=point[i].getY(); if(rect.contains(x,y))

{ containTowerPoint=true; endI=i;

- 18 -

东华理工大学理学院信计Java课程设计

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)

{ Disk tempDisk=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); }

- 19 -

东华理工大学理学院信计Java课程设计

} else

{disk.setLocation(startX,startY); } } } }

if(disk!=null&&!containTowerPoint) { disk.setLocation(startX,startY);} } }

public void mouseEntered(MouseEvent e) { }

public void mouseExited(MouseEvent e) { }

public void mouseClicked(MouseEvent e) { }

public void 自动演示搬运盘子(int 盘子数,char one,char two,char three) { if(盘子数==1)

{ 信息条.append(\到: \塔\\n\ Disk disk=在塔中获取最上面的盘子(one); int startI=在塔中获取最上面盘子的位置(one);

int endI=在塔中获取最上面盘子的上方位置(three); if(disk!=null)

{ point[endI].放置盘子(disk,this); point[startI].set有盘子(false); try

{ Thread.sleep(1000); }

catch(Exception ee) { } } } else

{ 自动演示搬运盘子(盘子数-1,one,three,two); 信息条.append(\到: \塔\\n\ Disk disk=在塔中获取最上面的盘子(one); int startI=在塔中获取最上面盘子的位置(one);

int endI=在塔中获取最上面盘子的上方位置(three); if(disk!=null)

{ point[endI].放置盘子(disk,this);

- 20 -

东华理工大学理学院信计Java课程设计

point[startI].set有盘子(false); try

{ Thread.sleep(1000); }

catch(Exception ee) { } }

自动演示搬运盘子(盘子数-1,two,one,three); } }

public Disk 在塔中获取最上面的盘子(char 塔名) { Disk disk=null;

if(塔名==towerName[0])

{ for(int i=0;i<盘子数目;i++)

{ if(point[i].是否有盘子()==true) { disk=point[i].获取盘子(); break; } } }

if(塔名==towerName[1])

{ for(int i=盘子数目;i<2*盘子数目;i++) { if(point[i].是否有盘子()==true) { disk=point[i].获取盘子(); break; } } }

if(塔名==towerName[2])

{ for(int i=2*盘子数目;i<3*盘子数目;i++) { if(point[i].是否有盘子()==true) { disk=point[i].获取盘子(); break; } } }

return disk; }

public int 在塔中获取最上面盘子的上方位置(char 塔名) { int position=0;

- 21 -

东华理工大学理学院信计Java课程设计

if(塔名==towerName[0]) { int i=0;

for(i=0;i<盘子数目;i++)

{ if(point[i].是否有盘子()==true) { position=Math.max(i-1,0); break; } }

if(i==盘子数目)

{ position=盘子数目-1;} }

if(塔名==towerName[1]) { int i=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]) { int i=0;

for(i=2*盘子数目;i<3*盘子数目;i++) { if(point[i].是否有盘子()==true) { position=Math.max(i-1,0); break; } }

if(i==3*盘子数目)

{ position=3*盘子数目-1; } }

return position; }

public int 在塔中获取最上面盘子的位置(char 塔名) { int position=0;

if(塔名==towerName[0]) { int i=0;

- 22 -

东华理工大学理学院信计Java课程设计

for(i=0;i<盘子数目;i++)

{ if(point[i].是否有盘子()==true) { position=i; break; } }

if(i==盘子数目)

{ position=盘子数目-1; } }

if(塔名==towerName[1]) { int i=0;

for(i=盘子数目;i<2*盘子数目;i++) { if(point[i].是否有盘子()==true) { position=i; break; } }

if(i==2*盘子数目)

{ position=2*盘子数目-1; } }

if(塔名==towerName[2]) { int i=0;

for(i=2*盘子数目;i<3*盘子数目;i++) { if(point[i].是否有盘子()==true) { position=i; break; } }

if(i==3*盘子数目)

{ position=3*盘子数目-1; } }

return position; } }

3.

/**

* @(#)Disk.java *

- 23 -

东华理工大学理学院信计Java课程设计

*

* @author

* @version 1.00 2014/12/29 */

import java.awt.*;

public class Disk extends Button { int number;

boolean 上方有盘=false;

public Disk(int number,HannoiTower con) { this.number=number;

setBackground(Color.blue); addMouseMotionListener(con); addMouseListener(con); }

public boolean get上方有盘() { return 上方有盘; }

public void set上方有盘(boolean b) { 上方有盘=b; } public int getNumber() { return number; } }

4.

/**

* @(#)TowerPoint.java * *

* @author

* @version 1.00 2014/12/29 */

import java.awt.*;

public class TowerPoint { int x,y;

boolean 有盘子; Disk 盘子=null;

HannoiTower con=null;

- 24 -

东华理工大学理学院信计Java课程设计

public TowerPoint(int x,int y,boolean boo) { this.x=x; this.y=y; 有盘子=boo; }

public boolean 是否有盘子() { return 有盘子; }

public void set有盘子(boolean boo) { 有盘子=boo; } public int getX() { return x; } public int getY() { return y; }

public void 放置盘子(Disk 盘子,HannoiTower con) { this.con=con;

con.setLayout(null); this.盘子=盘子; con.add(盘子);

int w=盘子.getBounds().width; int h=盘子.getBounds().height; 盘子.setBounds(x-w/2,y-h/2,w,h); 有盘子=true; con.validate(); }

public Disk 获取盘子() { return 盘子; } }

- 25 -

本文来源:https://www.bwwdw.com/article/7wag.html

Top