第二次結對編程做業

一、連接

隊友博客連接戳這裏
本次做業博客連接戳這裏
github項目地址
UI演示視頻javascript

二、具體分工

  • 王景弘:負責實現AI部分,設計出牌算法,編寫單元測試,提供算法思路、關鍵、改進和性能分析等博客內容。
  • 陳靖雯:負責實現UI部分,用接口鏈接算法造成最終文件,提供UI部分博客內容,用markdown格式編寫博客內容。

三、PSP表格

PSP2.1 Personal Software Process Stages 預估耗時
(小時)
實際耗時
(小時)
Planning 計劃 1 1.5
· Estimate · 估計這個任務須要多少時間 45 50
Development 開發 5 5
· Analysis · 需求分析 (包括學習新技術) 8 7.5
· Design · 生成設計文檔 0.5 0.5
· Design Review · 設計複審 0.2 0.3
· Coding Standard · 代碼規範 (爲目前的開發制定或選擇合適的規範) 1 1
· Design · 具體設計 4 5
· Coding · 具體編碼 15 20
· Code Review · 代碼複審 1 2
· Test · 測試(自我測試,修改代碼,提交修改) 2 3
Reporting 報告 1 0.8
· Test Report · 測試報告 1 0.5
· Size Measurement · 計算工做量 0.1 0.1
· Postmortem & Process Improvement Plan · 過後總結, 並提出改進計劃 0.5 0.5
  · 合計 45.3 50.2

四、解題思路描述與設計實現說明

(1)網絡接口的使用

按照所給的接口文檔,調用所給接口。本次做業採用html、css、javascript實現UI部分,須要新建一個XMLHttpRequest對象,向所給地址發送GET或POST請求,須要在控制檯觀察是否響應以便修改錯誤。成功響應的請求會返回須要的內容。發送的數據用JSON.stringify()轉換成json字符串發送,返回的json字符串用JSON.parse()轉換爲JS對象,再逐一匹配標籤id顯示到頁面中或進行其餘操做。因爲用到Token認證,須要用cookie保存token值並加入到請求頭中。php

(2)代碼組織與內部實現設計(類圖)

(3)說明算法的關鍵與關鍵實現部分流程圖

算法關鍵:

  • 實現的時候須要用到不少重複的switch和if/else語句。
  • 發到的牌按大小排完序以後,存入數組中,按照相同的牌的數量來分類。
  • 給每種牌型賦予權重值。
  • 利用switch語句不斷的找到手牌中全部的牌型。
  • 以後將最大的拿出來留給後墩,而後剩下的牌再去尋找最大的牌型留給中墩,前墩的牌型就放在最後用剩下來的三張牌補進去,直到三道都有牌型。
  • 再把牌放到Choice.java中建立的三個數組中(即前中後墩)
  • 最後轉換爲接口所需的數據格式

關鍵實現部分流程圖

五、關鍵代碼解釋

AI部分:
最開始發到牌後,將牌從小到大排序,存儲到數組中。css

public void change(List<Card> handCard)
    {
        Collections.sort(handCard,new Comparator<Card>()          //從小到大排序
        {
            public int compare(Card c1, Card c2) 
            {  
                int i = c1.rank - c2.rank;  
                if(i == 0)  
                    return c1.type - c2.type;    
                return i;
            }   
        });
    arrange(handCard);        //將牌整理到arr中

將排好序的牌按照相同的牌的數量來對數組進行分類html

for(int i=0;i<handCard.size();i++)
    { 
        if((i+1)<handCard.size()&&handCard.get(i).rank==handCard.get(i+1).rank)
        if((i+2)<handCard.size()&&handCard.get(i).rank==handCard.get(i+2).rank)
        if((i+3)<handCard.size()&&handCard.get(i).rank==handCard.get(i+3).rank)    //四張相同的牌
        {
            arr.ranknum4.addAll(handCard.subList(i,i+4));
            i+=3;
        }
        else                                               //三張相同的牌
        {
            arr.ranknum3.addAll(handCard.subList(i,i+3));
            i+=2;
        }
        else                                   //兩張相同的牌
        {
            arr.ranknum2.addAll(handCard.subList(i,i+2));
            i+=1;
        }
        else                                  //沒有相同的牌
        {
            arr.ranknum1.add(handCard.get(i));
        }
    }

經過判斷讀取出的對子數目和剩下的牌的數目來判斷是否有牌型
此處爲判斷是否有四套三條和五對三條java

if(arr.ranknum3.size()==12||(arr.ranknum3.size()==9&&arr.ranknum4.size()==4))              //四套三條
    {
        choice=tochoice(handCard);
        choice.headType="sitaosantiao";
        return;
    }
    if(arr.ranknum2.size()==10&&arr.ranknum3.size()==3)       //五對三條
    {
        choice=tochoice(handCard);
        choice.headType="wuduisantiao";
        return;
    }

經過arr.ranknum4.size和arr.ranknum3.size的大小來判斷牌型,而且改變Choice.java中的前中後墩數組(choice.headType/midType/endType)來進行出牌時的文字說明git

if(arr.ranknum4.size()==4)                  //尾道爲鐵支
    {
        choice.end.addAll(arr.ranknum4);
        card.removeAll(choice.end);
        arrange(card);
        if(arr.ranknum3.size()==6)              //中道是葫蘆
        {
            if(!arr.ranknum2.isEmpty())
            {
                choice.mid.addAll(arr.ranknum3.subList(3, 6));
                choice.mid.addAll(arr.ranknum2);
                choice.midType="hulu";
                choice.head.addAll(arr.ranknum3.subList(0, 3));
                choice.headType="santiao";
                card.removeAll(choice.head);
                card.removeAll(choice.mid);
                choice.end.addAll(card);
                choice.endType="tiezhi";
                return;
            }
            else
            {
                choice.mid.addAll(arr.ranknum3.subList(1, 6));
                card.removeAll(choice.mid);
                choice.end.add(card.get(0));
                choice.head.addAll(card.subList(1, 4));
                choice.endType="tiezhi";
                choice.midType="hulu";
                choice.headType="wulong";
                return;
            }
        }

UI部分:
登陸的請求成功後會返回一個token,要用cookie保存,以後的請求要用split函數從cookie中提取出token放在其餘須要token的請求的請求頭中。github

xhr.addEventListener("readystatechange", function () {
      if (this.readyState === this.DONE) {
      console.log(this.responseText);
      var JsonObj = JSON.parse(this.responseText);
      if(JsonObj.status==0)
      {
        document.cookie = JsonObj.data.token;
        valid();
      }
      }
      });
var token = document.cookie.split(";")[0];
    xhr.setRequestHeader("x-auth-token",token);

進行下一次查詢時須要刪除以前表格中存在的數據,用到deleteRow函數將存在的行刪除,若按從下標小到大的順序刪除,在刪除過程當中行的下標會不斷改變,因此要從大到小刪除。算法

var tb = document.getElementById('table');
    var rowNum=tb.rows.length;
    for (var j=rowNum-1;j>=0;j--) //下標會變化,要從後往前刪
    {
        tb.deleteRow(j);
    }

六、性能分析與改進

(1)描述改進思路

一開始只是單純的想全用if/else語句來進行全部牌型的羅列但發現工程量實在是太大了,仍是得逐步分析才能獲得解法。後面想到先對花色和點數綜合排序以後填入數組進行第一次分類(分點數大小的類),而後用判斷數組大小的方式來進行第二次分類(分牌型的類,如對子三條之類的),再根據第二次分類出的結果來判斷有沒有特殊牌型(如全大全小、至尊青龍、五對三條之類的),最後給每種判斷出的牌型賦予權重,用以判斷什麼牌型該放在什麼位置。在進行完判斷牌型的步驟以後再進行一下文字說明。json

(2)展現性能分析圖和程序中消耗最大的函數

七、單元測試

public static void main(String[] args) {
        List<Card> allCards = new ArrayList<>();
        Random random = new Random();
        CardController cardController = new CardController();
        for (int i = 1;i <= 4; i++){
            for (int j = 1; j <= 13; j++){
                allCards.add(new Card(j,i));
            }
        }

        for (int i = 0; i < 10; i++){
            List<Card> tempCards = new ArrayList<>();
            List<Card> cards = new ArrayList<>();
            tempCards.addAll(allCards);
            for (int j = 0; j < 13; j++){
                Card card = tempCards.get(random.nextInt(52 - j));
                cards.add(card);
                tempCards.remove(card);
            }
            String cardStr = "";
            for (int j = 0; j < 13; j++){
                Card card = cards.get(j);
                cardStr += card.toString();
                if (j < 12)
                    cardStr += " ";
            }
            JSONObject jsonObject = new JSONObject();
            try {
                jsonObject.put("id",0);
                jsonObject.put("card",cardStr);
            } catch (JSONException e) {
                e.printStackTrace();
            }

            System.out.println(cardController.card2(jsonObject.toString()));;

        }
    }

每次隨機構造13張牌,而且轉化爲符合json格式的字符串,再調用接口,得出結果後端

八、Github的代碼簽入記錄


九、遇到的代碼模塊異常或結對困難及解決辦法

(1)問題描述

UI部分:

  • 不熟悉如何將json數據顯示在頁面中。
  • 接口調用不知道如何實現。
  • http請求一直失敗,顯示未受權。

AI部分:

  • 由於剛開始接觸java,關鍵的算法也是束手無策。
  • 在調用接口的時候也遇到了不會調接口,每一個請求的寫法不會,無數次請求失敗。

(2)作過哪些嘗試

UI部分:

  • 在百度等渠道瘋狂搜索解決方法,查找以前練習的代碼。
  • 詢問同窗。

AI部分:

  • 接口和java算法的問題都是老老實實看資料學習

(3)是否解決

UI部分:
已解決。(如下每一點與問題一一對應)

  • 正確使用javascript,理清標籤父子關係,使用json.parse()將json格式轉化成js對象。
  • 接口文檔有code generation,根據須要修改。
  • token值沒有保存,設置的請求頭有錯,使用了document.cookie解決。

AI部分:

  • 已解決。

(4)有何收穫

由於剛剛接觸java不少知識都不甚瞭解
此次比較複雜的程序設計也算是逼迫我在ddl以前嘗試了一次敏捷開發
雖然不少代碼都是對着查到的資料現學現用,但也算是收穫了很多java語法、算法相關的知識


十、評價你的隊友

(1)值得學習的地方

  • 界面設計得很漂亮,對UI設計有經驗。

(2)須要改進的地方

  • 沒啥須要改進的地方已經作得很好了

    十一、學習進度條

    第N周 新增代碼(行) 累計代碼(行) 本週學習耗時(小時) 累計學習耗時(小時) 重要成長
    1 476 476 15 15 熟悉了java的基本語法
    2 421 897 10 25 經過練習,掌握了數組的多種用法
    3 1300 2197 25 50 完善了剩餘的算法,學習了接口的使用

製做UI時查找到的實用資料

HTML頁面跳轉的5種方法
用js實現動態添加表格數據
JSON.parse()
js中設置元素class的三種方法小結
js中刪除table裏全部行
詳細介紹NW.js基本使用
HTML網頁打包成EXE可執行文件
將Token添加到請求頭Header中
JSON.parse() 與 JSON.stringify() 簡單使用
Session與Token認證機制 先後端分離下如何登陸
js使用sessionStorage、cookie保存token

相關文章
相關標籤/搜索
本站公眾號
   歡迎關注本站公眾號,獲取更多信息