结对编程第二阶段

一、实验目标
  1)体验敏捷开发中的两人合作。

  2)进一步提高个人编程技巧与实践。

二 、实验内容
  1)根据以下问题描述,练习结对编程(pair programming)实践;

  2)要求学生两人一组,自由组合。每组使用一台计算机,二人共同编码,完成实验要求。

  3)要求在结对编程工作期间,两人的角色至少切换 4 次;

  4)编程语言不限,版本不限。建议使用 Python 或 JAVA 进行编程。

博客内容应该包括:
1、代码规范
2、程序的总体设计(附图说明模块之间的关系)
3、程序结对编程过程(附图)及功能实现情况(附代码和图)
4、项目github地址(附图)
5、实验总结

三、实验过程及截图记录

1、代码规范

  虽说结对编程利大于弊,但对于我们这些代码掌握不牢靠的人来说,弊端还是很明显的。在来回交换角色的过程中,我跟李同学几次都不能与对方心有灵犀,几乎就是各写各的。因为疫情原因,我跟李同学分隔两地,通过语音电话实验结对编程,各有各的想法,各有各的追求,我们通过语音电话很混乱的表达自己的想法以及实现后的效果。在简单的代码的地方,每个人都想多写点,在复杂代码的地方,每个人又都只写两段。在来回三次艰难却愉快的写代码阶段完成之后,我们又来了一轮对代码的润滑和规范美化,其中包括了:

(1)因为英语单词的存储量有限,有的函数可以用英文单词命名,有的不知道英语单词的就用了拼音。所以在最后一次交换修改代码中,我们把所有的函数名都统一用拼音表示了,简单易明。

(2)在一个工程中,难免有大量的代码,尤其是不止一个人写代码的时候,这个时候为了让编程能力弱的人立马明白你写的代码,注释是一个很重要的条件。在我们合作的代码中,几乎行行都有代码的注释,首先是为了让对方能很快的明白自己想表达的意思,其次也是为了以后复盘的时候可以让自己更清晰。

(3)在编程中,有许多程序语言可以选择,根据我们自己的能力,我们在java、python、c/c++中选择了c/c++。在一个语言中,一种命令可以有多种执行方式,在c++代码中,我们规定了,注释统一使用“//”,函数名统一使用拼音。

2、程序的总体设计

  李同学和我我们起初看过几篇生命游戏的小程序,有的画面非常精美,我们本来想花点时间做出那种精美的带有色彩的小程序。后来被现实打败,多少次我们都想不出来那个代码究竟应该怎么写。最后我们一拖再拖拖到了我们放弃精美画面的时候。在这个不精美的小程序中,黑点点代表细胞,黑点点消失了就代表细胞死亡。

(1)流程图

(2)函数

void start(); //选择开始,初始化
void zuotu(MOUSEMSG *_m); //作图函数
void shengsi(); //生死判断
void shuru(); //输入函数
void shuchu(); //输出函数
void dy_world(); //打印函数
void shubiao(); //鼠标控制
void huitushebei(); //建立绘图
void jianpanjiankong(); //键盘控制

3、程序结对编程过程(附图)及功能实现情况(附代码和图)

我们通过QQ里的屏幕分享进行互动,李同学的麦有点问题,我们同时又在微信上进行语音通话。

 

 

 

(1)第一次交换角色。李同学创建了远程仓库,并且已经指定了部分所需头文件,定义了小程序里的一些参数。我fork了她的仓库,然后也初步声明了一些需要用到的函数。目前还没有写出函数。这是我们第一次做结对编程,这一步更是结对编程里的第一不,所以我们前进的异常困难。fork部分,我又重新学习了上一次实验报告里的知识。在pull request的时候,我没有成功提交pull request,导致李同学没有办法merge我的pull request,在这里我们耽搁了很久。

(2)第二次交换角色。李同学完成了 start() 和 jianpanjiankong()函数的编写,我完成了完成了 huitushebei() ,shubiao(),zuotu(MOUSEMSG *_m)函数的编写。有上一步的经验,我们这次的操作熟练了并且有自信了许多。就是写代码的时候略微困难,复杂的、困难的函数几乎都在这一步。

(3)第三次交换角色。完成kongjian(int x1, int x2, char *s),shengsi()函数的编写,我完成 打印,输入,输出函数。在这一步里,我的函数没有什么难度,我们很快就完成了。李同学的函数在这里出现了卡壳,不过后来经过百度询问,得到了解决。我们已经感觉到胜利就在眼前,并且不像之前那么愁眉苦脸了。

 

 

 

(4)第四次交换角色。代码部分已经写完了,在这一part里,我们对代码进行了美化规范。李同学提出我的代码格式没有缩进,我说c对缩进不敏感所以我就没在意,她说这个样子的代码很难看,然后一点一点把我的代码进行了缩进。我在已经有的注释上修改了一些模糊的注释。至此,我们的结对编程算是完美落幕了。

 

 

 (5)代码和运行结果

  1 //李一,编写了所需的头文件
  2 #include<graphics.h>//安装了EASY X才能打开这个头文件。
  3 #include<stdio.h>
  4 #include<stdlib.h>
  5 #include<windows.h>
  6 #include <conio.h>
  7 #include <time.h>
  8 __int8 world[102][202] = {0};
  9 IMAGE imgLive, imgEmpty;        // 定义活细胞和无细胞区域的图案  //创建两个图像对象。
 10 
 11 MOUSEMSG m;              //定义鼠标消息结构体的变量,并定义指向它的指针
 12 MOUSEMSG *_m = &m;
 13 
 14 char s1[20] = "速度:1", s2[20] = " ";    //速度值字符串s1,s2
 15 int Speed = 125;            // 游戏速度(毫秒)
 16 
 17 //王一,定义要用到的若干个函数,以及 main 函数的编写
 18 void start();   //世界初始化
 19 void kongjian(int x1, int x2, char *s);   //控件函数
 20 void zuotu(MOUSEMSG *_m);   //作图
 21 void shengsi();  //生死判断
 22 void shuru();   //输入函数
 23 void shuchu();    //输出函数
 24 void dy_world();   //打印世界
 25 void shubiao();   //鼠标监控与操作
 26 void RandWorld();  //随机设置世界
 27 void huitushebei();    //建立绘图设备
 28 void jianpanjiankong();   //键盘监控
 29 
 30 int main()
 31 {
 32     
 33 
 34     initgraph(1800, 900);  //创建一个尺寸为 1800x900 的绘图环境,原点坐标(0,0),位于左上角
 35     start();   //世界初始化
 36     huitushebei();     //建立绘图设备
 37     while (true)
 38     {
 39         jianpanjiankong();  //键盘监控
 40         shubiao();        //鼠标监控与操作
 41         dy_world();            // 绘制世界
 42         shengsi();            // 生死判断
 43         Sleep(Speed);
 44     }
 45     return 0;
 46 }
 47 
 48 //李二,完成了 start() 和 jianpanjiankong()函数的编写
 49 void start()
 50 {
 51     memset(world, 0, 102 * 202 * sizeof(bool));   //初始化world数组
 52     setbkcolor(WHITE);// 设置背景色为白色
 53     cleardevice();// 用背景色清空屏幕
 54     setfillcolor(BLACK);   //设置填充颜色为黑色
 55     kongjian(0, 0, " ");
 56     setcolor(BROWN);    // 设置字体颜色为棕色
 57     outtextxy(900, 5, s1); //打印速度值
 58     setcolor(BLACK);    // 设置字体颜色为黑色
 59     outtextxy(400, 5, "Q/清空  W/保存  E/加载  S/随机"); //打印文字
 60 }
 61 void jianpanjiankong()   //键盘监控
 62 {
 63     if (_kbhit())   
 64     {
 65         char c = _getch();    //读取键盘    //Speed等于450时,此处暂停
 66 
 67         if (c >='0' && c <= '9')
 68         {
 69             sprintf(s2, "%d", c - '0');      //将速度值写入字符数组s2中
 70             strcpy(s1, "速度:");     //初始化s1
 71             strcat(s1, s2);          //将s2连接到s1后
 72             setcolor(BROWN);    // 设置字体颜色为棕色
 73             outtextxy(900, 5, s1); //打印速度值
 74             if (c == '0')
 75                 Speed = 900;
 76             else
 77                 Speed = ('9' - c) * 25;  //根据输入数字调整速度
 78         }
 79         switch (c)
 80         {
 81         case 'q':
 82             start();  //世界初始化
 83             break;
 84         case 'w':
 85             shuchu();     //输出操作
 86             break;
 87         case 'e':
 88             shuru();     //输入操作
 89             break;
 90 
 91         case 's':
 92             RandWorld();   // 创建一个细胞随机分布的世界
 93             dy_world();            // 绘制世界
 94             break;
 95 
 96         case ' ':
 97             c = '/';
 98             setcolor(LIGHTRED);    // 设置字体颜色为亮红色
 99             outtextxy(1400, 5, "暂停"); //打印文字
100             while (c != ' ')
101             {
102                 shubiao();  //鼠标监控与操作
103                 Sleep(500);
104                 if (_kbhit())
105                 {
106                     c = _getch();
107                     dy_world();            // 绘制世界    
108                     shengsi();            // 生死判断    
109                 }
110             }
111             setfillcolor(WHITE);        //设置当前填充颜色为白色
112             solidrectangle(1400, 5, 1450, 20);    //打印白色方格,覆盖“暂停”文字
113             setfillcolor(BLACK);        //设置当前填充颜色为黑色
114             break;
115         }
116     }
117 }
118 //王二,完成了 huitushebei() ,shubiao(),zuotu(MOUSEMSG *_m)函数的编写
119 void huitushebei()     //建立绘图设备
120 {
121     // 调整世界图案的大小
122     Resize(&imgLive, 9, 9);    //
123     Resize(&imgEmpty, 9, 9);   //用于调整指定绘图设备的尺寸。
124 
125     // 绘制有生命世界的图案
126     SetWorkingImage(&imgLive);   //用于设定当前的绘图设备。
127     setfillcolor(BLACK);        //设置当前填充颜色为黑色
128     setcolor(LIGHTGRAY);        //设置边框颜色为白色
129     fillrectangle(0, 0, 8, 8);    //打印黑色方格,有边框
130 
131     // 绘制无生命世界的图案
132     SetWorkingImage(&imgEmpty);
133     setfillcolor(WHITE);        //设置当前填充颜色为白色
134     solidrectangle(0, 0, 8, 8);    //打印白色方格
135 
136     // 恢复对默认窗口的绘图
137     SetWorkingImage(NULL);
138 }
139 void shubiao()    //鼠标监控与操作
140 {
141     
142 
143     int x1 = 0, x2 = 0;      //x1,x2存储单个控件的左右边的X坐标位置
144     while (MouseHit())   //检测是否有鼠标消息
145     {
146         m = GetMouseMsg();       //获取鼠标消息
147         if (m.mkLButton || m.mkRButton)   //鼠标左右键是否有按下
148         {
149 
150             if (m.y > 26)      //m.y>26说明鼠标位于作图区,否则位于控件区
151             {
152                 do
153                 {
154                     if (m.y > 26)
155                         zuotu(_m);  //将鼠标信息传递给做图函数
156                     m = GetMouseMsg();       //获取鼠标消息
157                 } while (m.mkLButton || m.mkRButton);   //直到松开按键才结束作图
158             }
159             else      //判断鼠标位于哪个控件
160             {
161                 if (2 < m.x&&m.x < 63)
162                 {
163                     x1 = 2; x2 = 63;      //第一个控件的位置
164                     char s[] = "清空";
165                     kongjian(x1, x2, s);  //实现控件动画
166                     x1 = 0; x2 = 0;
167 
168                     start();
169 
170                 }
171                 if (72 < m.x&&m.x < 133)
172                 {
173                     x1 = 72; x2 = 133;     //第二个控件的位置
174                     char s[] = "保存";
175                     kongjian(x1, x2, s);  //实现控件动画
176                     x1 = 0;  x2 = 0;
177 
178                     shuchu();     //输出操作
179 
180                 }
181                 if (142 < m.x&&m.x < 203)
182                 {
183                     x1 = 142; x2 = 203;     //第三个控件的位置
184                     char s[] = "加载";
185                     kongjian(x1, x2, s);  //实现控件动画
186                     x1 = 0;  x2 = 0;
187 
188                     shuru();     //输入操作
189                 }
190                 if (212 < m.x&&m.x < 273)
191                 {
192                     x1 = 212; x2 = 273;     //第三个控件的位置
193                     char s[] = "随机";
194                     kongjian(x1, x2, s);  //实现控件动画
195                     x1 = 0;  x2 = 0;
196 
197                     RandWorld();   // 创建一个细胞随机分布的世界
198                     dy_world();            // 绘制世界
199 
200                 }
201                 if (282 < m.x&&m.x < 343)
202                 {
203                     x1 = 142; x2 = 203;     //第三个控件的位置
204                     char s[] = "结束";
205                     kongjian(x1, x2, s);  //实现控件动画
206                     x1 = 0;  x2 = 0;
207 
208                     exit(0);     //结束程序
209                 }
210 
211             };
212         }
213     }
214     FlushMouseMsgBuffer();   //清空鼠标消息缓冲区
215 }
216 void zuotu(MOUSEMSG *_m)   //作图
217 {
218     int x, y, xb, yb;
219 
220     xb = _m->x / 9+1;
221     yb = (_m->y - 26) / 9+1;
222     x = (xb - 1) * 9;
223     y = (yb - 1) * 9 + 26;
224     if (_m->mkLButton)
225     {
226         putimage(x, y, &imgLive);   //按左键时,打印方格,有边框
227         world[yb][xb] = 1;
228     }
229     if (_m->mkRButton)
230     {
231         putimage(x, y, &imgEmpty);    //按右键时,删除方格
232         world[yb][xb] = 0;
233     }
234 
235 }
236 //李三 完成kongjian(int x1, int x2, char *s),shengsi()函数的编写
237 void kongjian(int x1, int x2, char *s)     //控件函数
238 {
239     if (x1 == 0 && x2 == 0)  //若x1,x2==0,则初始化控件
240     {
241         setcolor(BLACK);// 设置字体颜色为黑色
242         setfillcolor(WHITE);   //设置填充颜色为白色
243 
244         fillrectangle(2, 2, 63, 23);  //画白色填充矩形
245         outtextxy(15, 5, "清空"); //打印文字
246 
247         fillrectangle(72, 2, 133, 23);  //画白色填充矩形
248         outtextxy(85, 5, "保存"); //打印文字
249 
250         fillrectangle(142, 2, 203, 23);  //画白色填充矩形
251         outtextxy(155, 5, "加载"); //打印文字
252 
253         fillrectangle(212, 2, 273, 23);  //画白色填充矩形
254         outtextxy(225, 5, "随机"); //打印文字
255 
256         fillrectangle(282, 2, 343, 23);  //画白色填充矩形
257         outtextxy(295, 5, "结束"); //打印文字
258 
259         setfillcolor(BLACK);   //设置填充颜色为黑色
260     }
261     if (x1 != 0 && x2 != 0)    //控件反馈效果
262     {
263         MOUSEMSG m;    //定义鼠标消息结构体的变量
264 
265         setcolor(BLACK);// 设置字体颜色为黑色
266 
267         setfillcolor(LIGHTGRAY);   //设置填充颜色为浅灰色
268         fillrectangle(x1, 2, x2, 23);  //画浅灰色填充矩形
269 
270         setbkcolor(LIGHTGRAY);// 设置背景色为浅灰色
271         outtextxy(x1 + 15, 5, s); //打印文字,与初始化相比向右移动2像素,实现动画效果
272         setbkcolor(WHITE);// 设置背景色为白色
273 
274         do  { m = GetMouseMsg(); } while (m.mkLButton || m.mkRButton);
275 
276         setfillcolor(WHITE);   //设置填充颜色为白色
277         fillrectangle(x1, 2, x2, 23);  //画白色填充矩形
278         outtextxy(x1 + 15 - 2, 5, s); //打印文字,返回初始化位置
279 
280         setfillcolor(BLACK);   //设置填充颜色为黑色
281     }
282 }
283 void shengsi()  //生死判断
284 {
285     __int8 tmp[102][202] = { 0 };        // 临时数组
286     int i, j;
287     int sum=0;
288     for (i = 1; i < 101;i++)
289     for (j = 1; j < 201; j++)
290     {
291         // 计算周围活着的生命数量
292         sum = world[i + 1][j] + world[i + 1][j - 1] + world[i][j - 1] + world[i- 1][j - 1]
293             + world[i - 1][j] + world[i - 1][j + 1] + world[i][j + 1] + world[i + 1][j + 1];
294 
295         // 计算当前位置的生命状态
296         switch (sum)
297         {
298         case 3:        tmp[i][j] = 1;                break;
299         case 2:        tmp[i][j] = world[i][j];    break;
300         default:    tmp[i][j] = 0;                break;
301         }
302     }
303     memcpy(world, tmp, 102 * 202 * sizeof(bool));  //从tmp中复制102 * 102 * sizeof(__int8)长度的数据给world
304 
305     
306 }
307 //王三,完成 打印,输入,输出函数
308 void dy_world()   //打印世界
309 {
310     int x, y;
311     int i, j;
312     for (i = 1; i <101; i++)
313     {
314         for (j = 1; j <201; j++)     //两层循环根据方格状态存储器处理方格
315         {
316             x = (j - 1) * 9;
317             y = (i - 1) * 9+26;
318             putimage(x, y, world[i][j] ? &imgLive : &imgEmpty);   //用于在指定位置,当前设备上绘制指定图像
319         }
320     }
321 }
322 
323 void RandWorld()   // 创建一个细胞随机分布的世界
324 {
325     
326     srand((unsigned)time(NULL));  // 设置随机种子
327 
328     for (int i = 1; i < 101; i++)
329     for (int j = 1; j <= 201; j++)
330         world[i][j] = rand() % 2;
331 }
332 void shuru()   //输入函数
333 {
334     FILE *fp;
335     if ((fp = fopen("data", "r")) == NULL)        //打开文件
336     {
337         setcolor(LIGHTRED);    // 设置字体颜色为亮红色
338         outtextxy(1600, 5, "错误!"); //打印文字
339         exit(0);
340     }
341 
342     int i, j;
343     char ch;
344     for (i = 1; i <101; i++)   //两层循环赋值给tu[][]
345     {
346         for (j =1; j<201; j++)
347         {
348             ch=fgetc(fp);
349             switch (ch)
350             {
351             case 48: world[i][j]=0; break;       //设置方格状态
352             case 49: world[i][j] = 1; break;    //设置方格状态
353             }
354 
355         }
356     }
357     dy_world();  //绘制世界
358     setcolor(LIGHTRED);    // 设置字体颜色为亮红色
359     outtextxy(1600, 5, "加载成功!"); //打印文字
360 
361 
362 }
363 void shuchu()    //输出函数
364 {
365     FILE *fp;   //定义文件指针
366     if ((fp = fopen("data", "w")) == NULL)       //打开文件并使fp指向文件
367     {
368         setcolor(LIGHTRED);    // 设置字体颜色为亮红色
369         outtextxy(1600, 5, "错误!"); //打印文字
370         exit(0);
371     }
372 
373     char ch;
374     int i, j;
375     for (i = 1; i<101; i++)          //用两层循环向文件中输入数据
376     {
377         for (j = 1; j <201; j++)
378         {
379             switch (world[i][j])
380             {
381             case 0: ch = '0'; break;
382             case 1: ch = '1'; break;
383             }
384             fputc(ch, fp);
385         }
386     }
387     fclose(fp);      //关闭
388 
389     setcolor(LIGHTRED);    // 设置字体颜色为亮红色
390     outtextxy(1600, 5, "保存成功!"); //打印文字
391 }

开始界面,按S键随机开始

黑点代表细胞,黑点消失代表细胞死亡

 

 4、项目github地址(附图)

github地址:https://github.com/lili-li1/practice

 

 5、实验总结

  我们两个实验合作的次数不少,但是这是第一次以这种形式合作。我有严重的拖延症,只要不到火烧眉毛我都不急,但是这次实验,李同学早早地就催促我快点做实验,快点想思路,快点写代码。跟她一起合作很开心。

  这门课程让我们学到了很多新东西,git和github都是曾听未曾听闻的,这次可以使用git在github上实现我和李同学的异地合作,学习了新知识,李同学跟我都很兴奋,虽然刚开始困难重重,但是最后完成任务时的兴奋和喜悦是很真实的。

 

posted @ 2020-03-31 22:58  小台  阅读(275)  评论(0编辑  收藏  举报