繁体   English   中英

从 Random.Range 中排除值

[英]Exclude value from Random.Range

我正在尝试制作纸牌游戏。 在这个游戏中,每张牌只有两张。 所以目标是每当某张牌被抽了两次,那张牌就不能再抽了。 目前,有3种不同的卡。 我在 0 和 3 之间做了一个随机范围。所以我试图实现的是,如果让我们说数字 1 被选中 2 次,那么如果它再次选择 1,它会跳过该轮并选择另一个数字,直到该数字不存在被选中 2 次的号码。

public GameObject[] cards;

public Transform spawnPos;

Vector3 tempPos;

int randomNum;

int C2i = 2;
int C3i = 2;
int C4i = 2;

bool C2 = true;
bool C3 = true;
bool C4 = true;

void Update()
{
    if(Input.GetMouseButtonDown(0))
    {
        SpawnCard();
    }

    if (C2i <= 0)
    {
        C2 = false;
    }

    if (C3i <= 0)
    {
        C3 = false;
    }

    if (C4i <= 0)
    {
        C4 = false;
    }
}

void SpawnCard()
{
    randomNum = Random.Range(0, cards.Length);

    CheckCards();

    if (C2 == true)
    {
        Instantiate(cards[randomNum], spawnPos.position, spawnPos.rotation);
    }
    else
    {
        SpawnCard();
    }

    if (C3 == true)
    {
        Instantiate(cards[randomNum], spawnPos.position, spawnPos.rotation);
    }
    else
    {
        SpawnCard();
    }

    if (C4 == true)
    {
        Instantiate(cards[randomNum], spawnPos.position, spawnPos.rotation);
    }
    else
    {
        SpawnCard();
    }

    tempPos = spawnPos.position;

    tempPos.x += 1.5f;

    spawnPos.position = tempPos;
}

void CheckCards()
{
    if (randomNum == 0)
    {
        C2i -= 1;
    }

    if (randomNum == 1)
    {
        C3i -= 1;
    }

    if (randomNum == 2)
    {
        C4i -= 1;
    }
}

你宁愿生成你的套牌基本上它在现实生活中是如何工作的。 这样维护起来更好,也更容易理解。

  1. 将您的卡片组存储在单独的集合中,这样您就可以轻松地使用新的卡片组重新开始,而不会丢失原始设置。

  2. 只需将每张卡片预制件中的两个添加到牌组中,然后在抽牌时将其移除。

  3. 要么将整个牌组洗牌,这样您以后就可以简单地按顺序抽牌(例如,一次也可以多张),或者使用您抽出的每张牌的随机索引。

就像是

using System.Linq;

...

// 1. You leave this collection untouched
// You only use it to create your deck from these prefabs
public GameObject[] cards;
public Transform spawnPos;

// NOT NEEDED
//private Vector3 tempPos;
//int randomNum;
//int C2i = 2;
//int C3i = 2;
//int C4i = 2;
//bool C2 = true;
//bool C3 = true;
//bool C4 = true;

// 1. Store your runtime deck here
// This will be generated and used to draw cards later
private readonly List<GameObject> deck = new List<GameObject>();

private void Awake ()
{
    CreateNewDeck();
}

private void CreateNewDeck()
{
    // 1. Start with an empty deck
    deck.Clear();

    // 2. Add two of each card prefabs
    foreach(var card in cards)
    {
        deck.Add(card);
        deck.Add(card);
    }

    // 3. Either shuffle the deck
    // If you use this then later you don't need random indices
    // the deck itself already is random so you can just draw them one by one later
    deck = deck.OrderBy(c => Random.value).ToList();
}

void Update()
{
    if(Input.GetMouseButtonDown(0))
    {
        SpawnCard();
    }
}

private void SpawnCard()
{
    if(deck.Count == 0) 
    {
        Debug.LogError("Deck is empty!", this);
        return;
    }

    // 3. If you did shuffle you can simply use 0
    var index = 0;
    // If you did not shuffle in Awake then pick random index from deck
    //var index = Random.Range(0, deck.Count); 
    // Pick card by index
    var card = deck[index];
    // Remove from deck
    deck.RemoveAt(index);   
    // Spawn card
    Instantiate(card, spawnPos.position, spawnPos.rotation);

    spawnPos.position += Vector3.right * 1.5f;
}
List<(int Card, int NumRemaining)> availableCards = Enumerable.Range(0, cards.Length).Select(i => (i, 2)).ToList(); int PickCard() { if (availableCards.Count == 0) throw new Exception("No cards remaining"); var cardIndex = availableCards.Count == 1 ? 0 : Random.Range(0, availableCards.Count); var (card, numRemaining) = availableCards[cardIndex]; if (numRemaining > 1) { availableCards[cardIndex] = (card, numRemaining - 1); } else { availableCards.RemoveAt(cardIndex); } return card; }

暂无
暂无

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

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