简体   繁体   English

检查列表中的下一个最高/最低值并选择该项目

[英]Check for next highest / lowest value in list and select that item

UPDATE: I should have been more clear. 更新:我应该更清楚。 I am attemtping to sort a list in ascending order, and then getting the first weapon that has a greater value than the currently select weapon. 我决定按升序对列表进行排序,然后获得第一个具有比当前选择武器更大价值的武器。

My NextWeapon() function doesn't do anything at this point (it was simply there to show things that I have tried), but in the past I was simply iterating to the next item in the list, however an item may not be there. 我的NextWeapon()函数此时没有做任何事情(它只是显示我尝试过的东西),但在过去我只是迭代到列表中的下一个项目,但是项目可能不在那里。

The enum F3DFXType are the weapons my character could possible pick up, but there is no sense in looping through those if they are not actually in the inventory. 枚举F3DFXType是我的角色可以拾取的武器,但是如果它们实际上不在库存中则没有意义。 Therefore, I tried creating a list of type int, and looping through that. 因此,我尝试创建一个int类型的列表,并循环使用它。 As the character picks up a new weapon, it would be added to the list as an int, and then when I switched to that int, I would check for that same int in the F3DFXType enum. 当角色拿起一个新武器时,它会作为一个int添加到列表中,然后当我切换到那个int时,我会在F3DFXType枚举中检查相同的int。

For example, in a pickup I would check for a collision event, then use: weaponList.Add(5); 例如,在拾取器中我会检查碰撞事件,然后使用:weaponList.Add(5); thinking it would add the integer 5 to my inventory. 认为它会将整数5添加到我的库存中。 The 5th item in the F3DFXType is "Seeker". F3DFXType中的第5项是“Seeker”。 When I tried to loop through my inventory, it wouldn't actually add the 5th F3DFXType, it would simply add the NEXT item in the F3DFXType. 当我试图遍历我的库存时,它实际上不会添加第五个F3DFXType,它只是在F3DFXType中添加NEXT项。 (Ex: I already have Vulcan, and this would simply add SoloGun, which is the 2nd item in the enum) (例如:我已经有了Vulcan,这只会添加SoloGun,这是枚举中的第二项)


I am trying to loop through items in a list. 我试图循环列表中的项目。

The issue I run into is that if Ito iterate to the next item in the list, that item may not actually be there. 我遇到的问题是,如果我迭代到列表中的下一个项目,那个项目可能实际上并不存在。 So how do I advance to the next item that DOES exist in the list? 那么我该如何前进到列表中存在的下一个项目?

I'm not necessarily looking for an answer using the code below, I just wanted to give some context, so that you could see my current approach. 我不一定要使用下面的代码来寻找答案,我只想提供一些背景信息,以便您可以看到我当前的方法。

// Possible weapon types
public enum F3DFXType
{
    Vulcan = 1,
    SoloGun,
    Sniper,
    ShotGun,
    Seeker,
    RailGun,
    PlasmaGun,
    PlasmaBeam,
    PlasmaBeamHeavy,
    LightningGun,
    FlameRed,
    LaserImpulse
}


 // List of weapons currently avaialable
public List<int> weaponList;
public int currentIndex = 1;


void NextWeapon()
    {
        // Keep within bounds of list
        if (currentIndex < weaponList.Count)
        {
            currentIndex++;

            // Check if a higher value exists
            var higherVal = weaponList.Any(item => item < currentIndex);

            // create a new list to store current weapons in inventory
            var newWeapList = new List<int>();
            foreach (var weap in weaponList)
            {
                newWeapList.Add(weap);
            }
            weaponList = newWeapList;

            // If a higher value exists....
            if (higherVal)
            {
                //  currentIndex = SOMEHIGHERVALUE
            }
        }        
    }



    void PrevWeapon()
    {
        if (currentIndex > 1)
        {
            currentIndex--;
        }
    }



  // Fire turret weapon
    public void Fire()
    {
        switch (currentIndex)
        {
            case 1:
                // Fire vulcan at specified rate until canceled
                timerID = F3DTime.time.AddTimer(0.05f, Vulcan);
                Vulcan();
                break;
            case 2:
                timerID = F3DTime.time.AddTimer(0.2f, SoloGun);
                SoloGun();
                break;
            case 3:
                timerID = F3DTime.time.AddTimer(0.3f, Sniper);
                Sniper();
                break;
            case 4:
                ShotGun();
                break;
            case 5:
                timerID = F3DTime.time.AddTimer(0.2f, Seeker);
                Seeker();
                break
           default:
                break;
        }
    }

If I'm understanding the question correctly, I think you could simply do this by sorting the list in ascending order, and then getting the first weapon that has a greater value than the currently select weapon. 如果我正确地理解了这个问题,我认为你可以通过按升序对列表进行排序,然后获得比当前选择的武器具有更大价值的第一个武器来做到这一点。

For example: 例如:

void Next()
{
    var nextWeapon = weaponList
        .OrderBy(w => w)                         // Sort the weapon list
        .FirstOrDefault(w => w > currentIndex);  // Get the next highest weapon

    // If nextWeapon is 0, there was no higher weapon found
    currentIndex = nextWeapon > 0 ? nextWeapon : currentIndex;
}

EDIT: 编辑:

You can also reverse this to get the previous weapon: 您也可以将其反转以获得以前的武器:

void PrevWeapon()
{
    if (currentIndex > 1)
    {
        var previousWeapon = weaponList
            .OrderByDescending(w => w)               // Sort the weapon list
            .FirstOrDefault(w => w < currentIndex);  // Get the next lowest weapon

        // If previousWeapon is 0, there is no next lowest weapon
        currentIndex = previousWeapon > 0 ? previousWeapon : currentIndex;
    }
}

I found a solution. 我找到了解决方案。 No idea why this took me so long to figure out. 不知道为什么这花了这么长时间才弄明白。 Anyway, I have it working now. 无论如何,我现在都在工作。

I start off with 2 guns in my inventory. 我从库存中开始使用2支枪。 I can only switch between those two for now. 我现在只能在这两者之间切换。 (Items 0 & 4 in my array). (我的数组中的项目0和4)。

When I collide with a pickup, I can add another item to this inventory (item 11 in the array). 当我与拾取器碰撞时,我可以向此库存添加另一个项目(阵列中的第11项)。

Now when I hit Previous or Advance, it knows to stay within the array's bounds, and if a higher weapon is not found, then default back to the one we are currently using. 现在,当我点击Previous或Advance时,它知道保持在数组的范围内,如果找不到更高的武器,则默认返回到我们当前使用的武器。

// Weapon types
public enum F3DFXType
{
    Vulcan          = 0,
    SoloGun         = 1,
    Sniper          = 2,
    ShotGun         = 3,
    Seeker          = 4,
    RailGun         = 5,
    PlasmaGun       = 6,
    PlasmaBeam      = 7,
    PlasmaBeamHeavy = 8,
    LightningGun    = 9,
    FlameRed        = 10,
    LaserImpulse    = 11,
    MAX_WEAPONS     = 12
}


    public bool[] aWeaponsHave = new bool[(int)F3DFXType.MAX_WEAPONS];
    int iWeaponsCurrent;


public Constructor() 
{

       .....
     // Start at first weapon (VULCAN)
        iWeaponsCurrent = 0;
        aWeaponsHave[0] = true;

        // DEBUG: Add weapon to inventory
        aWeaponsHave[1] = true;
         .....
}



 private void GoNextWeapon()
    {
        // If there isn't a higher value found, then default back to the original one
        var originalVal = iWeaponsCurrent;

        do
        {
            iWeaponsCurrent++;
            // Went to the end of array & didn't find a new weapon. Set it to the original one. 
            if (iWeaponsCurrent == 12)
            {
                iWeaponsCurrent = originalVal;
                return;
            }
        } while (aWeaponsHave[iWeaponsCurrent] == false);
    }


    void GoPrevWeapon()
{
    do
    {
        iWeaponsCurrent--;

        // Prevent from spilling over
        if (iWeaponsCurrent < 0)
        {
            // Went to end of array. Set weapon to lowest value and get out of here
            iWeaponsCurrent = 0;
            return;
        }
    } while (!aWeaponsHave[iWeaponsCurrent]);
}



// Fire turret weapon
    public void Fire()
    {
        switch (iWeaponsCurrent)
        {
            //case F3DFXType.Vulcan:
            case 0:
                // Fire vulcan at specified rate until canceled
                timerID = F3DTime.time.AddTimer(0.05f, Vulcan);
                // Invoke manually before the timer ticked to avoid initial delay
                Vulcan();
                break;

            //case F3DFXType.SoloGun:
            case 1:
                timerID = F3DTime.time.AddTimer(0.2f, SoloGun);
                Debug.Log("Solo");
                SoloGun();
                break;

            //case F3DFXType.Sniper:
            case 2:
                timerID = F3DTime.time.AddTimer(0.3f, Sniper);
                Debug.Log("Sniper");
                Sniper();
                break;

            //case F3DFXType.ShotGun:
            case 3:
                timerID = F3DTime.time.AddTimer(0.3f, ShotGun);
                ShotGun();
                break;

            //case F3DFXType.Seeker:
            case 4:
                timerID = F3DTime.time.AddTimer(0.2f, Seeker);
                Seeker();
                break;

            //case F3DFXType.RailGun:
            case 5:
                timerID = F3DTime.time.AddTimer(0.2f, RailGun);
                Debug.Log("railgun");
                RailGun();
                break;
            //case F3DFXType.PlasmaGun:
            case 6:
                timerID = F3DTime.time.AddTimer(0.2f, PlasmaGun);
                PlasmaGun();
                break;

            //case F3DFXType.PlasmaBeam:
            case 7:
                // Beams has no timer requirement
                PlasmaBeam();
                break;

            //case F3DFXType.PlasmaBeamHeavy:
            case 8:
                // Beams has no timer requirement
                PlasmaBeamHeavy();
                break;

            //case F3DFXType.LightningGun:
            case 9:
                // Beams has no timer requirement
                LightningGun();
                break;

            //case F3DFXType.FlameRed:
            case 10:
                // Flames has no timer requirement
                FlameRed();
                break;

            //case F3DFXType.LaserImpulse:
            case 11:
                timerID = F3DTime.time.AddTimer(0.15f, LaserImpulse);
                LaserImpulse();
                break;
            default:
                break;
        }
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM