第二次结对编程作业

徘徊边缘 提交于 2019-12-02 23:50:38

第二次结对编程作业

一、结对博客信息:

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 StartAGame()
    {
        UnityWebRequest webRequest = new UnityWebRequest(NetMgr.GetUrl("StartGame"), "POST");
        webRequest.SetRequestHeader("X-Auth-Token", NetMgr.TokenDate);
        webRequest.downloadHandler = new DownloadHandlerBuffer();
        yield return webRequest.SendWebRequest();
        if (webRequest.isDone)
        {
            string result = webRequest.downloadHandler.text;
            // Debug.Log(result);
            if (result == "")
            {
                ShowMes("网络连接失败");
            }
            else
            {
                JsonData results = JsonMapper.ToObject(result);
                string state = "";
                try
                {
                    state = results["status"].ToJson();
                }
                catch
                {
                    ShowMes("连接失败");

                }
                if (state == "0")
                {
                    Debug.Log("成功获取牌");
                    NetMgr.GameID = (int)results["data"]["id"];
                    JsonData list = results["data"]["card"];
                    NetMgr.CardList = list.ToString();
                    Debug.Log(NetMgr.GameID + "牌:" + NetMgr.CardList);
                    CardIsDone();
                }
                else
                {
                    ShowMes(NetMgr.GetState(state));
                }
            }
        }
        else
        {
            if (Application.internetReachability == NetworkReachability.NotReachable)
            {
                ShowMes("网络连接失败");
            }
        }
    }


    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("网络连接失败");
            }
        }
    }

七、单元测试

先进行本地测试

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!