实验课程名称:___软件工程基本实验____________
实验项目名称 |
结对编程 |
实验成绩 |
|
||
实 验 者 |
余凡 |
专业班级 |
软件1501 |
组 别 |
|
同 组 者 |
张旭东 |
实验日期 |
2017年8月 5日 |
||
第一部分:实验预习报告(包括实验目的、意义,实验基本原理与方法,主要仪器设备及耗材,实验方案与技术路线等) 一、 实验内容 1)选择一个程序实例,练习结对编程(pairprogramming)实践; 2)要求学生两人一组,自由组合。每组使用一台计算机,二人共同编码,完成实验要求。 3)要求在结对编程工作期间,两人的角色至少切换 4 次; 4)编程语言不限,版本不限。建议使用Python 或JAVA进行编程。 二、 实验目的与意义 1)体验敏捷开发中的两人合作。 2)进一步提高个人编程技巧与实践 三、 实验基本原理和方法 实验选择的是问题(一):生死游戏。根据游戏的规则,如果一个细胞周围有3 个细胞为生,则该细胞为生;如果一个细胞周围有2 个细胞为生,则该细胞的生死状态保持不变;在其它情况下,该细胞为死。主要仪器设备及耗材 该程序分为四个类:lifegame、jindianmoshi、suijimoshi、jiemian。 Lifegame是入口类,该类中包括最初的界面以及功能。该界面中存在两个按钮,分别是随机模式和经典模式提供给用户选择。并且有一个标签作为介绍这两个模式的特点。按钮“经典模式”的事件监听是创建jindianmoshi类的对象并加到框架对象world中,按钮“随机模式”的事件监听是创建一个新的jiemian类对象。核心代码如下: lifegame(){ this.setSize(630,600); this.setTitle("生命游戏"); this.setLayout(null); this.add(jb); this.add(bu1); this.add(bu2); bu1.setSize(100, 100); bu1.setLocation(100, 100); bu2.setSize(100,100); bu2.setLocation(100, 300); jb.setSize(500,200); jb.setLocation(300,100); bu1.addActionListener(this); bu2.addActionListener(this); this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); this.setLocationRelativeTo(null); this.setResizable(false); } Jindianmoshi类继承于JFrame类,是被作为面板加到Lifegame类中的一个world框架上,经典模式是我们在程序里面已经设定好了图案(我们设计的是两个小鱼的图案)。具体实现方法:我们用数组world[][]来存储每个细胞的存亡情况,1则表示活着,0表示死去。设定一个计时器,而且每计时一次就要重新填写矩阵和重新画图。实现代码如下: timer = new Timer(DELAY_TIME, new ActionListener() { public void actionPerformed(ActionEvent e) { changeCellStatus(); repaint(); } }); timer.start(); 画图的函数为protected void paintComponent(Graphics g),该函数的功能是根据矩阵world来画图,矩阵world中为1的元素画成黑色,而矩阵中为0的元素画成白色。具体代码如下: protected void paintComponent(Graphics g) { super.paintComponent(g); for (int i = 1; i < nextStatus.length-1; i++) { for (int j = 1; j < nextStatus[i].length-1; j++) { if (nextStatus[i][j] == 1) { g.fillRect( j * width, i * height, width, height);
} else { g.drawRect( j * width, i * height, width, height); } } } } 因为计时器每计时一次矩阵都要变化一次,所以我们需要一个函数来变动矩阵,该函数为public void changeCellStatus(),变化的规则就如题中所述一样,但是会出现一个问题就是边缘的点不好计算,所以我们决定将周边一圈的点全部设置为0,而且不做显示。具体代码如下: public void changeCellStatus() { int flag = 0; for (int row = 1; row < nextStatus.length-1; row++) { for (int col = 1; col < nextStatus[row].length-1; col++) { flag = 0; for(int i=row-1; i<=row+1; i++) for(int j=col-1; j<=col+1; j++) { if(i==row && j==col) continue; if(tempStatus[i][j]==1) flag++; } switch (flag) { case 0: case 1: case 4: case 5: case 6: case 7: case 8: nextStatus[row][col] = 0; break; case 2: nextStatus[row][col] = tempStatus[row][col]; break; case 3: nextStatus[row][col] = 1; break; } } } copyWorldMap(); }
Jiemian类是随机模式的一个入口,因为随机模式需要用户自己输入速度,所以这个类是一个中间类的作用,为了防止用户不知道该输入多少,所以给予一定的输入提示。在程序中还必要加上错误处理,如果用户输入的数字范围不对或者输入的不是数字,就要结束程序。一切完成后,创建一个新的框架,再为新的框架添加面板new suijimoshi(speed)。该类中最核心的部分就是判断输入的对错以及添加新的面板对象。核心代码如下: String speed = Speed.getText(); if(!isNumeric(speed) || speed == null || speed.length()<=0) { System.exit(0); } int speed1 = Integer.parseInt(speed); // System.out.println(speed1); if(speed1<=2200 && speed1>=0) { world.add(new suijimoshi(speed1)); world.setVisible(true);} else { System.exit(0); } suijimoshi类是随机模式的类,这是一个面板类的子类,被添加与jiamian类中的一个框架变量,该类中大部分与jindianmoshi类相同,所以我们在这里只阐述与jindianmoshi类不同的地方。 首先,该类中最初的地图是由系统随机生成的,而不是设定好的,具体代码如下: for(int i=1; i<world.length-1; i++) for(int j=1; j<world.length-1; j++) { Random r = new Random(); int suiji = r.nextInt(2); world[i][j] = suiji; } for(int i=0; i<world.length; i++) {world[i][0] = 0; world[i][world.length-1] = 0;} for(int j=0; j<world.length; j++) {world[0][j] = 0; world[world.length-1][j] = 0;}
for (int row = 0; row < world.length; row++) { for (int col = 0; col < world[0].length; col++) { nextStatus[row][col] = world[row][col]; tempStatus[row][col] = world[row][col]; } } 其次他的颜色每次都会发生变化,所以我在画图的函数中加入了颜色的变化,具体代码如下: for (int i = 1; i < nextStatus.length-1; i++) { for (int j = 1; j < nextStatus[i].length-1; j++) { if (nextStatus[i][j] == 1) { Color color = new Color(0,0,0); Random ran = new Random(); color = new Color((int)(ran.nextFloat()*255),(int)(ran.nextFloat()*255),(int)(ran.nextFloat()*255)); g.setColor(color); g.fillRect( j * width, i * height, width, height);
} else { g.drawRect( j * width, i * height, width, height); } }
四、 实验仪器设备及耗材 PC机,Eclipse 五、 结对编程照片 |
|||||
第二部分:实验过程记录(可加页)(包括实验原始数据记录,实验现象记录,实验过程发现的问题等) 一、实验数据和现象记录 因为我们制作的程序有两种模式:随机模式和经典模式。两种模式都不需要人工输入。随机模式的速度是可以选择的,这种模式所有的点都是电脑随机生成的,而且每变化一次都会有颜色上的变化。而经典模式则是最先生成两条小鱼,随后让他们变化。 二、实验过程中发现的问题 实验虽然已经被完成,但是实验过程中还是有一些错误。下面我们来总结一下: 1. 最初开始的时候我们将界面、逻辑部分全部放于一个类,这样做一不符合独立性的特点,二也给自己的编程带来了麻烦,看的很不清晰。 2. 最先计算周围细胞存活个数的时候,我没有考虑到边缘和角落的棋子,导致程序运行的时候出现了数组越界的情况。后来经过我们组的讨论,决定将周围一圈空出来,赋值为0,这样既解决了越界问题,又不会影响计算细胞数。 3. 随机模式中用户填写速度出现了错误。因为我们缺少了错误判断,当用户属于错误的信息时程序就会出现异常,停止操作。所以我们后来加入了错误判断,主要包括两个方面,一个是数字范围,还有一个是输入必须是数字。否则都会报错。 4. 随机模式中设置随机细胞位置的时候最开始使用的是r.nextInt(1),我们误以为这是可以生成0或者1的,但实际上这只能生成0,后来经过我们查阅资料,知道r.nextInt(2)才是正确的编码。 5. 因为我们时间控制是DELAY_TIME越大速度越慢,而我们让用户选择时间的时候,用户会认为越大越快,所以我们后来用2400-speed赋值给DELAY_TIME 6. 为随机模式添加颜色的时候,开始将变换颜色的代码放在前面,这样做的结果:每张图虽与其他图的颜色不同,但是本身的颜色一致。之后我们加在为格子填色的循环里面,这样就使每张图的颜色变化多端。 教师签字__________ |
|||||
第三部分 结果与讨论(可加页) 一、 实验结果分析(包括数据处理、实验现象分析、影响因素讨论、综合分析和结论等) 1. 实验现象 主界面: 随机模式中提示用户填写速度: 随机模式的界面: 经典模式前两个时刻: 2. 影响因素分析 该游戏的影响因素有很多,主要包括以下几个方面: 第一, 对于边缘的点要考虑上并不是八个细胞,而是少于八个细胞。注意溢出的问题。 第二, 用户输入的部分一定要加上错误处理,否则会出错,甚至程序崩溃。 3. 结论 经过我们两人的测试,发现结果可以到达老师的要求而且能够正常运行。所以该代码是正确可行的。 二、 小结、建议及体会 我们学习计算机的时间有两年了,也编写了不少的程序,但是我们之前编写程序无论大小都是一个人独立完成,这次的实验是结对编程。结对编程就是要两个人同时使用同一台电脑,一起来完成任务。这对于我们俩都是第一次,也算是一个考验。 实验中遇到了不少的困难,具体的在上面的“实验中发现的问题”中已经叙述,我们二人在解决这些困难的时候也有一些争论,但是这些个问题都被我们一一解决了,而且完成的还算可以。经过这次实验,我们不仅提高了各自的编码能力,而且都对合作的重要性有了更高层次的认识,所以这次试验对我们的帮助还是很大的。 |