實驗三報告

 北京電子科技學院(BESTI)php

                     實     驗    報     告html

      課程:Java   班級: 1352     姓名:談愈敏     學號:20135220java

      成績:                指導教師:婁嘉鵬          實驗日期:2015.5.8git

      實驗密級:           預習程度:                實驗時間:15:30~18:00程序員

      儀器組次:20         必修/選修:選修           實驗序號:02github

      實驗名稱:敏捷開發與XP實踐                                            算法

      實驗儀器:express

名稱編程

型號設計模式

數量

計算機

lenovo

1

實驗樓

 

1

 

              

實驗步驟

(一)敏捷開發與XP

軟件工程是把系統的、有序的、可量化的方法應用到軟件的開發、運營和維護上的過程。軟件工程包括下列領域:軟件需求分析、軟件設計、軟件構建、軟件測試和軟件維護。 人們在開發、運營、維護軟件的過程當中有不少技術、作法、習慣和思想體系。軟件工程把這些相關的技術和過程統一到一個體系中,叫「軟件開發流程」。軟件開發流程的目的是爲了提升軟件開發、運營、維護的效率,並提升軟件的質量、用戶滿意度、可靠性和軟件的可維護性。 光有各類流程的思想是不夠的,咱們還要有一系列的工具來保證這些思想可以在實踐中有效率地運做。軟件開發很重要的一點不是看你能對多少理論講的頭頭是道,還要看你對相關工具應用的如何,好比Java中單元測試要和JUnit的應用結合起來,建模要和Umbrello或StarUML的應用結合起來。編程學習是一個習而學的過程。 一個常見的公式是:軟件工程=開發流程+工具 鄒欣老師給出的兩個公式:軟件=程序+軟件工程軟件企業=軟件+商業模式 開發流程你們能夠參考學習鄒欣老師的軟件團隊和開發流程。常見的開發流程有:

  • RUP(Rational Unified Process)
  • PSP(Personal Software Process )
  • TSP(Team Software Process )
  • Agile Process
  • ……

敏捷開發(Agile Development)是一種以人爲核心、迭代、按部就班的開發方法。「敏捷流程」是一系列價值觀和方法論的集合。從2001年開始,一些軟件界的專家開始倡導「敏捷」的價值觀和流程,他們確定了流行作法的價值,可是強調敏捷的作法更能帶來價值。

敏捷開發包括不少模式:
圖片描述信息

其中,極限編程(eXtreme Programming,XP)是 是一種全新而快捷的軟件開發方法。XP團隊使用現場客戶、特殊計劃方法和持續測試來提供快速的反饋和全面的交流:

  • XP是以開發符合客戶須要的軟件爲目標而產生的一種方法論
  • XP是一種以實踐爲基礎的軟件工程過程和思想
  • XP認爲代碼質量的重要程度超出人們通常所認爲的程度
  • XP特別適合於小型的有責任心的、自覺自勵的團隊開發需求不肯定或者迅速變化的軟件

XP軟件開發是什麼樣的經過 XP準則來表達:

  • 溝通 :XP認爲項目成員之間的溝通是項目成功的關鍵,並把溝通看做項目中間協調與合做的主要推進因素。
  • 簡單 :XP假定將來不能可靠地預測,在如今考慮它從經濟上是不明智的,因此不該該過多考慮將來的問題而是應該集中力量解決燃眉之急。
  • 反饋 :XP認爲系統自己及其代碼是報告系統開發進度和狀態的可靠依據。系統開發狀態的反饋能夠做爲一種肯定系統開發進度和決定系統下一步開發方向的手段。
  • 勇氣:表明了XP認爲人是軟件開發中最重要的一個方面的觀點。在一個軟件產品的開發中人的參與貫穿其整個生命週期,是人的勇氣來排除困境,讓團隊把局部的最優拋之腦後,達到更重大的目標。代表了XP對「人讓項目取得成功」的基本信任態度。

一項實踐在XP環境中成功使用的依據經過XP的法則呈現,包括:快速反饋、假設簡單性、遞增更改、提倡更改、優質工做。

XP軟件開發的基石是XP的活動,包括:編碼、測試、傾聽、設計。

項目成員用戶成功執行XP活動的技術經過XP實踐來呈現,包括編程、團隊、過程相關的12條實踐:

圖片描述信息

咱們關注其中的編碼標準結對編程代碼集體全部測試重構等實踐。上次實驗已經講過TDD,經過學習這些實踐,能夠造成以測試爲核心的開發流程:

圖片描述信息

敏捷能夠做爲一種作事的方式,掌握好的在之後的工做中也會受益無窮。

(二)編碼標準

編寫代碼一個重要的認識是「程序大多時候是給人看的」,編程標準使代碼更容易閱讀和理解,甚至能夠保證其中的錯誤更少。編程標準包含:具備說明性的名字、清晰的表達式、直截了當的控制流、可讀的代碼和註釋,以及在追求這些內容時一致地使用某些規則和慣用法的重要性。

編碼標準中的版式就是一個很好的例子,版式雖然不會影響程序的功能,但會影響可讀性。程序的版式追求清晰、美觀,是程序風格的重要因素。

咱們常見的是這樣的代碼:

public class CodeStandard { public static void main(String [] args){ StringBuffer buffer = new StringBuffer(); buffer.append('S'); buffer.append("tringBuffer"); System.out.println(buffer.charAt(1)); System.out.println(buffer.capacity()); System.out.println(buffer.indexOf("tring")); System.out.println("buffer = " + buffer.toString()); if(buffer.capacity()<20) buffer.append("1234567"); for(int i=0; i<buffer.length();i++) System.out.println(buffer.charAt(i)); } } 

程序沒有最基本的縮進,讓人讀起來很費勁,這個問題在Eclipse中比較容易解決,咱們單擊Eclipse菜單中的source->Format 或用快捷鍵Ctrl+Shift+F就能夠按Eclipse規定的規範縮進。

代碼標準中很重要的一項是如何給包、類、變量、方法等標識符命名,能很好的命名可讓本身的代碼立立刻升一個檔次。Java中的通常的命名規則有:

  • 要體現各自的含義
  • 包、類、變量用名詞
  • 方法名用動賓
  • 包名所有小寫,如:io,awt
  • 類名第一個字母要大寫,如:HelloWorldApp
  • 變量名第一個字母要小寫,如:userName
  • 方法名第一個字母要小寫:setName
  • ...

標識符名字應當直觀且能夠拼讀,可望文知意,沒必要進行「解碼」,通常採用英文單詞或其組合,便於記憶和閱讀,切忌使用漢語拼音來命名,用詞要準確例如「當前值」應該起名currentValue,寫成nowValue就不許確了,但還湊合,寫成dqz(dang qian zhi 首字母)就是笑話了。

標識符的長度「min-length && max-information」的原則,好比:maxVal 比maxValueUntilOverflow要好些,能夠經過去元音法把變量名變短,如returnValue->rtnVal ,message->msg;通常全局變量用具備說明性的名字,局部變量用短名字:單字符的名字,常見的如i,j,k等用做局部變量。

其餘的能夠參考鄒欣老師寫的代碼規範與代碼複審.

關於代碼標準,能夠遵循如下原則:圖片描述信息

有一些公司好比Google公開了本身的編碼標準,能夠做爲學習不錯的參考,你們參考一下範飛龍老師寫的代碼規範&代碼風格,有興趣的能夠嘗試如何在Eclipse中實踐Google Java Style(中文版),也就是說如何作到「按一下快捷鍵Ctrl+Shift+F就可讓本身的代碼符合Google Java Style(中文版)的要求」,完成後單獨寫一篇Blog,有加分的

(三)結對編程

結對編程是XP中的重要實踐。在結對編程模式下,一對程序員肩並肩、平等地、互補地進行開發工做。他們並排坐在一臺電腦前,面對同一個顯示器,使用同一個鍵盤、同一個鼠標一塊兒工做。他們一塊兒分析,一塊兒設計,一塊兒寫測試用例,一塊兒編碼,一塊兒作單元測試,一塊兒作集成測試,一塊兒寫文檔等。 結對編程中有兩個角色:

  • 駕駛員(Driver)是控制鍵盤輸入的人。
  • 領航員(Navigator)起到領航、提醒的做用。

如何結對編程,爲什麼要結對編程,你們參考一下結對編程和兩人合做 ,重點是:

  • 駕駛員:寫設計文檔,進行編碼和單元測試等XP開發流程。
  • 領航員:審閱駕駛員的文檔、駕駛員對編碼等開發流程的執行;考慮單元測試的覆蓋率;思考是否須要和如何重構;幫助駕駛員解決具體的技術問題。
  • 駕駛員和領航員不斷輪換角色,不要連續工做超過一小時,每工做一小時休息15分鐘。領航員要控制時間。
  • 主動參與。任何一個任務都首先是兩我的的責任,也是全部人的責任。沒有「個人代碼」、「你的代碼」或「他/她的代碼」,只有「咱們的代碼」。
  • 只有水平上的差距,沒有級別上的差別。兩人結對,儘管可能你們的級別資歷不一樣,但無論在分析、設計或編碼上,雙方都擁有平等的決策權利。

團隊精神是好多地方都強調的一個精神,最小的團隊就是一對一的二人團隊了,培養團隊精神從結對編程開始吧。社會生活中人與人相處最重要的是誠信,有同理心,互利。結對編程中你們會出現分歧,如何更有效地合做要作到對事不對人,掌握這些是能夠終生受益的,如何影響小夥伴,你們參考一下兩人合做:要會作漢堡包

 

(以上爲閱讀了解到的)

(四)版本控制(如下爲實驗樓本身動手作的)

XP的集體全部制意味着每一個人都對全部的代碼負責;這一點,反過來又意味着每一個人均可以更改代碼的任意部分。結對編程對這一實踐貢獻良多:藉由在不一樣的結對中工做,全部的程序員都能看到徹底的代碼。集體全部制的一個主要優點是提高了開發程序的速度,由於一旦代碼中出現錯誤,任何程序員都能修正它。 這意味着代碼要放到一個你們都能方便獲取的地方,咱們叫代碼倉庫。這引出另一個話題叫版本控制(Version Control)。

不管是對於團隊仍是個體,版本控制都提供了不少好處。

  • 版本控制提供項目級的 undo(撤銷) 功能: 沒有什麼事情是終結版本, 任何錯誤必須很容易回滾。 假設你在使用世界上最複雜的文字處理系統。 它具有了全部的能想到的功能,就是沒有支持 DELETE(刪除) 鍵。想象你打字的時候得多麼的謹慎和緩慢吧, 特別是一篇超大的文檔的快臨近末尾的時候, 一個不當心就要重頭再來(試想你選中全部的文字, 不當心按了 DELETE 鍵, 由於沒有撤銷功能,只好從新錄入)。編輯文字和版本控制相同,任什麼時候候都須要回滾,不管是一個小時, 一天, 仍是一週, 這讓你的團隊工做自由快速的工做, 並且對於修正錯誤也很是自信。
  • 版本控制容許多人在同一代碼上工做, 只要遵照必定的控制原則就行。 不再會發生諸如一我的覆蓋了另外一我的編輯的代碼,致使那我的的修改無效這樣的狀況。
  • 版本控制系統保存了過去所做的修改的歷史記錄。若是你遭遇到一些驚訝的代碼,經過版本控制系統能夠很容易找出是誰幹的, 修改了什麼, 修改的時間, 若是幸運的話,還能找出緣由。
  • 版本控制系統還支持在主線上開發的同時發佈多個軟件版本。在軟件發佈的時候也不須要整個團隊的中止工做,不須要凍結代碼。
  • 本控制也是項目級的時間機器,你能夠選擇任何一個時間, 精確地查看項目在當時的狀況。 這對研究很是有用, 也是重現之前某個有問題的發佈版本的基礎。

流行的版本控制工具備CVS,SVN,Git等,更多的能夠參考這裏。Git是Linus除了Linux操做系統外的另一個重要發明。

首先開通個人代碼庫功能。

咱們給一個HelloWorld的例子: 首先進入Code目錄,你會發現有了shiyanlou_cs212目錄,進入shiyanlou_cs212,建立HelloWorld目錄,建立並編輯HelloWorld.java文件

以下圖所示:

 

注意一點,往代碼庫提交的代碼必定編譯、運行、測試都沒有問題的代碼,咱們上面測試代碼沒有問題了,就能夠提交了:

 

 

 

如圖:咱們能夠先用git status查看一下代碼狀態,顯示有未跟蹤的代碼,並建議用git add <file>...添加,咱們使用git add HelloWorld.* 把要提交的文件的信息添加到索引庫中。當咱們使用git commit時,git將依據索引庫中的內容來進行文件的提交。這只是在本地操做,關閉實驗環境,會刪除代碼的,若是想把代碼保存到遠程託管服務器中,須要使用git push實驗完成前,必定不要忘了使用git push,不然就是至關於你在Word中編輯了半天文件最後卻沒有保存。 咱們能夠修改HelloWorld.java,以下圖所示:編譯、運行、測試沒有問題後進行提交,這兒使用的是git commit -a

 

咱們能夠經過git log查看代碼提交記錄:

 

 

(五)重構

咱們先看看重構的概念:

重構(Refactor),就是在不改變軟件外部行爲的基礎上,改變軟件內部的結構,使其更加易於閱讀、易於維護和易於變動 。

重構中一個很是關鍵的前提就是「不改變軟件外部行爲」,它保證了咱們在重構原有系統的同時,不會爲原系統帶來新的BUG,以確保重構的安全。如何保證不改變軟件外部行爲?重構後的代碼要能經過單元測試。如何使其更加易於閱讀、易於維護和易於變動設計模式給出了重構的目標。

重構重要嗎?你看看Eclipse菜單中有個refactor菜單就知道了,重構幾乎是現代IDE的標配了

 

咱們在編碼標準中說「給標識符命名」是程序員一項重要技能,之前沒有這個意識,如今知道了怎麼辦?沒問題,上圖中重構的第一項功能就是Rename,能夠給類、包、方法、變量更名字。

修改方法是,用鼠標單擊要改的名字,選擇Eclipse中菜單中的Refactor->Rename...

 

學過C語言的學生學Java時常犯的毛病是不會封裝,該用類的地方都用告終構體。好比要定義一個類Student,會出現這樣的代碼:

 

Eclipse中菜單中的Refactor->Encapsulate Field...

 

注意分析一下重構先後的代碼變化:

 

一樣能夠封裝idage兩個成員變量,結果以下:

 

每次打印學生信息都這麼寫代碼違反了DRY原則,形成代碼重複,正常的重構可使用Eclipse中的Extract Method...

因爲Java中全部的類都有個專門的toString方法,咱們使用Eclipse中Source->Generate toString()... 給Student類產生一個toString方法

修改main的代碼,結果以下:

 

 

 

(如下爲閱讀了解的)

咱們要修改軟件,萬變不離其宗,無非就是四種動機:

  • 增長新功能;
  • 原有功能有BUG;
  • 改善原有程序的結構;
  • 優化原有系統的性能 。

第一種和第二種動機,都是源於客戶的功能需求,而第四種是源於客戶的非功能需求。軟件的外部質量,其衡量的標準就是客戶對軟件功能需求與非功能需求的滿意度。它涉及到一個企業、一個軟件的信譽度與生命力,所以爲全部軟件企業所高度重視。要提升軟件內部質量,毫無疑問就是軟件修改的第三個動機:改善原有程序的結構。它的價值是隱性的,並不體如今某一次或兩次開發中,而是逐漸體如今往後長期維護的軟件過程當中。 高質量的軟件,能夠保證開發人員(即便是新手)可以輕易看懂軟件代碼,可以保證往後的每一次軟件維護均可以輕易地完成(不論軟件經歷了多少次變動,維護了多少年),可以保證往後的每一次需求變動都可以輕易地進行(而不是傷筋動骨地大動)。要作到這幾點其實並不容易,它須要咱們持續不斷地對系統內部質量進行優化與改進。這,就是系統重構的價值。 下面一個重要問題是哪些地方須要重構?有臭味道(Bad Smell)的代碼。 什麼是臭味道?想象一下你打開冰箱門,出來一股臭味道你就知道冰箱裏有東西腐壞了,要清除了。代碼同樣有臭味道:

臭味行列中首當其衝的就是Duplicated Code(重複的代碼)。若是你在一個以上的地點看到相同的程序結構,那麼當可確定:設法將它們合而爲一,程序會變得更好。

  • 最單純的Duplicated Code就是[同一個class內的兩個方法含有相同表達式(expression)]。這時候你須要作的就是採用Extract Method提煉出重複的代碼,而後讓這兩個地點都調用被提煉出來的那一段代碼。
  • 另外一種常見狀況就是[兩個互爲兄弟(sibling)的subclasses內含有相同表達式]。要避免這種狀況,只須要對兩個classes都使用Extract Method,而後再對被提煉出的代碼使用Pull Up Method,將它推入superclass內。
  • 若是代碼之間只是相似,並不是徹底相同,那麼就得運用Extract Method將類似部分和差別部分割開,構成單獨一個方法。而後你可能發現或許能夠運用Form Template Method得到一個Template Method設計模式。
  • 若是有些方法以不一樣的算法作相同的事,你能夠擇定其中較清晰的一個,並使用Substitute Algorithm將其它方法的算法替換掉。
  • 若是兩個絕不相關的classes內出現Duplicaded Code,你應該考慮對其中一個使用Extract Class,將重複代碼提煉到一個獨立class中,而後在另外一個class內使用這個新class。可是,重複代碼所在的方法也可能的確只應該屬於某個class,另外一個class只能調用它,抑或這個方法可能屬於第三個class,而另兩個classes應該引用這第三個class。你必須決定這個方法放在哪兒最合適,並確保它被安置後就不會再在其它任何地方出現。

其餘Bad Smell與相應的重構手法以下表所示:圖片描述信息

Eclipse中Refactor菜單中的重構手法的應用時機以下圖所示:圖片描述信息

一個完整的重構流程包括:

  1. 從版本控制系統代碼庫中Check out code
  2. 讀懂代碼(包括測試代碼)
  3. 發現bad smell
  4. Refactoring
  5. 運行全部的Unit Tests
  6. 往代碼庫中Check in code

 

(六)實踐項目

1、題目簡介

  一個簡單的掃雷小遊戲,在12*12的方格盤上,首先能夠設定雷的個數,而後點擊開始程序就會隨機佈雷,開始遊戲後若是點到雷就會顯示遊戲結束,若是沒有,會出現數字表示周圍一圈雷的個數,以此推理當掃出全部雷將顯示遊戲勝利。

2、實驗結隊分工

 1:談愈敏:負責代碼找尋與編寫部分
 2:黃曉妍:負責代碼修改與運行測試部分 http://www.cnblogs.com/angelahxy/

3、代碼

package shiyan3;

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

public class Frame extends JFrame {

private static final long serialVersionUID = 6929664228252319515L;
JTextField text;
JLabel nowBomb, setBomb;
int BombNum, BlockNum; // 當前雷數,當前方塊數
int rightBomb, restBomb, restBlock; // 找到的地雷數,剩餘雷數,剩餘方塊數

JButton start = new JButton(" 開始 ");
JPanel MenuPamel = new JPanel();
JPanel bombPanel = new JPanel();
Bomb[][] bombButton;

JPanel c;
BorderLayout borderLayout1 = new BorderLayout();
GridLayout gridLayout1 = new GridLayout();

public Frame() {
try {
setDefaultCloseOperation(EXIT_ON_CLOSE);
jbInit();
} catch (Exception exception) {
exception.printStackTrace();
}
}

private void jbInit() throws Exception {
c = (JPanel) getContentPane();
setTitle("掃雷");
c.setBackground(Color.WHITE);
MenuPamel.setBackground(Color.GRAY);
c.setLayout(borderLayout1);
setSize(new Dimension(600, 600));
setResizable(false);

BlockNum = 144;
BombNum = 10;
text = new JTextField("10 ", 3);
nowBomb = new JLabel("當前雷數" + ":" + BombNum);
setBomb = new JLabel("設置地雷數");
start.addActionListener(new Frame1_start_actionAdapter(this));

MenuPamel.add(setBomb);
MenuPamel.add(text);
MenuPamel.add(start);
MenuPamel.add(nowBomb);
c.add(MenuPamel, java.awt.BorderLayout.SOUTH);

bombPanel.setLayout(gridLayout1);
gridLayout1.setColumns((int) Math.sqrt(BlockNum));
gridLayout1.setRows((int) Math.sqrt(BlockNum));
bombButton = new Bomb[(int) Math.sqrt(BlockNum)][(int) Math
.sqrt(BlockNum)];
for (int i = 0; i < (int) Math.sqrt(BlockNum); i++) {
for (int j = 0; j < (int) Math.sqrt(BlockNum); j++) {
bombButton[i][j] = new Bomb(i, j);
// bombButton[i][j].setSize(10, 10);
bombButton[i][j].setFont(new Font("", Font.PLAIN, 14));// 設置字體大小

bombButton[i][j].setForeground(Color.white);
bombButton[i][j].addMouseListener(new Bomb_mouseAdapter(this));
bombButton[i][j]
.addActionListener(new Bomb_actionAdapter(this));
bombPanel.add(bombButton[i][j]);
}
}
c.add(bombPanel, java.awt.BorderLayout.CENTER);

startBomb();
}

/* 開始按鈕 */

public void start_actionPerformed(ActionEvent e) {
int num = Integer.parseInt(text.getText().trim());
if (num >= 5 && num < 50) {
BombNum = num;
startBomb();
} else if (num < 5) {
JOptionPane.showMessageDialog(null, "您設置的地雷數太少了,請重設!", "錯誤",
JOptionPane.ERROR_MESSAGE);
num = 10;
BombNum = num;
} else {
JOptionPane.showMessageDialog(null, "您設置的地雷數太多了,請重設!", "錯誤",
JOptionPane.ERROR_MESSAGE);
num = 10;
BombNum = num;
}
}

/* 開始,佈雷 */

public void startBomb() {
nowBomb.setText("當前雷數" + ":" + BombNum);
for (int i = 0; i < (int) Math.sqrt(BlockNum); i++) {
for (int j = 0; j < (int) Math.sqrt(BlockNum); j++) {
bombButton[i][j].isBomb = false;
bombButton[i][j].isClicked = false;
bombButton[i][j].isRight = false;
bombButton[i][j].BombFlag = 0;
bombButton[i][j].BombRoundCount = 9;
bombButton[i][j].setEnabled(true);
bombButton[i][j].setText("");
bombButton[i][j].setFont(new Font("", Font.PLAIN, 14));// 設置字體大小
bombButton[i][j].setForeground(Color.BLUE);
rightBomb = 0;
restBomb = BombNum;
restBlock = BlockNum - BombNum;
}
}

for (int i = 0; i < BombNum;) {
int x = (int) (Math.random() * (int) (Math.sqrt(BlockNum) - 1));
int y = (int) (Math.random() * (int) (Math.sqrt(BlockNum) - 1));

if (bombButton[x][y].isBomb != true) {
bombButton[x][y].isBomb = true;
i++;
}
}
CountRoundBomb();
}

/* 計算方塊周圍雷數 */

public void CountRoundBomb() {
for (int i = 0; i < (int) Math.sqrt(BlockNum); i++) {
for (int j = 0; j < (int) Math.sqrt(BlockNum); j++) {
int count = 0;
// 當須要檢測的單元格自己無地雷的狀況下,統計周圍的地雷個數
if (bombButton[i][j].isBomb != true) {
for (int x = i - 1; x < i + 2; x++) {
for (int y = j - 1; y < j + 2; y++) {
if ((x >= 0) && (y >= 0)
&& (x < ((int) Math.sqrt(BlockNum)))
&& (y < ((int) Math.sqrt(BlockNum)))) {
if (bombButton[x][y].isBomb == true) {
count++;
}
}
}
}
bombButton[i][j].BombRoundCount = count;
}
}
}
}

/* 是否挖完了全部的雷 */

public void isWin() {
restBlock = BlockNum - BombNum;
for (int i = 0; i < (int) Math.sqrt(BlockNum); i++) {
for (int j = 0; j < (int) Math.sqrt(BlockNum); j++) {
if (bombButton[i][j].isClicked == true) {
restBlock--;
}
}
}

if (rightBomb == BombNum || restBlock == 0) {
JOptionPane.showMessageDialog(this, "您挖完了全部的雷,您勝利了!", "勝利",
JOptionPane.INFORMATION_MESSAGE);
startBomb();
}
}

/** 當選中的位置爲空,則翻開周圍的地圖* */

public void isNull(Bomb ClickedButton) {
int i, j;
i = ClickedButton.num_x;
j = ClickedButton.num_y;

for (int x = i - 1; x < i + 2; x++) {
for (int y = j - 1; y < j + 2; y++) {
if (((x != i) || (y != j)) && (x >= 0) && (y >= 0)
&& (x < ((int) Math.sqrt(BlockNum)))
&& (y < ((int) Math.sqrt(BlockNum)))) {
if (bombButton[x][y].isBomb == false
&& bombButton[x][y].isClicked == false
&& bombButton[x][y].isRight == false) {
turn(bombButton[x][y]);
}
}
}
}
}

/* 翻開 */

public void turn(Bomb ClickedButton) {
ClickedButton.setEnabled(false);
ClickedButton.isClicked = true;
if (ClickedButton.BombRoundCount > 0) {
ClickedButton.setText(ClickedButton.BombRoundCount + "");
} else {
isNull(ClickedButton);
}
}

/* 左鍵點擊 */

public void actionPerformed(ActionEvent e) {
if (((Bomb) e.getSource()).isClicked == false
&& ((Bomb) e.getSource()).isRight == false) {
if (((Bomb) e.getSource()).isBomb == false) {
turn(((Bomb) e.getSource()));
isWin();
}

else {
for (int i = 0; i < (int) Math.sqrt(BlockNum); i++) {
for (int j = 0; j < (int) Math.sqrt(BlockNum); j++) {
if (bombButton[i][j].isBomb == true) {
bombButton[i][j].setText("b");
}
}
}
((Bomb) e.getSource()).setForeground(Color.RED);
((Bomb) e.getSource()).setFont(new Font("", Font.BOLD, 20));
((Bomb) e.getSource()).setText("X");
JOptionPane.showMessageDialog(this, "你踩到地雷了,按肯定重來", "踩到地雷", 2);
startBomb();
}
}
}

/* 右鍵點擊 */

public void mouseClicked(MouseEvent e) {
Bomb bombSource = (Bomb) e.getSource();
boolean right = SwingUtilities.isRightMouseButton(e);

if ((right == true) && (bombSource.isClicked == false)) {
bombSource.BombFlag = (bombSource.BombFlag + 1) % 3;
if (bombSource.BombFlag == 1) {
if (restBomb > 0) {
bombSource.setForeground(Color.RED);
bombSource.setText("F");
bombSource.isRight = true;
restBomb--;
} else {
bombSource.BombFlag = 0;
}
} else if (bombSource.BombFlag == 2) {
restBomb++;
bombSource.setText("Q");
bombSource.isRight = false;
} else {
bombSource.setText("");
}

if (bombSource.isBomb == true) {
if (bombSource.BombFlag == 1) {
rightBomb++;
} else if (bombSource.BombFlag == 2) {
rightBomb--;
}
}
nowBomb.setText("當前雷數" + ":" + restBomb);
isWin();
}
}

public static void main(String[] args) {
Frame frame = new Frame();
frame.setVisible(true);
}
}

class Frame1_start_actionAdapter implements ActionListener {
private Frame adaptee;

Frame1_start_actionAdapter(Frame adaptee) {
this.adaptee = adaptee;
}

public void actionPerformed(ActionEvent e) {
adaptee.start_actionPerformed(e);
}
}

// //////////////////////////
class Bomb extends JButton {

private static final long serialVersionUID = 2550424246611071294L;
int num_x, num_y; // 第幾號方塊
int BombRoundCount; // 周圍雷數
boolean isBomb; // 是否爲雷
boolean isClicked; // 是否被點擊
int BombFlag; // 探雷標記
boolean isRight; // 是否點擊右鍵

public Bomb(int x, int y) {
num_x = x;
num_y = y;
BombFlag = 0;
BombRoundCount = 9;
isBomb = false;
isClicked = false;
isRight = false;
}
}

class Bomb_actionAdapter implements ActionListener {
private Frame adaptee;

Bomb_actionAdapter(Frame adaptee) {
this.adaptee = adaptee;
}

public void actionPerformed(ActionEvent e) {
adaptee.actionPerformed(e);
}
}

class Bomb_mouseAdapter extends MouseAdapter {
private Frame adaptee;

Bomb_mouseAdapter(Frame adaptee) {
this.adaptee = adaptee;
}

public void mouseClicked(MouseEvent e) {
adaptee.mouseClicked(e);
}
}

4、運行結果截圖:

 

初始界面:

 

設置雷數爲10,開始遊戲,會顯示數字:

 

踩到雷,遊戲結束:

 

掃完雷,遊戲勝利:

 

 

5、心得體會

經過結對項目,我認識到了合做的重要性,緊密的合做可以提升咱們的能力。代碼測試過程當中出現不少錯誤,但通過互相的合做和探討,加以改進,即可以成功運行。

 

統計的PSP(Personal Software Process)時間

 

步驟

耗時(min)

百分比

需求分析

20~30

10%

設計

40~50

20%

代碼實現

90~100

40%

測試

40~50

20%

分析總結

20~25

10%

相關文章
相關標籤/搜索