unity 实现太空狼人杀排序逻辑

这边按要求需要实现一个排序的算法:
玩家自身站在中间,
如果自己是平民,则以自身为中心,先排右边一个再排左边一个依次直到排完。
如果自己是狼人,则以自身为中心,右边排一个狼人,然后再按照先排右边一个再排左边一个依次直到排完。

因为这里最多只有两狼,所以没有做专门的数组进行存储。

首先将数据按照编号从小到大排序,然后对排序号的数据进行遍历,将需要排在左侧的数据存入栈中,将需要排在右侧的数据存入队列中,如果玩家自身是狼人,则将另一狼人数据单独存储。最后输出成排序好的列表,先出栈,然后存入玩家自身,如果狼人有数据则再存入狼人数据,最后出队列。得到的列表就是已经按照要求所实现的站位列表。

using net;
using System.Collections.Generic;

namespace SocialApp
{
    
    
    /// <summary>
    /// 狼人游戏辅助类
    /// </summary>
    class WolfGame_Common
    {
    
    
        /// <summary>
        /// 根据玩家编号排列角色分配界面
        /// 编号从小到大排序
        /// 以自身为中心(如果自身是狼人,将狼人玩家优先排在自身右边),先右后左依次排序
        /// </summary>
        /// <param name="infos"></param>
        /// <param name="side"></param>
        public static void SortPlayerIndex(ref List<WolfGamePlayerInfo> infos, CSPlayerSide side = CSPlayerSide.CS_PLAYER_SIDE_CIVILIAN)
        {
    
    
            Queue<WolfGamePlayerInfo> m_rightQue = new Queue<WolfGamePlayerInfo>();  //右侧队列
            Stack<WolfGamePlayerInfo> m_leftSta = new Stack<WolfGamePlayerInfo>();  //左侧栈
            WolfGamePlayerInfo m_curInfo = new WolfGamePlayerInfo();  //玩家自身数据
            WolfGamePlayerInfo m_wolfInfo = new WolfGamePlayerInfo();  //其他狼人数据
            int m_index = 0;
            int m_stackCount = 0;
            int m_queueCount = 0;

            //初始列表升序排序
            SortListUp(ref infos);

            #region 数据排序初始化

            for (int i = 0; i < infos.Count; i++)
            {
    
    
                //如果是玩家自身,单独取值
                if (infos[i].m_uin == BattleContext.CtrlUin)
                {
    
    
                    m_curInfo = infos[i];
                    continue;
                }
                else//其他玩家区分狼人和平民
                {
    
    
                    if (infos[i].m_side == CSPlayerSide.CS_PLAYER_SIDE_WOLF)
                    {
    
    
                        m_wolfInfo = infos[i];

                        if (side == CSPlayerSide.CS_PLAYER_SIDE_WOLF)  //如果玩家自身是狼,则需要将其他狼人剔除。否则不需要
                        {
    
    
                            continue;
                        }
                    }
                }

                //分配玩家数据到栈和队列
                //从右往左排
                //先进队列后进栈  依次
                if (m_index % 2 == 0)  //右侧  进队列
                {
    
    
                    m_rightQue.Enqueue(infos[i]);
                }
                else  //左侧  进栈
                {
    
    
                    m_leftSta.Push(infos[i]);
                }
                m_index++;
            }

            #endregion

            #region 数据写入列表

            //先出栈再写入玩家自身数据(狼人再写入狼人玩家)最后出队列
            infos.Clear();

            //出栈
            m_stackCount = m_leftSta.Count;
            for (int i = 0; i < m_stackCount; i++)
            {
    
    
                infos.Add(m_leftSta.Pop());
            }
            m_leftSta.Clear();

            //写入玩家自身数据(狼人再写入狼人玩家)
            infos.Add(m_curInfo);
            if (side == CSPlayerSide.CS_PLAYER_SIDE_WOLF)
            {
    
    
                //排除只有自己一狼的情况下,出现空数据
                if(m_wolfInfo.m_uin != 0)
                {
    
    
                    infos.Add(m_wolfInfo);
                }
            }

            //出队列
            m_queueCount = m_rightQue.Count;
            for (int i = 0; i < m_queueCount; i++)
            {
    
    
                infos.Add(m_rightQue.Dequeue());
            }
            m_rightQue.Clear();

            #endregion
        }

        /// <summary>
        /// 对玩家编号进行升序排序
        /// </summary>
        /// <param name="infos"></param>
        private static void SortListUp(ref List<WolfGamePlayerInfo> infos)
        {
    
    
            List<WolfGamePlayerInfo> tmpInfos = new List<WolfGamePlayerInfo>();  //排序后列表
            int m_count = infos.Count;  //传入列表的长度
            int m_minIndex;  //最小的索引值
            int m_minValue;  //最小的编号

            //数据排序
            for (int i = 0; i < m_count; i++)  //排序循环次数
            {
    
    
                m_minIndex = 0;    //当前最小的索引值
                m_minValue = (int)infos[0].m_roleNo;  //当前最小的编号
                for (int j = 0; j < infos.Count; j++)  //查找当前列表中的最小值对应的索引值
                {
    
    
                    if ((int)infos[j].m_roleNo < m_minValue)
                    {
    
    
                        m_minIndex = j;
                        m_minValue = (int)infos[j].m_roleNo;
                    }
                }

                //将当前最小索引值传入列表
                tmpInfos.Add(infos[m_minIndex]);
                infos.RemoveAt(m_minIndex);
            }

            //数据写入
            infos.Clear();
            infos.AddRange(tmpInfos);

            //清空数据
            tmpInfos.Clear();
        }
    }
}

猜你喜欢

转载自blog.csdn.net/weixin_47819574/article/details/131287233