阶段一报告--18111107
目 录
1 选题 1
2 系统需求分析 2
2.1 系统可行性分析 2
2.2 系统需求分析 2
2.3 项目进度安排 5
3 系统设计 6
3.1 系统设计 6
3.2 文件设计 20
4 系统实现 21
4.1 简易计算器界面实现 21
5 系统测试 22
6 结论和心得 25
1 选题
|
选题一 |
猜数游戏 |
|
题目要求 |
|
|
计算机产生1-100随机数,与用户输入进行对比。猜中即胜,猜不中,提示是大了还是小了,给出范围(如第一次猜,随机数60,用户所猜40,提示用户猜的值偏小,范围40-100),继续猜,直至猜到,给出所用时间和次数,计算出分数。做出成绩排行榜,给出相应将奖励,排行榜存放到文件中。
|
|
|
使用Java知识 |
|
|
random()产生随机数、Scanner接受用户键盘输入的值、if-else对比用户猜数大小、Date()获得当前时间、getTime()获取毫秒数、do-while控制参赛人数,得到猜数次数、数组存储分数、sort()升序排列、for循环输出排名、OutputStream字节输出流、getByte()字符串打散为字节数组、write()写入文件。
|
|
|
选题二 |
简易计算机模拟程序 |
|
题目要求 |
|
|
仿照Windows计算器,编写一个具有GUI的计算器,能实现加、减、乘、除四则运算,平方、开方运算,倒数、百分号运算等。历次计算过程存放在文件中,再显示回控制台便于查看计算过程。具体参考windows计算器。
|
|
|
使用Java知识 |
|
|
GUI设计。面板JPanel、文本框JTextField、按钮JButton、各种布局(更改名字 颜色 字体 风格等)、String常用函数、字节输入输出流。
|
|
2 系统需求分析
2.1 系统可行性分析
猜数游戏:技术可行性、操作可行性----项目可行。
简易计算机模拟程序:技术可行性、操作可行性-----项目可行。
2.2 系统需求分析
调研对象:老师、同组同学、五组组长
猜数游戏:计算机生成1-100随机数,与用户输入进行对比,猜中即游戏结束,猜不中则提示用户所猜大或小,给出范围(如随机数60,用户所猜40,提示用户猜的数偏小,给出下次猜数范围40-100),让用户继续猜,直到猜中为止。记录用户猜的次数和时间,统计出成绩,排列做出排行榜,将排行榜放入文件,用户可根据分数查询自己获得的奖励。
简易计算器模拟程序:仿照Windows计算器,编写一个具有GUI的计算器,能实现加、减、乘、除四则运算,平方、开方运算,倒数、百分号运算等。历次计算过程保存放入文件中,再显示回控制台便于查看计算过程。

图2-1 猜数游戏程序流程图

图2-2 简易计算器程序流程图
2.3 项目进度安排
阶段一进度安排如表3-1所示。
表3-1 进度安排表
|
阶段 |
持续时间 |
阶段描述 |
输出 |
|
构思阶段 |
60min |
需求分析 |
需求说明,功能模块图 |
|
设计阶段 |
120min |
系统设计 |
设计说明-可以画流程图;数据库设计 |
|
实现阶段 |
两天 |
编写代码 |
项目工程源代码 |
|
120min |
系统测试 |
进行黑盒测试(功能测试)-测试说明 |
|
|
运行阶段 |
60min |
部署、运行 |
系统使用说明、运维报告、录制视频 |
3 系统设计
3.1 系统设计
猜数游戏
//接受用户键盘输入的值
Scanner input = new Scanner(System.in);
//记录猜数次数
int i = 0;
//记录参加人数
int n = 1;
//定义数组记录用户分数
double[] number = new double[4];
do {
//获取用户姓名,给用户一个参赛编码,方便后续查看分数
System.out.println("**********猜数游戏**********");
String name;
System.out.print("请输入您的姓名:");
name = input.next();
System.out.println("欢迎来到猜数游戏!");
System.out.println("您的姓名为:"+name+",您的参赛编码为:"+n);
//产生1-100之间随机数
int random = (int)(Math.random()*100+1);
//记录当前最大最小值,便于提示用户猜数范围
int min = 1;
int max = 100;
//输入的整数应在1-100之间
int num;
double score;
try {
//得到开始游戏时间 记录用户完成猜数游戏所用时间
Date date = new Date();
SimpleDateFormat formater = new SimpleDateFormat("HH:mm:ss");
String sdate = formater.format(date);
System.out.println("开始游戏时间为:"+sdate);
Date d1 = formater.parse(sdate);
//规定参加游戏人数(三人)
do {
System.out.print("输入"+min+"到"+max+"之间的整数:");
num = input.nextInt();
i++;
//比较用户输入整数大小
if(num>max || num<min) {
System.out.println("输入有误!");
}else if(num < random) {
System.out.println("猜错了!您猜的数偏小!");
System.out.print("请重新猜,");
min = num;
}else if(num > random) {
System.out.println("猜错了!您猜的数偏大!");
System.out.print("请重新猜,");
max = num;
}
//输出用户猜数次数
}while (num != random);
System.out.println("恭喜您猜对了!你猜了"+i+"次");
//得到结束游戏时间
SimpleDateFormat formater2 = new SimpleDateFormat("HH:mm:ss");
Date date2 = new Date();
String sdate2 = formater2.format(date2);
System.out.println("结束游戏时间为:"+sdate2);
Date d2 = formater2.parse(sdate2);
//得到时间是毫秒级别的
long s = (d2.getTime()-d1.getTime())/1000;
System.out.println("您完成猜数游戏所用时间:"+s+"秒");
//获得分数
//次数相同的情况下 比较时间 将时间/10+次数为最后分数
score = ((double)s/10)+i;
System.out.println("您的分数为:"+score);
number[n] = score;
i = 0;
n++;
} catch (ParseException e) {
e.printStackTrace();
}
}while(n<4);
System.out.println("*****************************");
System.out.println("人数已满!本游戏只允许三人参加!");
System.out.println("排名如下:");
for(n=1;n<=3;n++) {
System.out.println("参赛编码为:"+n+"的用户分数为:"+number[n]);
}
System.out.println("请根据参赛编码牢记你的分数,便于获取奖励!");
//将分数升序排列,分数少的名次高
Arrays.sort(number);
for(int j=1;j<=3;j++) {
System.out.println("第"+j+"名,分数:"+number[j]+"分");
}
//根据用户分数领取奖励
System.out.println("*****************************");
System.out.print("请输入你的分数,获取奖励:");
Double sc = input.nextDouble();
if(sc==number[1]) {
System.out.println("恭喜你!第一名!获得了十只钢笔!");
}else if(sc==number[2]) {
System.out.println("不错!你获得了第二名!获得了一支钢笔!");
}else {
System.out.println("第三名!再接再厉!没有奖励");
}
System.out.println();
System.out.println("游戏结束!");
//利用流输出到文件
FileOutputStream file = null;
try {
file = new FileOutputStream("D:\\java\\Z_End\\PaiMing.txt");
for(int j=1;j<=3;j++) {
String s = "第"+j+"名,分数:"+number[j]+"分";
//将字符串打散为一个字节数组
byte[] word = s.getBytes();
file.write(word, 0, word.length);
file.write("\n".getBytes());
}
System.out.println("排名已更新!");
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
//关闭流
file.close();
} catch (IOException e) {
e.printStackTrace();
}
}
简易计算器模拟程序
public class Calculator extends JFrame implements ActionListener {
//设置按钮名称
private String[] KEYS= {"+", "7", "8", "9", "平方", "-", "4", "5", "6", "√", "*", "1", "2", "3", "%", "/", ".", "0", "=", "1/x"};
//上方按钮显示清空后退功能
private String[] UP = {"C", "Back"};
//设置按钮数组
private JButton keys[] = new JButton[KEYS.length];
//设置上方功能按钮数组
private JButton ups[] = new JButton[UP.length];
//计算结果文本框
private JTextField textField = new JTextField("0");
//是否是开始的第一个数字或是运算符后的第一个数字
private boolean firstDigit = true;
//计算中间过程的结果
private double middle = 0.0;
//当前运算符
private String operator = "=";
//操作是否合法
private boolean flag = true;
//初始化后面要用到的信息
byte[] b;
String label;
FileOutputStream fos = null;
FileReader fr = null;
BufferedReader br = null;
//设置计算器外表
public Calculator() {
super();
//初始化计算器
init();
//设置背景颜色
this.setBackground(Color.LIGHT_GRAY);
//设置窗口标题
this.setTitle("简易计算器--张睿滢--18111107");
//设置窗口位置大小
this.setBounds(100, 100, 500, 300);
//弹出初始位置
this.setLocation(500, 300);
//设置固定窗口
this.setResizable(false);
}
//初始化计算器
public void init() {
//文本框中的内容向右对齐
textField.setHorizontalAlignment(JTextField.RIGHT);
//不允许修改文本框内容
textField.setEditable(false);
//设置文本框背景为白色
textField.setBackground(Color.WHITE);
//初始化面板
JPanel keyspanel = new JPanel();
//布局一个4行5列网格,网格之间的水平间隔8像素,垂直间隔8像素
keyspanel.setLayout(new GridLayout(4,5,8,8));
//将按钮数组循环添加在面板上 并设置为黑色
for(int i=0;i<keys.length;i++) {
keys[i] = new JButton(KEYS[i]);
keyspanel.add(keys[i]);
keys[i].setForeground(Color.BLACK);
//事件监听器
keys[i].addActionListener(this);
//设置字体风格字号
keys[i].setFont(new Font("黑体", Font.BOLD, 18));
}
//运算符用红键表示
keys[0].setForeground(Color.red);
keys[4].setForeground(Color.red);
keys[5].setForeground(Color.red);
keys[9].setForeground(Color.red);
keys[10].setForeground(Color.red);
keys[14].setForeground(Color.red);
keys[15].setForeground(Color.red);
keys[18].setForeground(Color.red);
keys[19].setForeground(Color.red);
//初始化功能键,都用红色标示。将功能键放在一个画板内
JPanel upsPanel = new JPanel();
//布局一个1行,2列的网格,网格之间的水平方向间隔为8个像素,垂直方向间隔为8个像素
upsPanel.setLayout(new GridLayout(1, 2, 8, 8));
//将上方按钮数组循环添加在面板上 并设置为蓝色
for (int i=0; i<UP.length; i++) {
ups[i] = new JButton(UP[i]);
upsPanel.add(ups[i]);
ups[i].setForeground(Color.BLUE);
//事件监听器
ups[i].addActionListener(this);
}
//新建一个大的面板,将上面建立的ups和keys放入该面板内
JPanel panel = new JPanel();
//设置面板里组件之间的水平和垂直间隔都为8象素
panel.setLayout(new BorderLayout(8, 8));
panel.add("North", upsPanel);
panel.add("Center", keyspanel);
//建立一个面板放文本框
JPanel top = new JPanel();
top.setLayout(new BorderLayout());
top.add("Center", textField);
//整体布局
getContentPane().setLayout(new BorderLayout(5,5));
getContentPane().add("North", top);
getContentPane().add("Center", panel);
}
//处理事件
public void actionPerformed(ActionEvent e) {
//获取事件源的标签
label = e.getActionCommand();
//用户按了"Back",调用函数
if(label.equals(UP[1])) {
handleBack();
//设置如果按下清空键 文件中的信息换行
}else if (label.equals(UP[0])) {
try {
fos = new FileOutputStream("D:\\java\\Z_End\\calculator.txt", true);
fos.write("\n".getBytes());
System.out.println("文件已更新!");
} catch (FileNotFoundException e1) {
e1.printStackTrace();
} catch (IOException e1) {
e1.printStackTrace();
} finally {
try {
fos.close();
} catch (IOException e1) {
e1.printStackTrace();
}
}
//用户按了"C",调用函数
handleC();
//indexOf()返回某个指定字符串值在字符串中出现的位置
}else if ("0123456789.".indexOf(label) >= 0) {
//用户按了数字键或者小数点键
handleNumber(label);
}else {
//用户按了运算符键
handleOperator(label);
//如果是"="以外的运算符号,显示在文本框上
if(label != String.valueOf("=")) {
textField.setText(label);
save();
}
}
}
//运算符
private void handleOperator(String key) {
if(operator.equals("/")) {
//除法
//如果当前结果文本框中的值等于0
if(getNumber() == 0.0) {
//操作不合法
flag = false;
textField.setText("除数不能为零");
}else {
middle /= getNumber();
}
}else if (operator.equals("1/x")) {
//倒数
if (middle == 0.0) {
//零没有倒数
flag = false;
textField.setText("零没有倒数");
}else {
middle = 1 / middle;
}
}else if (operator.equals("+")) {
//加法
middle += getNumber();
}else if (operator.equals("-")) {
//减法
middle -= getNumber();
}else if (operator.equals("*")) {
//乘法
middle *= getNumber();
}else if (operator.equals("√")) {
//开方
middle = Math.sqrt(middle);
}else if (operator.equals("%")) {
//百分号运算,除以100
middle = middle / 100;
}else if (operator.equals("平方")) {
//平方
middle = Math.pow(middle, 2);
}else if (operator.equals("=")) {
//赋值
middle = getNumber();
}
if (flag) {
//双精度浮点数
long t1;
double t2;
t1 = (long) middle;
t2 = middle - t1;
if (t2 == 0) {
//转化成String类型
textField.setText(String.valueOf(t1));
//文件中获得等号和结果
String s1 = "=" + t1;
b = s1.getBytes();
}else {
textField.setText(String.valueOf(middle));
String s1 = "=" + middle;
b = s1.getBytes();
}
}
try {
fos = new FileOutputStream("D:\\java\\Z_End\\calculator.txt", true);
fos.write(b);
System.out.println("文件已更新!");
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
//运算符等于用户按的按钮
operator = key;
firstDigit = true;
flag = true;
}
//数字键
private void handleNumber(String key) {
if(firstDigit) {
//输入第一个数字
textField.setText(key);
}else if ((key.equals(".")) && (textField.getText().indexOf(".") < 0)) {
//输入小数点,并且之前没有小数点,将小数点附在结果文本框的后面
textField.setText(textField.getText() + ".");
}else if (!key.equals(".")) {
//输入的不是小数点,则将数字附在结果文本框的后面
textField.setText(textField.getText() + key);
}
firstDigit = false;
save();
}
//C 清空文本框
private void handleC() {
//初始化计算器
textField.setText("0");
firstDigit = true;
operator = "=";
}
//Back 后退一步
private void handleBack() {
String text = textField.getText();
int i =text.length();
if(i>0) {
//退一步
text = text.substring(0, i-1);
if(i==0) {
//文本框没有内容,则初始化计算器的各种值
textField.setText("0");
firstDigit = true;
operator = "=";
}else {
//显示新的文本
textField.setText(text);
}
}
}
//从结果文本框中获取数字
private double getNumber() {
double result = 0;
try {
//valueOf()返回给定参数原生对象值
//doubleValue()将一个字符串转化成一个Double对象,赋给result
result = Double.valueOf(textField.getText()).doubleValue();
}catch (NumberFormatException e) {
}
return result;
}
public static void main(String[] args) {
Calculator calculator1 = new Calculator();
//让窗口显示出来
calculator1.setVisible(true);
//设置关闭窗口 退出JVM
calculator1.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
private void save() {
try {
//利用流输出到文件
String s = textField.getText();
fos = new FileOutputStream("D:\\java\\Z_End\\calculator.txt", true);
//将字符串打散为一个字节数组
byte[] word = s.getBytes();
fos.write(word);
System.out.println("文件已更新!");
//利用流读取文件到控制台
StringBuffer sb = new StringBuffer("");
fr = new FileReader("D:\\java\\Z_End\\calculator.txt");
br = new BufferedReader(fr);
String line = null;
while((line = br.readLine())!=null) {
sb.append(line+"\n");
System.out.println(line);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
//关闭流
fos.close();
fr.close();
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
3.2 文件设计
利用io流输出排行榜、运算过程到文件。

图3-1 猜数游戏文件

图3-2 简易计算器文件
4 系统实现
4.1 简易计算器界面实现
用户可通过简易计算器计算简单加减乘除 平方开方等运算,如图所示。

图4-1 简易计算器界面
5 系统测试





图5-1 猜数游戏系统测试
这里简易计算器输入文件有点小问题(真的不会改),但不影响观察运算过程


图5-2 简易计算器系统测试
经过测试,所有功能都符合需求分析并且均能正常实现。
6 结论和心得
心得:经过这几天阶段一的设计,我发现很多问题不需要想的太复杂,从简单出发也许会发现不一样的惊喜。以后要多进行代码设计练习,多熟悉代码,多了解一些方法,学会看帮助文档,不会的问题多向老师请教。对于设计代码,GUI这方面都是自己搜集资料学习,从设计一个计算器框架,再往里面填按钮文本框并设计好位置,再将这些匹配上相应的功能,再将计算过程变成一个整体输出到文件等等。可能还有很多不完善的地方,像第三题简易计算器做了很多天虽然输出正确了一部分但还是有很多不满意的地方,为了下一阶段的学习,还要自学很多东西。这次的两道题都是输出到文件,下一阶段要尝试一下数据库,找一些数据库的资料,多加学习。

浙公网安备 33010602011771号