简体   繁体   English

从 Random.Range 中排除值

[英]Exclude value from Random.Range

I am trying to make a card game.我正在尝试制作纸牌游戏。 In this game, there are only two of each card.在这个游戏中,每张牌只有两张。 So the goal is that whenever a certain card is drawn two times, that card cannot be drawn anymore.所以目标是每当某张牌被抽了两次,那张牌就不能再抽了。 Currently, there are 3 different cards.目前,有3种不同的卡。 I made a random range between 0 and 3. So what im trying to achieve is that if lets say the number 1 gets picked 2 times, then if it picks 1 again that it skips that round and picks another number until that number is not any number that is picked 2 times.我在 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;
    }
}

You could rather generate your deck once basically how it works in real life.你宁愿生成你的套牌基本上它在现实生活中是如何工作的。 This is way better to maintain and also easier to understand.这样维护起来更好,也更容易理解。

  1. Store your cards deck in a separate collection so you can easily restart with a new deck without loosing your original setup.将您的卡片组存储在单独的集合中,这样您就可以轻松地使用新的卡片组重新开始,而不会丢失原始设置。

  2. Simply add two of each card prefab to the deck and remove them whenever you draw a card.只需将每张卡片预制件中的两个添加到牌组中,然后在抽牌时将其移除。

  3. Either shuffle the entire deck so you can simply draw the cards in order later (eg also multiple at a time) or use a random index of each card you draw.要么将整个牌组洗牌,这样您以后就可以简单地按顺序抽牌(例如,一次也可以多张),或者使用您抽出的每张牌的随机索引。

Something like就像是

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