20135333苏正生实验三实验报告 敏捷开发与XP实践

课程:

Java程序设计

班级:

1353

姓名:

苏正生

学号:

2015333

成绩:

 

指导教师:

娄家鹏

实验日期:

2015.5.6

实验密级:

 

预习程度:

 

实验时间:

3:20~5:00

仪器组次:

 

必修/选修:

必修

实验序号:

实验三

实验名称:

实验内容:

1. XP基础

2. XP核心实践

3. 相关工具

 

 

实验仪器:

 

名称

型号

数量

笔记本电脑

 

 

Msi GS70

 

 

 

1

                 

实验步骤

(一)敏捷开发与XP

     学习软件工程的标准和流程,其中主要以敏捷开发流程为主,而其中有一极限编程作为学习流程的主要软件开发方法。包括:编码,测试,倾听,设计,作为学习者,我主要关注和研究了编码标准、结对编程、代码集体所有、测试、重构等。

(二)编码标准

      编码是一个即主观又客观的过程,每个程序员都有他自己的编程风格,但是不管到底是怎么编程,都要有一个良好的编程风格,而这个风格,就是编程标准,让代码具有了良好的可读性。

实验过程记录:20135333苏正生实验三实验报告
敏捷开发与XP实践

20135333苏正生实验三实验报告
敏捷开发与XP实践

(三)结对编程

     结对编程是我新认识的编程形式,总体来说就是两个人进行一边编程一边测试的过程。我(20135333)和芦畅(20135308)组成了小组,进行了小游戏和其他小程序的开发。

     在试验中,我俩对于团队精神和合作有了新的认识,相互决策,相互帮助。

(四)版本控制

     对于大型的软件编程,一定会有很多个程序员对整个软件工程进行修缮和维护,在这之间,必然会产生很多个软件版本,为了能够更好的保证代码的安全和高效,产生了代码仓库。

     本次实验,我们用了实验楼我的代码库,进行了代码库的开通以及git的实验练习。

实验过程记录:

20135333苏正生实验三实验报告
敏捷开发与XP实践

20135333苏正生实验三实验报告
敏捷开发与XP实践

20135333苏正生实验三实验报告
敏捷开发与XP实践

20135333苏正生实验三实验报告
敏捷开发与XP实践

20135333苏正生实验三实验报告
敏捷开发与XP实践

(五)重构

对于程序的维护和开发便利,重构对于程序员应该说是一个很有利的工具,主要体现在对于大规模程序和代码段的修改中极大的提高效率和安全性。

主要包括,修改名称,对于方法、变量名、常量、类、接口以及参数对象等java编程常常修改和更正的地方。

实验过程记录:

20135333苏正生实验三实验报告
敏捷开发与XP实践

20135333苏正生实验三实验报告
敏捷开发与XP实践20135333苏正生实验三实验报告
敏捷开发与XP实践

(六)实践项目

   本次java时间项目我小组选择了“五子棋”小游戏,在试验过程中,使用到了GUI用户界面显示,并同时试写了测试代码。

通过不断地磨合与协作,小游戏成功的运行,并进行了试玩,效果良好,未发现结果错误。

实验过程记录:

20135333苏正生实验三实验报告
敏捷开发与XP实践20135333苏正生实验三实验报告
敏捷开发与XP实践

源代码:

Game.java
import javax.swing.*;


public class Game {


public static void main(String[] args) {

GameFrame GFrame=new GameFrame();
GFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
GFrame.setVisible(true);
}

}

GameFrame.java
import java.awt.*;
import javax.swing.*;


class GameFrame extends JFrame {

private static final int Width=570;
private static final int Height=470;

GameFrame(){
setTitle("五子棋游戏");
CenteredFrame();
setSize(Width,Height);
GamePanel Gpanel=new GamePanel();
add(Gpanel);
}

void CenteredFrame(){
Toolkit kit=Toolkit.getDefaultToolkit();
Dimension screenSize=kit.getScreenSize();
int screenHeight=screenSize.height;
int screenWidth=screenSize.width;

int Xposition=(screenWidth-Width)/2;
int Yposition=(screenHeight-Height)/2;
setLocation(Xposition,Yposition);
}
}

GamePanel.java

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;


class GamePanel extends JPanel {

private Point cursor=new Point(40,60); //棋盘坐标
private int[][] ChessState=new int[18][18];//棋盘状态
private int i=0;//横坐标   
private int j=0;//纵坐标
private final static int testnum=5;//五子棋的规定棋子数
private Player Black=new Player(1,Color.BLACK,"黑方");//黑方棋子
private Player White=new Player(2,Color.WHITE,"白方");//白方棋子
private Player Cplayer=null;//当前用户的引用
private JTextField textBlack=new JTextField("",5);//黑方文本提示框对象和文本长度设置
private JTextField textWhite=new JTextField("",5);//白方文本提示框对象和文本长度设置
private String Nothing="";
private String textblack="请黑方下子";//黑方提示文本
private String textwhite="请白方下子";//白方提示文本


GamePanel(){
setLayout(null);
Initialization();
setFocusable(true);

JButton Rutton=new JButton("重新开局");
Rutton.setBounds(20,14,100,26);
RestartListener restart=new RestartListener();
Rutton.addActionListener(restart);
add(Rutton);


textBlack.setHorizontalAlignment(JTextField.CENTER);
textBlack.setBounds(150,14,110,26);
textBlack.setEditable(false);
add(textBlack);

textWhite.setHorizontalAlignment(JTextField.CENTER);
textWhite.setBounds(290,14,110,26);
textWhite.setEditable(false);
add(textWhite);

JTextArea gInstruction=new JTextArea();
gInstruction.setSelectedTextColor(new Color(238,238,238));
String gSInstruction=
"Play1(黑方) Key up--------W down----S left--------A right------F "+
"Play2(白方) Key up--------up down----down left--------left right------right "+
"Exit game: Press Esc";
gInstruction.setText(gSInstruction);
gInstruction.setEditable(false);
gInstruction.setBounds(440,60,100,340);
add(gInstruction);

ChessManPerformListener Perform=new ChessManPerformListener();
addKeyListener(Perform);

}

// 设置第一个JTextField输出"请黑方下棋",坐标为(40,60)
void Initialization(){
for(int i=0,j;i<18;i++)
for(j=0;j<18;j++){
ChessState[i][j]=0;
}
cursor.setLocation(40,60);
Cplayer=Black;
textBlack.setText(textblack);
textWhite.setText(Nothing);
}


//画棋盘和初始化棋局状态
protected void paintComponent(Graphics g){
super.paintComponent(g);
Graphics2D g2=(Graphics2D) g;

for(int i=60;i<=400;i+=20){
g2.drawLine(40,i,380,i);
}
for(int j=40;j<=380;j+=20){
g2.drawLine(j,60,j,400);
}
g2.drawString("_",cursor.x-6,cursor.y);
g2.drawString("_",cursor.x,cursor.y);

for(i=0;i<18;i++)
for(j=0;j<18;j++){
if(ChessState[i][j]!=0){
if(ChessState[i][j]==1){
g2.setPaint(Black.getplayerChessManColor());
}
if(ChessState[i][j]==2){
g2.setPaint(White.getplayerChessManColor());
}
g2.fillOval(j*20+40-10, i*20+60-10, ChessMan.getChessManSize(), ChessMan.getChessManSize());
}
}
}



//判断棋盘的当前位置是否已有棋子
boolean isChessState(){
this.j=(cursor.x-40)/20;
this.i=(cursor.y-60)/20;
if(ChessState[this.i][this.j]!=0)
return true;
else
return false;
}




//记录落子后棋盘的当前位置的状态
void RecordChessState(){
this.j=(cursor.x-40)/20;
this.i=(cursor.y-60)/20;
ChessState[this.i][this.j]=Cplayer.getCurrentIdentify();
}






//判断当前玩家落子后是否赢了
void JudgeWin(){
for(int i=0;i<4;i++)
if(JudgeWinLine(i)){
//提示当前玩家已经获得胜利
try{
String Ginformation="GameInformation";
String Message="恭喜玩家"+Cplayer.getsIdentify()+"获胜!"+" "+"继续游戏还是退出游戏?";
String[] options = {"继续","退出"};
int selection=JOptionPane.showOptionDialog(null,Message,Ginformation,
JOptionPane.YES_NO_OPTION,JOptionPane.INFORMATION_MESSAGE ,null,options,options[0]);//throws HeadlessException
if(selection==JOptionPane.OK_OPTION){
Initialization();
repaint();
return;
}
if(selection==JOptionPane.NO_OPTION){
System.exit(0);//退出程序
}

}catch(HeadlessException e){
e.printStackTrace();
}
}
//如果当前方没有赢棋则双方轮换
ChangeCurrentPlayer();
}





//在当前方向上是否有连续的五只棋子
boolean JudgeWinLine(int direction){
int i,j,di,dj,count;
i=j=di=dj=count=0;
switch(direction){
case 0:
j=this.j-(testnum-1);
i=this.i;
dj=1;
di=0;
break;
case 1:
j=this.j;
i=this.i-(testnum-1);
dj=0;
di=1;
break;
case 2:
j=this.j-(testnum-1);
i=this.i+(testnum-1);
dj=1;
di=-1;
break;
case 3:
j=this.j-(testnum-1);
i=this.i-(testnum-1);
dj=1;
di=1;
break;
}

for(int k=0;k<testnum*2+1;k++){
if(j>=0&&j<18&&i>=0&&i<18){
if(ChessState[i][j]==Cplayer.getCurrentIdentify()){
count++;
if(count>=testnum)
return true;
}
else
count=0;
}
j+=dj;
i+=di;
}
return false;
}




//更换当前玩家
void ChangeCurrentPlayer(){
if(Cplayer==Black){
Cplayer=White;
textBlack.setText(Nothing);
textWhite.setText(textwhite);
}
else{
Cplayer=Black;
textBlack.setText(textblack);
textWhite.setText(Nothing);
}
}






//重新开局监听器
private class RestartListener implements ActionListener{

public void actionPerformed(ActionEvent arg0) {

Initialization();
repaint();
requestFocus();
}
}





//棋盘、棋局状态监听器
private class ChessManPerformListener implements KeyListener{


//玩家2的按键
public void keyPressed(KeyEvent event) {
int keyCode=event.getKeyCode();
if(keyCode==KeyEvent.VK_ESCAPE)
System.exit(0);
if(Cplayer.getCurrentIdentify()==2){//判别当前玩家
if(keyCode==KeyEvent.VK_LEFT){
if(cursor.x>40)
cursor.x-=20;
}
else if(keyCode==KeyEvent.VK_RIGHT){
if(cursor.x<380)
cursor.x+=20;
}
else if(keyCode==KeyEvent.VK_UP){
if(cursor.y>60)
cursor.y-=20;
}
else if(keyCode==KeyEvent.VK_DOWN){
if(cursor.y<400)
cursor.y+=20;
}
else if(keyCode==KeyEvent.VK_ENTER){
if(!isChessState()){
Cplayer.PerformChessMan();
RecordChessState();
repaint();
JudgeWin();//判定当前落子后是否赢棋

}

}
repaint();
}
}





public void keyReleased(KeyEvent event) {}




//玩家1的按键
public void keyTyped(KeyEvent event) {

char keyChar=event.getKeyChar();
if(Cplayer.getCurrentIdentify()==1){//判别当前玩家
if(keyChar=='a'){
if(cursor.x>40)//对移动光标超界现象做判别
cursor.x-=20;
}
else if(keyChar=='d'){
if(cursor.x<380)
cursor.x+=20;
}
else if(keyChar=='w'){
if(cursor.y>60)
cursor.y-=20;
}
else if(keyChar=='s'){
if(cursor.y<400)
cursor.y+=20;
}
else if(keyChar==' '){
if(!isChessState()){ //落子前先判断当前位置上是否已有棋子
Cplayer.PerformChessMan();//落子
RecordChessState();//记录当前落子后棋盘状态
repaint();
JudgeWin();//判定当前落子后是否赢棋

}
}

}
repaint();
}

}

}


ChessMan.java
import java.awt.Color;

class ChessMan {

private static final int ChessManSize=20;
private Color ChessManColor;

ChessMan(Color c){
ChessManColor=c;
}



static int getChessManSize(){
return ChessManSize;
}


Color getChessManColor(){
return ChessManColor;
}


}

Player.java
import java.awt.Color;


class Player {

private int identify;
private ChessMan pChessMan;
private String PlayerStringIdentify;


Player(int identify,Color c,String sIdentify){
this.identify=identify;
pChessMan=new ChessMan(c);
this.PlayerStringIdentify=sIdentify;
}


int getCurrentIdentify(){
return identify;
}



String getsIdentify(){
return PlayerStringIdentify;
}


void PerformChessMan(){}


Color getplayerChessManColor(){
return pChessMan.getChessManColor();
}
}

所做小游戏由五个java源程序文件组成,Game.java、GameFrame.java、GamePanel.java、 ChessMan.java、Player.java 

  用Java编写了一个五子棋游戏,实现了实现了人人对战。

GitHub链接:

shiyanlou_cs212 - Gogs: Go Git Service
http://git.shiyanlou.com/szs20135333/shiyanlou_cs212

分工情况:

  苏正生:负责棋子胜负判断部分

  芦畅:gui设计以及代码完善修复http://www.cnblogs.com/bonjourvivi/p/4550714.html

重点说明:

  判断棋子胜负

  判断X行是否五只相连

实验总结:

通过本次实验,从java程序开发方式到代码重构都有了新的认识,同时在结对编程中体会到了团队协作的优点,在整个编程过程中对于程序整体设计理念有了更新的认识。

编程过程中,出现了调用功能失误、类型不匹配代码、逻辑错误、运行结果不符合预期、操作指令混乱这五个问题,多亏了结伴编程,在编程的过程中即对错误的地方进行了修正,极大的减少了测试时间,提高了效率。

在试验过程中,出现了vim指令操作不明,无法保存退出的情况,之后通过查找vim指令集,得知“:wq”为保存退出指令。后经使用,并未保存退出,之后经过仔细查阅其他博客园博主的帖子,发现先要通过“ctrl+c”或者“esc”进行退出,之后进过退出操作,成功完成。

步骤 耗时 百分比
需求分析  30min  5%
设计  1h  10%
代码实现  4h  40%
测试  4h  40%
分析总结