第二次結對編程做業

博客連接和Github連接

結對同窗博客連接javascript

本做業博客連接html

Github項目地址前端

具體分工

高星負責前端界面和美工vue

我負責13水的算法部分和前端的接口處理java

psp表格

PSP2.1 Personal Software Process Stages 預估耗時(分鐘) 實際耗時(分鐘)
Planning 計劃
• Estimate • 估計這個任務須要多少時間 2500 7070
Development 開發
• Analysis • 需求分析 (包括學習新技術) 120 700
• Design Spec • 生成設計文檔 15 20
• Design Review • 設計複審 10 30
• Coding Standard • 代碼規範 (爲目前的開發制定合適的規範) 5 20
• Design • 具體設計 20 120
• Coding • 具體編碼 2100 5160
• Code Review • 代碼複審 30 40
• Test • 測試(自我測試,修改代碼,提交修改) 200 980
Reporting 報告
• Test Report • 測試報告 20 30
• Size Measurement • 計算工做量 10 5
• Postmortem & Process Improvement Plan • 過後總結, 並提出過程改進計劃 10 10
合計 2540 7115

解題思路與設計實現說明

網絡接口的使用ios

用的vue的axiosgit

一開始計劃用java寫13水 由於接口部分的處理因此最後選擇用了前端的框架vue,原本打算用vue的resource(由於以前學的這個)可是想到這個如今幾乎沒啥人用,最後用了axiosgithub

axios的get和post方法都是去官方文檔看的,慢慢學習web

此次代碼有不少不完善的地方其中有一點就體如今vue接口部分的使用,咱們兩沒有把axios封裝好,致使咱們兩接口部分的代碼不太好(簡直差到沒眼看)這部分應該再學習,每次寫代碼都發現好多不足和不會(前端沒有咱們兩想象中的那麼容易,菜是真菜)算法

代碼組織與內部實現

  1. 工程結構

  1. src中結構(內部實現設計)

  1. 對代碼詳細說明

首先代碼有五個主要界面 (登入界面,開始界面,遊戲牌型顯示界面,排行榜顯示界面,歷史記錄界面)其中註冊界面看成一個彈窗寫在登入界面中,歷史記錄詳情也是做爲一個彈窗寫在歷史記錄中(沒有在另外寫兩個主要界面)

界面名稱 界面功能
UserLogin.vue 這是登入界面用於用戶登入的,其中註冊界面也在其中
BeginView.vue 這是登陸成功後進入的界面,用戶能夠選擇加入戰局,或者查看歷史排行榜
CardShowVIew.vue 這是用戶加入戰局,此頁面用於顯示接收後端接口提供卡牌信息,通過ai處理後把處理好的牌的出牌的樣式顯示再界面上,而且把處理的卡牌信息經過發給後端
HistoryList.vue 這是用來查看歷史記錄的頁面,能夠經過查看詳情獲取更多當局的信息
RankingList.vue 這個用於查看排名總榜的頁面

界面的跳轉用的vue的路由處理

Token認證和用戶id用的vuex存儲在localStorage中,在把判斷哪一個頁面須要用到Token,讓它自動加進去,核心代碼以下

axios.interceptors.request.use(
config => {
if (
config.url === 'https://api.shisanshui.rtxux.xyz/auth/login'
) {
//若是是登陸和註冊操做,則不須要攜帶header裏面的token
} else {
if (localStorage.getItem('Authorization')) {
  config.headers['X-Auth-Token'] = localStorage.getItem('Authorization')
}
}
return config
},
error => {
return Promise.reject(error)
}
)

其中咱們兩的算法寫在了CardShowVIew中,前端如何在鏈接一個後端處理代碼我不會(能力不足能力不足,這也是代碼的一大缺點)

由於沒有用到類,因此我類圖就沒有寫了,給出前面給出了內部設計

​ 4.代碼界面展現

登入界面(UserLogin)

登入成功界面(BeginView)

開始遊戲界面(CardShowVIew)

點擊開啓戰局以後,界面顯示ai出牌的樣式

排行總榜(RankingList)

歷史總榜(HistoryList)

歷史總榜詳情

算法的關鍵與關鍵實現部分流程圖

算法關鍵

算法關鍵1 有不少個數組同時記錄牌的狀況(不用對象數組的緣由後面有講)

算法關鍵2 給把牌分等級,這樣才方便比較J Q K A這樣的牌(2就是等級2,...,J就是等級11,Q就是等級12,K就是等級13,A就是等級14)而且經過等級給牌排序(對應數組也要變化)

算法關鍵3 有個數組放重複牌的數量 有個數組放四個花色(方塊,梅花,黑桃,紅桃)的數量,這樣方便找到炸彈 葫蘆 三條 同花的狀況

算法關鍵4 最大的放後墩 在挑出牌放中墩 剩下最後三張放前墩

(爲何算法和代碼這麼的面向過程 我用的js 面向對象有點難用 主要是本身水平不夠 )

算法關鍵5 對於特殊牌型用的鴕鳥算法 咱們兩以爲咱們兩運氣沒這麼好,會碰到特殊牌型(主要是代碼寫的差,不會 反思本身,兩個菜雞)

下表格是算法中使用的各個數組的用途

使用的數組名 其功能
cardsUse[13] 用於看存放的牌是否使用 初始值爲false 使用後爲true
cardsTotal[13] 用於存放*2 這樣的完整字符串
cardsDegree[13] 用於存放牌的等級 2就是等級2以此類推
cardsType[13] 牌的類型 0表示# 1表示$ 2 表示& 3表示*(這樣後期渲染到頁面的時候方便)
cardsNumber[13] 這個等級的牌有幾張 K有4張 對應的K數就有幾張
cardsTypeNumber[4] 用於存放#$&*有幾張 好比cardTypeNumber[0]=4 表示 #號牌有四張 方便找同花的狀況
houdun[5] 用於存放找到的後墩
zhongdun[5] 用於存放找到的中墩
qiandun[3] 用於存放找到的前墩
sendCards[3] 用於存放處理好的牌,而後發給後端接口

下表格是使用到的函數

使用的函數 功能
PlayAndShowCards() 用於從接口得到信息,以及調用各個函數,以及返回處理後的牌給接口
setCards() 用於初始各個數組的狀況,處理最開始從接口得到的信息
decideHoudun() 用於選擇出後墩
decideZhongdun() 用於選擇出中墩
decideQiandun() 用於選擇出前墩
showCards() 用於渲染到頁面上(改變img屬性的src 顯示牌在界面上)

算法流程圖

後墩流程圖

中墩思路和後墩差很少,不一樣的是其中中墩須要判斷牌是否被使用過,即cardsUsed[i]是否爲false,若是true表示牌被使用了。則不能接着使用

關鍵代碼解釋

重要的有價值的代碼片斷

var cards=this.card.split(" ");
  for(var i=0;i<=12;i++){
  
    this.cardsUse[i]=false;
    this.cardsTotal[i]=cards[i];
    this.cardsType[i]=cards[i].slice(0,1);
  
    if(this.cardsType[i]==="#"){
      this.cardsTypeNumber[0]++;
      this.cardsType[i]=0;
    }else if(this.cardsType[i]==="$"){
      this.cardsTypeNumber[1]++;
      this.cardsType[i]=1
    }else if(this.cardsType[i]==="&"){
      this.cardsTypeNumber[2]++;
      this.cardsType[i]=2
    }else if(this.cardsType[i]==="*"){
      this.cardsTypeNumber[3]++;
      this.cardsType[i]=3
    }
   
    if(cards[i].slice(1,2)==="A"){
      this.cardsDegree[i]=14;
      this.cardsDegree[i]=parseInt(this.cardsDegree[i]);
      this.cardsNumber[14]++;
    }else if(cards[i].slice(1,2)==="K"){
      this.cardsNumber[13]++;
      this.cardsDegree[i]=13;
    }else if(cards[i].slice(1,2)==="Q"){
      this.cardsDegree[i]=12;
      this.cardsNumber[12]++;
    }else if(cards[i].slice(1,2)==="J"){
      this.cardsNumber[11]++;
      this.cardsDegree[i]=11;
    }else if(cards[i].slice(1,2)==="1"){
      this.cardsDegree[i]=10;
      this.cardsNumber[10]++;
    }
    else{
      this.cardsDegree[i]=parseInt(cards[i].slice(1,2));
      this.cardsNumber[this.cardsDegree[i]]++;
    }
  
}
//如下是經過等級給這些數值排序
for (var i = this.cardsDegree.length - 1; i > 0; i--) {
    for (var j = 0; j < i; j++) {
      if (this.cardsDegree[j] < this.cardsDegree[j + 1]) {
        [this.cardsDegree[j], this.cardsDegree[j + 1]] = [this.cardsDegree[j + 1], this.cardsDegree[j]];
        [this.cardsTotal[j], this.cardsTotal[j + 1]] = [this.cardsTotal[j + 1], this.cardsTotal[j]];
        [this.cardsType[j], this.cardsType[j + 1]] = [this.cardsType[j + 1], this.cardsType[j]];
      }
    }
  }

根據接口接收到的信息,split(' ')把信息分出,再經過slice()完善各個數組的信息

cardsDegree和cardsTotal和cardsType和cardsUse這些一一對應關係(不用對象數組是由於js對象數組太難用了 不要笑我憨憨)

經過數組cardsDegree 能夠比較牌大小 用於排序查看等級等

經過數值cardsType表示對應的值牌的類型

經過cardsNumber數組(下標表示牌的等級)數值表示該等級的牌有幾張 排序時不用動cardsNumber它自己就是排好了順序(爲0就表示沒有該牌 或者被用掉了)

eg:

cardsDegree[0]=13 表示最大的牌爲等級爲13的牌 也就是K

cardsType[0]=3 該牌類型爲*

cardsNumber[13]=4 表示等級13的牌有4張 也就是K有四張的意思

//找牌   
   var houdun=[]
   var flag=-1;
    var max1=0;//有多少重複的牌
     var max2=0;
  
         //看是否有炸彈 有葫蘆(重複牌數)
   for(var i=1;i<=14;i++)
   {
     if(max1<this.cardsNumber[i])
     max1=this.cardsNumber[i];
   }
   //看是否有同花
   for(var i=0;i<4;i++)
   {
     if(max2<this.cardsTypeNumber[i])
       {
         
         max2=this.cardsTypeNumber[i];
       }
   }
 
 
   if(max1>2){

        flag=-1;
      
       for(var j=1;j<=14;j++){
             
             if(this.cardsNumber[j]==5-max1)                                  
             {
               flag=j;
               break
             }
           }
       
           
       if(flag>0){

         for(var j=0;j<=12;j++)
         {
           
           if(this.cardsDegree[j]===flag&&this.cardsUse[j]===false)
           {
             
             this.cardsUse[j]=true;
             this.cardsNumber[this.cardsDegree[j]]--
             this.cardsTypeNumber[this.cardsType[j]]--
             houdun.push(this.cardsTotal[j]); 
           }
         }
       for(var j=1;j<=14;j++){ 
             if(this.cardsNumber[j]==max1)
             {
               flag=j;  
               
             }
           }
               
           for(var j=0;j<=12;j++)
           {
             
             if(this.cardsDegree[j]===flag)
             {
               
               this.cardsUse[j]=true;
               this.cardsNumber[this.cardsDegree[j]]--;
               this.cardsTypeNumber[this.cardsType[j]]--
               houdun.push(this.cardsTotal[j]);
               
             }
           }
    
       }
       //拆雙數的狀況
      else if(max1===4&&flag===-1){
             
         for(var j=1;j<=14;j++){
             if(this.cardsNumber[j]==5-max1+1)                                  
             {
               flag=j;
              
               break
             }
           }
         for(var j=0;j<=12;j++)
         {
           
           if(this.cardsDegree[j]===flag&&this.cardsUse[j]===false)
           {
             
             this.cardsUse[j]=true;
             this.cardsNumber[this.cardsDegree[j]]--
             this.cardsTypeNumber[this.cardsType[j]]--
             houdun.push(this.cardsTotal[j]); 
             break;
           }
         }
 
           for(var j=1;j<=14;j++){ 
             if(this.cardsNumber[j]==max1&&this.cardsUse[this.cardsNumber[j]]===false)
             {
               flag=j;  
               
             }
           }
               
           for(var j=0;j<=12;j++)
           {
             
             if(this.cardsDegree[j]===flag)
             {
               
               this.cardsUse[j]=true;
               this.cardsNumber[this.cardsDegree[j]]--;
               this.cardsTypeNumber[this.cardsType[j]]--
               houdun.push(this.cardsTotal[j]);
               
             }
           }
    
           
         }
     }
         
           
   //同花
   if(max2>=5&&flag<0){
     for(var i=0;i<=3;i++){
       if(this.cardsTypeNumber[i]>=5)
       {
         
           flag=i
           
       }
     }
     for(var i=0;i<13;i++)
     {
       if(this.cardsType[i]===flag&&houdun.length<=4){
         
         //this.cardsType[i]--
         this.cardsTypeNumber[this.cardsType[i]]--
         this.cardsNumber[this.cardsDegree[i]]--
         this.cardsUse[i]=true
         houdun.push(this.cardsTotal[i])
        
       }
     }
   }
   //只有2張
   else if(max1<=2){
     for(var i=0;i<=12;i++){
      
       if(this.cardsNumber[this.cardsDegree[i]]===2&&houdun.length<4)
       {
         
         houdun.push(this.cardsTotal[i])
        this.cardsTypeNumber[this.cardsType[i]]--
        
         this.cardsUse[i]=true
           
       }
       
     }
       for(var i=0;i<=12;i++){
       if(this.cardsUse[i]===true){
         this.cardsNumber[this.cardsDegree[i]]=0
       }
     }
         for(var j=1;j<=14;j++){
             
             if(this.cardsNumber[j]===1)                                  
             {
               flag=j;
               break
             }
           }
       for(var j=0;j<=12;j++)
       {
         
         if(this.cardsDegree[j]===flag)
         {
           
           this.cardsUse[j]=true;
           this.cardsTypeNumber[this.cardsType[j]]--
           houdun.push(this.cardsTotal[j]);
           
         }
       }
   }

分出後墩的代碼(具體解釋能夠看前面的流程圖)

性能分析與改進

改進思路

圖片加載的時候太慢了,(並且我圖片有特別多)算法我沒有用到太多的循環,性能差就差在加載資源的時候,改進思路是減少資源大小,思路是使用webp格式的圖片,其具備更優的圖像數據壓縮算法,同等畫面質量下,體積比jpg、png少了25%以上,

性能分析圖和程序中消耗最大的函數

性能分析圖

消耗最大的函數是PlayAndShowCards()

單元測試

單元測試代碼

import Vue from 'vue'
import RankingList from '@/components/RankingList'

describe('RankingList.vue', () => {
it('should render correct contents', () => {
const Constructor = Vue.extend(RankingList)
const vm = new Constructor().$mount()
expect(vm.$el.querySelector('.bg .username').textContent)
 .toEqual('用戶名')
 expect(vm.$el.querySelector('.bg .userscore').textContent)
 .toEqual('得分')
})
})


describe('HistoryList.vue', () => {
it('should render correct contents', () => {
const Constructor = Vue.extend(HistoryList)
const vm = new Constructor().$mount()
expect(vm.$el.querySelector('.loginbg .buttons img').src)
 .toBe('http://localhost/assets/ReturnGame.png')

})
})

單元測試的函數以及思路

​ 測試的是部分組件是否成功渲染 構造測試函數的思路是看圖片是否可以成功渲染(爲啥不測試js的函數 由於數據的內容咱們兩用圖片顯示到界面上了 最重要的是加上vue的測試我不太熟悉 學了一段時間好像仍是不能熟練的拿去測試js的函數 兩我的都不太會用vue的單元測試 )咱們兩把兩個主要頁面的組件都進行了測試

GitHub的代碼簽入記錄

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

(ps 問題嘗試解決收穫與前面的點一一對應 1對應1 )

問題描述

  1. 一開始考慮到算法佔主要部分 因此打算用java來寫 可是發現java界面處理和網絡接口處理對我兩來講有點難辦,決定界面用vue 算法用java,從而實現算法和界面分離(想象美好現實殘忍
  2. 用js寫算法 決定用對象數組存每一個卡牌的信息 後來發現。。。js的對象數組真真真真太難用了 我用數組名[i].屬性名這樣取一個屬性值取不出 會報一個 "TypeError:cannot read property '屬性名' of undefined 這樣的錯誤
  3. vue的token又是一個徹底沒有接觸過的知識點
  4. vue的網絡接口應用不熟練,以及vuex共享數據,還有localStorage
  5. 前端界面的自適應
  6. 前端的單元測試

作過哪些嘗試

  1. 研究不少百度上的資料 發現我目前學到的知識還作不到 還要再學不少新知識(javaee的框架 惋惜我servlet都還在入門 最近都沒怎麼有空學它了 並且這幾天是來不及的學框架而且運用上的 我tcl 若是有大佬幾天實現了算法和界面分離 別嘲笑我菜)
  2. 這個問題整了我很久 百度也沒有百度到說明結果 去後來查了js對象數組看了幾篇博客 發現要for item in 數組名[i]一個個遍歷js的屬性才能取 當我發現怎麼解決了致命問題又來了for(var i=12;i<=0;i++)這樣倒序去讀這個對象數組它又報錯了 我也是有小(da)脾氣的人呢 我最後用好幾個數組存每張卡牌信息
  3. 百度vue的token 一篇篇博客慢慢看 看實例看源碼 知道了Token是什麼
  4. 百度一個個研究,先寫幾個小的組件測試熟悉如下(
  5. 多看看樣例
  6. 太難了,瞭解了單元測試是什麼,可是如何對vue單元測試又是一個新的知識點,接着百度學習法

是否解決

  1. 算解決了?我用js寫算法 雖然會不會有點憨憨(好吧我以爲很憨)
  2. 解決了,我不用js的對象數組了!!!我用好幾個數組存卡片的信息(很傻 致使代碼可讀性比較差)
  3. 解決了!!!
  4. 搞定了!!!
  5. 算解決一半,(自打臉,自適應不行啊,我以爲也是我此次寫的代碼不足之處,寫到總結的時候發現本身還有好多不足須要改進)
  6. 解決了!!!

有何收穫

  1. 我明確了實現算法和界面分離還要在學哪些知識點(雖然我還作不到把她們分離)
  2. js學的不過關 對象數組都用不清楚 強化了一些js對象數組的使用方法(我以爲有點(te bie)難用 若是有人知道咋用 請指出)
  3. 原本對Token徹底沒概念 如今知道了token是一種身份的驗證,在大多數網站中,登陸的時候都會攜帶token,去訪問其餘頁面,token就想當於一種令牌。能夠判斷用戶是否登陸狀態。
  4. 原本不太熟悉的,此次就加深理解了。包括對localStorage的理解都有了瞭解(果真實踐出真知哈哈)
  5. 我覺得前端很簡單的,此次知道了前端我還要接着學不少,太多不足了
  6. 對單元測試和vue都有了新的瞭解

評價隊友

值得學習的地方

高星身爲一個前端兼職美工,眼光仍是很好的

菜雞互啄衝壓!!!

不足的地方

不足的地方固然是沒有!! (。・∀・)ノ

學習進度

週數 新增代碼(行) 累計代碼(行) 本週學習耗時(小時) 累計學習耗時(小時) 重要成長
1 200+ 200+ 20 20 學了Axure,以及原型設計,學了一些js(團隊做業須要全部去學習了)
2 2000++ 2000+ 50 50 對js以及vue有了進一步瞭解
3 800+ 3000+ 20 20 瞭解了axios以及localStorage
4 500+ 3500+ 4 4 服務器部署

學習新知識的資料

資料地址 說明
vue的Token認證 Token認證的代碼實例,邊看代碼邊學Token
vue的axios使用 vue的axios使用詳細代碼,配合官網使用
vue單元測試 vue的單元測試瞭解
vue如何單元測試 講解了一些vue如何單元測試
vue單元測試 vue的官網單元測試說明
前端性能 瞭解前端性能相關
前端性能優化 瞭解前端性能如何優化

(還有一些七零八碎的就沒有列入了)

界面

寫好的程序掛載服務器上啦,能夠瞅瞅(帳號密碼hello,也能夠本身註冊)、

自適應沒寫好,建議全屏,若是全屏界面仍是很奇怪,(dbq我太菜了,咱們兩的遊戲本上看正常的,若是是在什麼超大的屏幕dbq)

加載會有些慢請耐心等待(資源加載太多了)

歡迎光臨慧珺和高星的13水

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