一、   实验内容

(一)敏捷开发与XP

内容:1.敏捷开发(Agile Development)是一种以人为核心、迭代、循序渐进的开发方法。

2.极限编程(eXtreme Programming,XP)是一种全新而快捷的软件开发方法。

要点: 1. XP软件开发的基石是XP的活动,包括:编码、测试、倾听、设计。

2. 我们关注其中的编码标准,结对编程,代码集体所有,测试,重构等实践。(如实验二中的TDD)

(二)编码标准

内容:编程标准使代码更容易阅读和理解,甚至可以保证其中的错误更少。编程标准包含:具有说明性的名字、清晰的表达式、直截了当的控制流、可读的代码和注释,以及在追求这些内容时一致地使用某些规则和惯用法的重要性。

学习:

1. 软件辅助修改:在eclipse中,用source->Format进行格式规范;

2. 自己命名:包名全部小写,如: io ;类名第一个字母要大写,如:HelloWorldApp;等

(三)结对编程

内容:在结对编程模式下,一对程序员肩并肩、平等地、互补地进行开发工作。其中的角色分配为驾驶员(控制键盘输入),领航人(起到领航、提醒作用)。

(四)版本控制

摘要:版本控制提供项目级的 undo(撤销) 功能;•   版本控制允许多人在同一代码上工作;•  版本控制系统保存了过去所作的修改的历史记录;具体步骤如下——

# 添加修改文件

$ git add 所有修改的文件

# 提交到环境中本地代码仓库

$ git commit -m '本次修改的描述'

# push到git.shiyanlou.com,无需输入密码

$ git push

学习:按照要求指导,逐步在实验楼中完成,截图如下:

(五)重构

摘要:重构(Refactor),就是在不改变软件外部行为的基础上,改变软件内部的结构,使其更加易于阅读、易于维护和易于变更 。学习:尝试Encapsulate Field(封装)功能:

原图:

(六)实践项目

同伴郝爽20135335博客地址http://www.cnblogs.com/20135335hs

1.综述

我们采取“先学习,后操作;边操作,边变通”的实验思路。具体方法是:研读要求—学习代码要素—复习TDD内容—构建测试程序—检查测试程序—测试产品代码—修改产品代码—重新检查产品代码—完成实验报告。在这一过程中,我们对各方面内容都进行了详细记录(未在实验楼中进行托管和git)

团队由两名成员组成,详细分工为:

20135335郝爽:负责前期学习的整理工作,将java代码进行必要注释,并对TDD内容进行补充;进行后期测试

20135233杨光:负责中期的测试代码开发;进行后期测试

2.研读要求与自我学习(20135211)

1.TDD(Test Driven Development, 测试驱动开发),

TDD的一般步骤如下:

  • 明确当前要完成的功能,记录成一个测试列表
  • 快速完成编写针对此功能的测试用例
  • 测试代码编译不通过(没产品代码呢)
  • 编写产品代码
  • 测试通过
  • 对代码进行重构,并保证测试通过(重构下次实验练习)
  • 循环完成所有功能的开发

2. 测试类具体操作:把鼠标放到项目名上,单击右键,在弹出的菜单中选定New->Source Folder新建一个测试目录test;把鼠标放到test目录上,单击右键,在弹出的菜单中选定New->JUnit Test Case新建一个测试用例类

3.实验要求要点为:程序要有GUI界面,参考用户界面和用户体验;记录TDD和重构的过程,测试代码不要少于业务代码

package game;

import java.awt.Button;

import java.awt.Canvas;

import java.awt.Color;

import java.awt.Dimension;

import java.awt.Frame;

import java.awt.Graphics;

import java.awt.GridLayout;

import java.awt.Insets;

import java.awt.Label;

import java.awt.Panel;

import java.awt.TextField;

import java.awt.event.ActionEvent;

import java.awt.event.ActionListener;

import java.awt.event.KeyEvent;

import java.awt.event.KeyListener;

import java.awt.event.WindowAdapter;

import java.awt.event.WindowEvent;

import java.awt.event.WindowListener;

//俄罗斯方块类

public class ERS_Block extends Frame {

public static boolean isPlay = false;

public static int level = 1, score = 0;

public static TextField scoreField, levelField;

public static MyTimer timer;

GameCanvas gameScr;

public static void main(String[] argus) {

ERS_Block ers = new ERS_Block(

"俄罗斯方块游戏  V1.0                   Author:Vincent");

WindowListener win_listener = new WinListener();

ers.addWindowListener(win_listener);

}

// 俄罗斯方块类的构造方法

ERS_Block(String title) {

super(title);

setSize(600, 480);

setLayout(new GridLayout(1, 2));

gameScr = new GameCanvas();

gameScr.addKeyListener(gameScr);

timer = new MyTimer(gameScr);

timer.setDaemon(true);

timer.start();

timer.suspend();

add(gameScr);

Panel rightScr = new Panel();

rightScr.setLayout(new GridLayout(2, 1, 0, 30));

rightScr.setSize(120, 500);

add(rightScr);

// 右边信息窗体的布局

MyPanel infoScr = new MyPanel();

infoScr.setLayout(new GridLayout(4, 1, 0, 5));

infoScr.setSize(120, 300);

rightScr.add(infoScr);

// 定义标签和初始值

Label scorep = new Label("分数:", Label.LEFT);

Label levelp = new Label("级数:", Label.LEFT);

scoreField = new TextField(8);

levelField = new TextField(8);

scoreField.setEditable(false);

levelField.setEditable(false);

infoScr.add(scorep);

infoScr.add(scoreField);

infoScr.add(levelp);

infoScr.add(levelField);

scorep.setSize(new Dimension(20, 60));

scoreField.setSize(new Dimension(20, 60));

levelp.setSize(new Dimension(20, 60));

levelField.setSize(new Dimension(20, 60));

scoreField.setText("0");

levelField.setText("1");

// 右边控制按钮窗体的布局

MyPanel controlScr = new MyPanel();

controlScr.setLayout(new GridLayout(5, 1, 0, 5));

rightScr.add(controlScr);

// 定义按钮play

Button play_b = new Button("开始游戏");

play_b.setSize(new Dimension(50, 200));

play_b.addActionListener(new Command(Command.button_play, gameScr));

// 定义按钮Level UP

Button level_up_b = new Button("提高级数");

level_up_b.setSize(new Dimension(50, 200));

level_up_b.addActionListener(new Command(Command.button_levelup,

gameScr));

// 定义按钮Level Down

Button level_down_b = new Button("降低级数");

level_down_b.setSize(new Dimension(50, 200));

level_down_b.addActionListener(new Command(Command.button_leveldown,

gameScr));

// 定义按钮Level Pause

Button pause_b = new Button("游戏暂停");

pause_b.setSize(new Dimension(50, 200));

pause_b.addActionListener(new Command(Command.button_pause, gameScr));

// 定义按钮Quit

Button quit_b = new Button("退出游戏");

quit_b.setSize(new Dimension(50, 200));

quit_b.addActionListener(new Command(Command.button_quit, gameScr));

controlScr.add(play_b);

controlScr.add(level_up_b);

controlScr.add(level_down_b);

controlScr.add(pause_b);

controlScr.add(quit_b);

setVisible(true);

gameScr.requestFocus();

}

}

// 重写MyPanel类,使Panel的四周留空间

class MyPanel extends Panel {

public Insets getInsets() {

return new Insets(30, 50, 30, 50);

}

}

// 游戏画布类

class GameCanvas extends Canvas implements KeyListener {

final int unitSize = 30; // 小方块边长

int rowNum; // 正方格的行数

int columnNum; // 正方格的列数

int maxAllowRowNum; // 允许有多少行未削

int blockInitRow; // 新出现块的起始行坐标

int blockInitCol; // 新出现块的起始列坐标

int[][] scrArr; // 屏幕数组

Block b; // 对方快的引用

// 画布类的构造方法

GameCanvas() {

rowNum = 15;

columnNum = 10;

maxAllowRowNum = rowNum - 2;

b = new Block(this);

blockInitRow = rowNum - 1;

blockInitCol = columnNum / 2 - 2;

scrArr = new int[32][32];

}

// 初始化屏幕,并将屏幕数组清零的方法

void initScr() {

for (int i = 0; i < rowNum; i++)

for (int j = 0; j < columnNum; j++)

scrArr[i][j] = 0;

b.reset();

repaint();

}

// 重新刷新画布方法

public void paint(Graphics g) {

for (int i = 0; i < rowNum; i++)

for (int j = 0; j < columnNum; j++)

drawUnit(i, j, scrArr[i][j]);

}

// 画方块的方法

public void drawUnit(int row, int col, int type) {

scrArr[row][col] = type;

Graphics g = getGraphics();

switch (type) { // 表示画方快的方法

case 0:

g.setColor(Color.black);

break; // 以背景为颜色画

case 1:

g.setColor(Color.blue);

break; // 画正在下落的方块

case 2:

g.setColor(Color.magenta);

break; // 画已经落下的方法

}

g.fill3DRect(col * unitSize, getSize().height - (row + 1) * unitSize,

unitSize, unitSize, true);

g.dispose();

}

public Block getBlock() {

return b; // 返回block实例的引用

}

// 返回屏幕数组中(row,col)位置的属性值

public int getScrArrXY(int row, int col) {

if (row < 0 || row >= rowNum || col < 0 || col >= columnNum)

return (-1);

else

return (scrArr[row][col]);

}

// 返回新块的初始行坐标方法

public int getInitRow() {

return (blockInitRow); // 返回新块的初始行坐标

}

// 返回新块的初始列坐标方法

public int getInitCol() {

return (blockInitCol); // 返回新块的初始列坐标

}

// 满行删除方法

void deleteFullLine() {

int full_line_num = 0;

int k = 0;

for (int i = 0; i < rowNum; i++) {

boolean isfull = true;

L1: for (int j = 0; j < columnNum; j++)

if (scrArr[i][j] == 0) {

k++;

isfull = false;

break L1;

}

if (isfull)

full_line_num++;

if (k != 0 && k - 1 != i && !isfull)

for (int j = 0; j < columnNum; j++) {

if (scrArr[i][j] == 0)

drawUnit(k - 1, j, 0);

else

drawUnit(k - 1, j, 2);

scrArr[k - 1][j] = scrArr[i][j];

}

}

for (int i = k - 1; i < rowNum; i++) {

for (int j = 0; j < columnNum; j++) {

drawUnit(i, j, 0);

scrArr[i][j] = 0;

}

}

ERS_Block.score += full_line_num;

ERS_Block.scoreField.setText("" + ERS_Block.score);

}

// 判断游戏是否结束方法

boolean isGameEnd() {

for (int col = 0; col < columnNum; col++) {

if (scrArr[maxAllowRowNum][col] != 0)

return true;

}

return false;

}

public void keyTyped(KeyEvent e) {

}

public void keyReleased(KeyEvent e) {

}

// 处理键盘输入的方法

public void keyPressed(KeyEvent e) {

if (!ERS_Block.isPlay)

return;

switch (e.getKeyCode()) {

case KeyEvent.VK_DOWN:

b.fallDown();

break;

case KeyEvent.VK_LEFT:

b.leftMove();

break;

case KeyEvent.VK_RIGHT:

b.rightMove();

break;

case KeyEvent.VK_SPACE:

b.leftTurn();

break;

}

}

}

// 处理控制类

class Command implements ActionListener {

static final int button_play = 1; // 给按钮分配编号

static final int button_levelup = 2;

static final int button_leveldown = 3;

static final int button_quit = 4;

static final int button_pause = 5;

static boolean pause_resume = true;

int curButton; // 当前按钮

GameCanvas scr;

// 控制按钮类的构造方法

Command(int button, GameCanvas scr) {

curButton = button;

this.scr = scr;

}

// 按钮执行方法

public void actionPerformed(ActionEvent e) {

switch (curButton) {

case button_play:

if (!ERS_Block.isPlay) {

scr.initScr();

ERS_Block.isPlay = true;

ERS_Block.score = 0;

ERS_Block.scoreField.setText("0");

ERS_Block.timer.resume();

}

scr.requestFocus();

break;

case button_levelup:

if (ERS_Block.level < 10) {

ERS_Block.level++;

ERS_Block.levelField.setText("" + ERS_Block.level);

ERS_Block.score = 0;

ERS_Block.scoreField.setText("" + ERS_Block.score);

}

scr.requestFocus();

break;

case button_leveldown:

if (ERS_Block.level > 1) {

ERS_Block.level--;

ERS_Block.levelField.setText("" + ERS_Block.level);

ERS_Block.score = 0;

ERS_Block.scoreField.setText("" + ERS_Block.score);

}

scr.requestFocus();

break;

case button_pause:

if (pause_resume) {

ERS_Block.timer.suspend();

pause_resume = false;

} else {

ERS_Block.timer.resume();

pause_resume = true;

}

scr.requestFocus();

break;

case button_quit:

System.exit(0);

}

}

}

// 方块类

class Block {

static int[][] pattern = {

{ 0x0f00, 0x4444, 0x0f00, 0x4444 },// 用十六进至表示,本行表示长条四种状态

{ 0x04e0, 0x0464, 0x00e4, 0x04c4 },

{ 0x4620, 0x6c00, 0x4620, 0x6c00 },

{ 0x2640, 0xc600, 0x2640, 0xc600 },

{ 0x6220, 0x1700, 0x2230, 0x0740 },

{ 0x6440, 0x0e20, 0x44c0, 0x8e00 },

{ 0x0660, 0x0660, 0x0660, 0x0660 } };

int blockType; // 块的模式号(0-6)

int turnState; // 块的翻转状态(0-3)

int blockState; // 快的下落状态

int row, col; // 块在画布上的坐标

GameCanvas scr;

// 块类的构造方法

Block(GameCanvas scr) {

this.scr = scr;

blockType = (int) (Math.random() * 1000) % 7;

turnState = (int) (Math.random() * 1000) % 4;

blockState = 1;

row = scr.getInitRow();

col = scr.getInitCol();

}

// 重新初始化块,并显示新块

public void reset() {

blockType = (int) (Math.random() * 1000) % 7;

turnState = (int) (Math.random() * 1000) % 4;

blockState = 1;

row = scr.getInitRow();

col = scr.getInitCol();

dispBlock(1);

}

// 实现“块”翻转的方法

public void leftTurn() {

if (assertValid(blockType, (turnState + 1) % 4, row, col)) {

dispBlock(0);

turnState = (turnState + 1) % 4;

dispBlock(1);

}

}

// 实现“块”的左移的方法

public void leftMove() {

if (assertValid(blockType, turnState, row, col - 1)) {

dispBlock(0);

col--;

dispBlock(1);

}

}

// 实现块的右移

public void rightMove() {

if (assertValid(blockType, turnState, row, col + 1)) {

dispBlock(0);

col++;

dispBlock(1);

}

}

// 实现块落下的操作的方法

public boolean fallDown() {

if (blockState == 2)

return (false);

if (assertValid(blockType, turnState, row - 1, col)) {

dispBlock(0);

row--;

dispBlock(1);

return (true);

} else {

blockState = 2;

dispBlock(2);

return (false);

}

}

// 判断是否正确的方法

boolean assertValid(int t, int s, int row, int col) {

int k = 0x8000;

for (int i = 0; i < 4; i++) {

for (int j = 0; j < 4; j++) {

if ((int) (pattern[t][s] & k) != 0) {

int temp = scr.getScrArrXY(row - i, col + j);

if (temp < 0 || temp == 2)

return false;

}

k = k >> 1;

}

}

return true;

}

// 同步显示的方法

public synchronized void dispBlock(int s) {

int k = 0x8000;

for (int i = 0; i < 4; i++) {

for (int j = 0; j < 4; j++) {

if (((int) pattern[blockType][turnState] & k) != 0) {

scr.drawUnit(row - i, col + j, s);

}

k = k >> 1;

}

}

}

}

// 定时线程

class MyTimer extends Thread {

GameCanvas scr;

public MyTimer(GameCanvas scr) {

this.scr = scr;

}

public void run() {

while (true) {

try {

sleep((10 - ERS_Block.level + 1) * 100);

} catch (InterruptedException e) {

}

if (!scr.getBlock().fallDown()) {

scr.deleteFullLine();

if (scr.isGameEnd()) {

ERS_Block.isPlay = false;

suspend();

} else

scr.getBlock().reset();

}

}

}

}

class WinListener extends WindowAdapter {

public void windowClosing(WindowEvent l) {

System.exit(0);

}

}

6.实验感悟

本次实验,我们没有进入实验楼完成,自己在电脑上自主做实验,在游戏设计的时候并不是一帆风顺,有许多问题都咨询了学长与同学。

在实验中我们也有查阅网上有关的游戏资料,增长了许多知识与见识,对我的程序设计有很大的帮助。

实验3 --俄罗斯方块 with 20135335郝爽的更多相关文章

  1. 20135335郝爽 & 20135304刘世鹏 实验一

    北京电子科技学院(BESTI) 实     验    报     告 课程: 密码系统设计基础                                                      ...

  2. 2014-2015-2 《Java程序设计》课程学生博客列表

    20135101 曹钰晶 20135103 王海宁 20135104 刘 帅 20135105 王雪铖 20135109 高艺桐 20135111 李光豫 20135114 王朝宪 20135116 ...

  3. LINUX第五次实验报告

    北京电子科技学院(BESTI) 实     验    报     告 课程:信息安全系统设计基础                     班级: 201353 姓名:刘世鹏 郝爽 学号:2013530 ...

  4. linux内核第二周

    chapter 1 知识点梳理 (一)计算机是如何工作的?(总结)——三个法宝 ①存储程序计算机工作模型,计算机系统最最基础性的逻辑结构: ②函数调用堆栈,高级语言得以运行的基础,只有机器语言和汇编语 ...

  5. 20145335郝昊《java程序设计》第2次实验报告

    20145335郝昊<java程序设计>第2次实验报告 实验名称 Java面向程序设计,采用TDD的方式设计有关实现复数类Complex. 理解并掌握面向对象三要素:封装.继承.多态. 运 ...

  6. 20145335郝昊《java程序设计》第1次实验报告

    2014535郝昊<java程序设计>实验1实验报告 实验名称 利用java语言实现凯撒密码,并运行测试. 实验内容 用java语言实现凯撒密码,凯撒密码是一种代替的移位密码,它将明文加密 ...

  7. 王爽<汇编语言>实验十

    实验十 3.数值显示(以下程序附带测试程序) ;名称: dtoc ;功能: 将dword型数据转变为表示十进制数的字符串,字符串以0为结尾 ;参数: (ax)=dword型数据低字 ; (dx)=dw ...

  8. 王爽<<汇编语言>> 实验十四

    ;以"年/月/日 时:分:秒"的格式, 显示当前的日期, 时间 assume cs:code code segment main: out 70h,al ;告诉CMOS RAM将要 ...

  9. 王爽< 汇编语言>实验十二

    ;此乃安装程序 ;功能:将8086cpu中断类型码为0 的中断向量设置为我们编写的中断服务程序入口地址 ;该中断在除法发送溢出的时候产生 assume cs:code code segment mai ...

随机推荐

  1. 使用zabbix发送邮件的简易设置流程(存档用)

    1.安装邮件软件 (一般默认安装sendmail,这样apache也不用重新设置.) $sudo yum install sendmail 2.在zabbix上设置发送邮件用的本地邮箱 选择管理-&g ...

  2. ruby puts, print, p方法比较

    1.puts([obj[, obj2[, ....]]] ) 依次将obj和换行符输出到$>.若没有参数的话则只会输出换行符. 若参数是数组,则依次输出数组元素和换行符.若将既非数组又非字符串的 ...

  3. (数据科学学习手札26)随机森林分类器原理详解&Python与R实现

    一.简介 作为集成学习中非常著名的方法,随机森林被誉为“代表集成学习技术水平的方法”,由于其简单.容易实现.计算开销小,使得它在现实任务中得到广泛使用,因为其来源于决策树和bagging,决策树我在前 ...

  4. Hibernate第一天——入门和基本操作

    第一个接触的框架就是这个Hibernate框架了,Hibernate本意是 冬眠 ,这里有必要引用CSDN上某位网友某个帖子的评论先引出框架的概念: 框架:一个软件半成品,帮你做了一些基础工作,你就可 ...

  5. 20155202 2016-2017-2 《Java程序设计》第9周学习总结

    20155202 2016-2017-2 <Java程序设计>第9周学习总结 教材学习内容总结 整合数据库: JDBC驱动程序,按照方式分4种类型: Type1 : JDBC-ODBC B ...

  6. 【SQLSERVER】处理一对多标签的语法糖

    数据库表设计的时候,经常会出现一对多的情况,比如标签.明细之类的. 有时,需要在一个查询中,将每个主体的所有标签在一个字段中展示出来,这个时候就可以用 FOR XML PATH 这个语法轻易的实现. ...

  7. c++ 方框中绘制菜单代码

    绘制静态菜单 getch与getchar 接收光标控制 一.绘制静态菜单 编写函数void mainmenu( void) 二.getch与getchar getch()的作用是从键盘接收一个字 ...

  8. Qt5.4 All Modules

    Qt5.4 All Modules Qt Essentials Qt essentials define the foundation of Qt on all platforms. They are ...

  9. 深度学习与计算机视觉(12)_tensorflow实现基于深度学习的图像补全

    深度学习与计算机视觉(12)_tensorflow实现基于深度学习的图像补全 原文地址:Image Completion with Deep Learning in TensorFlow by Bra ...

  10. 菜鸟vimer成长记——第2.2章、visual模式

    vi是没有可视模式的.然而大多数编辑软件都都是有可视模式.所以我猜测vim是几乎迫于无奈才有了visual模式. 个人建议,能不用就不用.这样能直接在头脑里处理好文本,锻炼文本处理能力,同时能转变过来 ...