• 第二次结对编程作业


    第二次结对编程作业

    一、结对博客信息:

    031702513卢欢

    031702545汪佳祥

    Github项目地址(前端与AI)

    二、具体分工

    前端:卢欢,设计与实现十三水界面和交互,实现网络api调用

    后端:汪佳祥,负责出牌AI算法设计与实现

    三,PSP表格

    过程 预估耗时(分钟) 实际耗时(分钟)
    计划 30 30
    估计任务时间 30 30
    开发 600 800
    需求分析 (包括学习新技术) 60 60
    生成设计文档 30 30
    设计复审 15 15
    代码规范 (为目前的开发制定合适的规范) 15 30
    具体设计 30 15
    具体编码 455 655
    代码复审 15 15
    测试(自我测试,修改代码,提交修改) 30 30
    报告 40 45
    测试报告 15 15
    计算工作量 10 15
    事后总结, 并提出过程改进计划 15 15
    合计 670 875

    四、解题思路描述与设计实现说明

    1.网络接口的使用

    其实各个接口使用都是差不多的

    贴出登录和开始游戏的C#代码

    //开始一局游戏
    UnityWebRequest webRequest = new UnityWebRequest(NetMgr.GetUrl("StartGame"), "POST");
            webRequest.SetRequestHeader("X-Auth-Token", NetMgr.TokenDate);
            webRequest.downloadHandler = new DownloadHandlerBuffer();
            yield return webRequest.SendWebRequest();
    
    //登录游戏
            JsonData data = new JsonData
            {
                ["username"] = username,
                ["password"] = password
            };
            string js1 = data.ToJson();
            byte[] postBytes = Encoding.UTF8.GetBytes(js1);
    
            UnityWebRequest webRequest = new UnityWebRequest(NetMgr.GetUrl("Rigister"), "POST")
            {
                uploadHandler = new UploadHandlerRaw(postBytes)
            };
           // UnityWebRequest.useHttpContinue = false;
            webRequest.SetRequestHeader("Content-Type", "application/json;charset=utf-8");
            webRequest.downloadHandler = new DownloadHandlerBuffer();
            yield return webRequest.SendWebRequest();
    


    五、关键代码解释

    重要的/有价值的代码片段
    AI出牌函数:

    public static List<TypeCard> GetMaxCardType(List<int> cardList)
            {
                List<TypeCard> typeCardList = new List<TypeCard>();
    
                //从大到小排序
                SortCard(cardList);
    
                //复制一份从小到大的牌
                List<int> cardList2 = cardList.GetRange(0, cardList.Count);
                SortCardMinToMax(cardList2);
    
                List<int> FourNum = cardList.GroupBy(p => p % 100).Where(p => p.Count() >= 4).Select(p => p.Key).ToList();
                List<int> ThreeNum = cardList.GroupBy(p => p % 100).Where(p => p.Count() >= 3).Select(p => p.Key).ToList();
                List<int> TwoNum = cardList.GroupBy(p => p % 100).Where(p => p.Count() >= 2).Select(p => p.Key).ToList();
                #region 同花顺
                foreach (var item in cardList2)
                {
                    //同花顺最小是从10开始
                    if (item % 100 >= 11)
                        break;
    
                    List<int> tempList = new List<int>();
                    tempList.Add(item);
    
                    foreach (var item2 in cardList2)
                    {
                        if (item2 - 1 == tempList.Last())
                            tempList.Add(item2);
    
                        if (tempList.Count >= 5)
                        {
                            TypeCard typeCard = new TypeCard() { cardList = tempList, cardType = DeckTypeEnum.TongHuaShun };
                            typeCardList.Add(typeCard);
                            break;
                        }
                    }
                }
                #endregion
    
                #region 炸弹
                foreach (var FourItem in FourNum)
                {
                    List<int> tempList = new List<int>();
                    foreach (var item in cardList)
                    {
                        if (item % 100 == FourItem)
                            tempList.Add(item);
    
                        if (tempList.Count >= 4)
                        {
                            TypeCard typeCard = new TypeCard() { cardList = tempList, cardType = DeckTypeEnum.Bomb };
                            typeCardList.Add(typeCard);
                            break;
                        }
                    }
    
                }
                #endregion
    
                #region 葫芦
                foreach (var ThreeItem in ThreeNum)
                {
                    List<int> tempList = new List<int>();
                    foreach (var item in cardList)
                    {
                        if (item % 100 == ThreeItem)
                            tempList.Add(item);
    
                        if (tempList.Count >= 3)
                        {
                            //找两对
                            foreach (var TwoItem in TwoNum)
                            {
                                if (ThreeItem != TwoItem)
                                {
                                    foreach (var AllItem in cardList)
                                    {
                                        if (AllItem % 100 != ThreeItem && AllItem % 100 == TwoItem)
                                            tempList.Add(AllItem);
    
                                        if (tempList.Count >= 5)
                                        {
                                            TypeCard typeCard = new TypeCard() { cardList = tempList, cardType = DeckTypeEnum.Gourd };
                                            typeCardList.Add(typeCard);
                                            tempList = typeCard.cardList.GetRange(0, 3);
                                            break;
                                        }
                                    }
                                }
                            }
                            break;
                        }
                    }
                }
                #endregion
    
                #region 同花
                List<int> FiveColor = cardList.GroupBy(p => p / 100).Where(p => p.Count() >= 5).Select(p => p.Key).ToList();
                List<int> FourColor = cardList.GroupBy(p => p / 100).Where(p => p.Count() >= 4).Select(p => p.Key).ToList();
                List<int> ThreeColor = cardList.GroupBy(p => p / 100).Where(p => p.Count() >= 3).Select(p => p.Key).ToList();
    
                List<TypeCard> typeCards = new List<TypeCard>();
    
                foreach (var Fiveitem in FiveColor)
                {
                    List<int> tempList = new List<int>();
                    foreach (var item in cardList)
                    {
                        if (item / 100 == Fiveitem)
                        {
                            tempList.Add(item);
                        }
                    }
                   
                    while (true)
                    {
                        if (tempList.Count >= 5)
                        {
                            TypeCard typeCard = new TypeCard() { cardList = tempList.GetRange(0, 5), cardType = DeckTypeEnum.TongHua };
                            typeCards.Add(typeCard);
                            //typeCardList.Add(typeCard);
                            tempList.RemoveAt(0);
                        }
                        else
                        {
                            break;
                        }
                    }
                }
                //收集同花集合后
                //对同花进行排序
                //
                if (typeCards.Count > 1)
                {
                    
                    //排序的优先级从高到低
                    typeCards.Sort((x, y) => -((x.cardList[0] % 100).CompareTo(y.cardList[0] % 100) * (1 << 4)
                    + (x.cardList[1] % 100).CompareTo(y.cardList[1] % 100) * (1 << 3)
                     + (x.cardList[2] % 100).CompareTo(y.cardList[2] % 100) * (1 << 2)
                      + (x.cardList[3] % 100).CompareTo(y.cardList[3] % 100) * (1 << 1)
                      + (x.cardList[4] % 100).CompareTo(y.cardList[4] % 100)
                    ));
                    //typeCards.Sort((x, y) => -((x.cardList[1]%100).CompareTo(y.cardList[1]%100)));
                }
                foreach (var typeCard in typeCards)
                {
                    typeCardList.Add(typeCard);
                }
    
                #endregion
    
                #region 顺子
    
                foreach (var MaxItem in cardList)
                {
    
                    if (MaxItem % 100 <= 5)
                    {
                        break;//从大到小,后面的也不需要循环了
                    }
    
                    List<int> tempList = new List<int>();
                    tempList.Add(MaxItem);
    
                    while (tempList.Count < 5)
                    {
                        bool flag = false;
                        foreach (var item in cardList)
                        {
                            if (item % 100 + 1 == tempList.Last() % 100)
                            {
                                tempList.Add(item);
                                flag = true;
                                break;
                            }
                        }
                        if (!flag)
                        {
                            break;
                        }
                    }
    
                    if (tempList.Count >= 5)
                    {
                        TypeCard typeCard = new TypeCard() { cardList = tempList, cardType = DeckTypeEnum.ShunZi };
                        typeCardList.Add(typeCard);
                    }
                }
    
                #endregion
    
                #region 三张
                foreach (var Threeitem in ThreeNum)
                {
                    List<int> tempList = new List<int>();
                    foreach (var item in cardList)
                    {
                        if (item % 100 == Threeitem)
                            tempList.Add(item);
    
                        if (tempList.Count >= 3)
                        {
                            TypeCard typeCard = new TypeCard() { cardList = tempList, cardType = DeckTypeEnum.Three };
                            typeCardList.Add(typeCard);
                            break;
                        }
                    }
                }
    
                #endregion
    
                #region 两对
    
                for (int i = 0; i < TwoNum.Count; i++)
                {
                    List<int> tempList = new List<int>();
    
                    foreach (var item in cardList)
                    {
                        if (item % 100 == TwoNum[i])
                        {
                            tempList.Add(item);
                        }
                    }
    
                    while (tempList.Count >= 2)
                    {
    
                        for (int j = i + 1; j < TwoNum.Count; j++)
                        {
                            List<int> tempList2 = new List<int>();
                            foreach (var item in cardList)
                            {
                                if (item % 100 == TwoNum[j])
                                {
                                    tempList2.Add(item);
                                }
                            }
    
                            while ((tempList2.Count >= 2))
                            {
                                TypeCard typeCard = new TypeCard() { cardList = tempList.GetRange(0, 2), cardType = DeckTypeEnum.TwoDouble };
    
                                //直接加入连对的判断
                                if (tempList[0] % 100 - 1 == tempList2[0] % 100)
                                {
                                    //连对
                                    typeCard.cardType = DeckTypeEnum.ContinuousTwoDouble;
                                }
                                typeCard.cardList.AddRange(tempList2.GetRange(0, 2));
                                typeCardList.Add(typeCard);
                                tempList2.RemoveAt(0);
                            }
    
                        }
                        tempList.RemoveAt(0);
                    }
    
                }
    

    六、性能分析与改进

    1.改进的思路
    消耗最大的函数是网络请求和AI,我们重点关注AI的改进。
    算法开始的时连对没考虑到,后面就加了这种情况
    然后对于一些特殊情况,可以先提前判断,可以减少消耗。
    2.展示性能分析图和程序中消耗最大的函数

    
        IEnumerator PostResult(string jsondata)
        {
    
            byte[] postBytes = Encoding.UTF8.GetBytes(jsondata);
    
            UnityWebRequest webRequest = new UnityWebRequest(NetMgr.GetUrl("submit"), "POST")
            {
                uploadHandler = new UploadHandlerRaw(postBytes)
            };
            webRequest.SetRequestHeader("X-Auth-Token", NetMgr.TokenDate);
            webRequest.SetRequestHeader("Content-Type", "application/json;charset=utf-8");
            webRequest.downloadHandler = new DownloadHandlerBuffer();
            yield return webRequest.SendWebRequest();
            if (webRequest.isDone)
            {
                string result = webRequest.downloadHandler.text;
                if (result == "")
                {
                    ShowMes("网络连接失败");
                }
                else
                {
                    JsonData results = JsonMapper.ToObject(result);
                    string state = "";
                    try
                    {
                        state = results["status"].ToJson();
                    }
                    catch
                    {
                        ShowMes("连接失败");
    
                    }
                    if (state == "0")
                    {
                        Pokemgr.Instance.Clean();
                        ExitButton.onClick.Invoke();
                        BackButton.onClick.Invoke();
    
                        if (AIScore)
                        {
                            StartButton.onClick.Invoke();
                        }
                        else
                        {
                            ShowMes("出牌成功");
                        }
                    }
                    else
                    {
                        ShowMes(NetMgr.GetState(state));
                    }
                }
            }
            else
            {
                if (Application.internetReachability == NetworkReachability.NotReachable)
                {
                    ShowMes("网络连接失败");
                }
            }
        }
    

    七、单元测试

    通过服务器获取牌堆,AI出牌后自动提交,同时留下记录
    如果服务器返回错误,则说明我们测试失败

    八、Github的代码签入记录

    九、遇到的代码模块异常或结对困难及解决方法

    汪佳祥(后端)

    1.

    遇到的问题:一开始AI出牌算法毫无思绪,后来。欢哥要求我使用C#写出算法,我被赶鸭子上架

    做过哪些尝试:到微信小程序玩了几十把罗松渐渐熟悉起来

    是否解决:是

    收获:一天速成C#简单语法,第二天开始写算法,也遇到许多bug,例如中墩比尾墩来得大(都是我的锅),都被欢哥逐一解决(再次抱紧欢哥大腿)。这些问题在我欢哥面前简直都不是个事

    卢欢(前端)

    1.

    问题描述:界面的设计没什么特别难的问题,主要是我自己写了很多界面动画,有时没有想要的效果

    做过哪些尝试:一直在改,强迫症犯了,就一直想做得好看,虽然现在做的也挺丑。。。

    是否解决:是

    有何收获:提高审美

    2.

    问题描述:网络接口

    做过哪些尝试:开始没用过,找个例子就理解了

    是否解决:成功解决

    有何收获:再次理解了网络异步通信,网络请求的代码写在协程里

    十、评价你的队友

    汪佳祥

    • 值得学习的地方
      • 评价队友:通过本次的软工实践,我紧抱欢哥大腿,感觉到了我的队友十分强悍,他设计的这个前端界面让我让我感觉我的后端算法有点配不上他,他也给我提供了许多的帮助,我还需要继续向他学习
    • 需要改进的地方
      • 应该尽可能地不要通宵,少熬夜。

    卢欢

    • 值得学习的地方
      • 祥哥真是个大忙人,不过敲起代码来效率飞快,总的来说碰的壁比较少吧,因此我们这个项目花的时间不是很多就写完成了
    • 需要改进的地方
      • AI能够更强大就好了

    十一、学习进度条

    • 后端(汪佳祥)
    第N周 新增代码(行) 累计代码(行) 本周学习耗时(小时) 累计学习耗时(小时) 重要成长
    1 0 0 10 10 上手墨刀,了解原型设计的过程
    2 600 600 15 25 写算法
    3 200 800 10 35 学习网络接口的使用
    • 前端(卢欢)
    第N周 新增代码(行) 累计代码(行) 本周学习耗时(小时) 累计学习耗时(小时) 重要成长
    1 0 0 8 8 上手墨刀,了解原型设计
    2 0 0 20 28 学会设计界面
    3 1170 1170 22 50 学会接口的使用
  • 相关阅读:
    SAP training scope SAP从入门到精通课程体系
    萨提亚·纳德拉
    说说为什么不再写博客了
    课上用过的Linux命令
    中国商用密码生产企业和商用密码产品及标准
    在Python中运行gmssl
    基于CMPP协议集成短信测试桩全流程实践分享 做梦的人
    mysqlslap: Error when connecting to server: 1064 Reach limit of connections 做梦的人
    大数据清洗表中没有找到对应表 做梦的人
    自动生成镜像,在上传到仓库 做梦的人
  • 原文地址:https://www.cnblogs.com/wjx-1999/p/11768047.html
Copyright © 2020-2023  润新知