Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 12 Next capture
2021 2022 2023
2 captures
12 Jun 22 - 14 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
This question was closed Apr 26, 2019 at 11:31 AM by ravenkane for the following reason:

The question is answered, right answer was accepted

avatar image
0
Question by ravenkane · Apr 25, 2019 at 04:08 PM · c#switchrandomization

7-Bag Randomiser

TL;DR: I've created a randomiser for tetrominos with a switch statement that marks pieces chosen as "picked", so that the switch statement can ignore it. However, the switch statement can still pick that case and results in returning the default Tetromino.


So, I'm working on a fan made Tetris game and I wanted to implement the 7 bag randomiser. (see this article for information)

So in order to generate a new Tetromino, I created a generate tetromino method which contains a switch statement that randomly picks out of 7 cases which Tetromino will be next.

 string GetRandomTetromino ()
     {
 
         if (IUsed == true && LUsed == true && JUsed == true && OUsed == true && SUsed == true && ZUsed == true && TUsed == true) {
 
             IUsed = false;
             LUsed = false;
             JUsed = false;
             OUsed = false;
             SUsed = false;
             ZUsed = false;
             TUsed = false;
 
         }
 
         int randomTetromino = Random.Range(1, 8);
 
         // This string is used to define the location of the next Tetromino.
         string randomTetrominoName = "Prefabs/Tetromino_J";
 
 
 
         // This switch is used to get a random Tetromino out of 7.
         // NOTE: This needs to be modified to have a 7-bag randomiser later.
         switch (randomTetromino)
         {
 
             case 1:
                 if (TUsed == false) {
                     randomTetrominoName = "Prefabs/Tetromino_T";
                     TUsed = true;
                     
                 }
 
                 break;
 
             case 2:
                 if (SUsed == false) {
                     randomTetrominoName = "Prefabs/Tetromino_S";
                     SUsed = true;
                     
                 }
 
                 break;
 
             case 3:
                 if (LUsed == false) {
                     randomTetrominoName = "Prefabs/Tetromino_L";
                     LUsed = true;
                     
                 }
 
                 break;
 
             case 4:
                 if (JUsed == false) {
                     randomTetrominoName = "Prefabs/Tetromino_J";
                     JUsed = true;
                     
                 }
 
                 break;
 
             case 5:
                 if (IUsed == false) {
                     randomTetrominoName = "Prefabs/Tetromino_I";
                     IUsed = true;
                     
                 }
 
                 break;
 
             case 6:
                 if (ZUsed == false) {
                     randomTetrominoName = "Prefabs/Tetromino_Z";
                     ZUsed = true;
                     
                 }
 
                 break;
 
             case 7:
                 if (OUsed == false) {
                     randomTetrominoName = "Prefabs/Tetromino_O";
                     OUsed = true;
                     
                 }
 
                 break;
             
 
         }
 
         // Return the location of the next Tetromino specified by the switch.
         return randomTetrominoName;
 
     }


Basically, I have 7 booleans called IUsed, LUsed, JUsed, etc. and they're enabled if the randomiser picks a certain piece, signalling "Hey, this piece shouldn't be called anymore". If all of these booleans are enabled, the if statement at the start makes them all false so that the randomiser has options again.

There's a problem though.

After 6 or so pieces pass by, a ton of J Pieces start appearing before the final piece comes along. I found out that this is because the switch statement is ignoring pieces that have already been picked and the final piece only comes when it's case is executed.

As a result, if the switch statement picks a case for a Tetromino already picked, it returns the default Tetromino: J.

Right here:

 string randomTetrominoName = "Prefabs/Tetromino_J";

I'm struggling to find alternatives to or an exact way to re-execute/ing the switch statement so that it only returns once it gets a piece not already picked.

If anyone finds an alternative that's better or a way to fix the issue with the current solution, all help would be appreciated.

Comment
Add comment
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

2 Replies

  • Sort: 
avatar image
1
Best Answer

Answer by Bunny83 · Apr 26, 2019 at 01:59 AM

Why do you work with strings here? Shouldn't you have a list of gameobject references to those prefabs in order to instantiate them? To create a random bag drawing all you have to do is use a List. When you draw an element from that List, just remove that element from the list until the list is empty. If the list is empty just add all 7 elements again.

 // assigned in the inspector or initialized inside Awake
 public GameObject[] pieces;
 
 private List<GameObject> bag = new List<GameObject>();
 
 public GameObject DrawPiece()
 {
     if (bag.Count == 0)
     {
         bag.AddRange(pieces);
     }
     int index = Random.Range(0, bag.Count);
     GameObject p = bag[index];
     bag.RemoveAt(index);
     return p;
 }

That's all you need. This is a self refilling bag of pieces. So if your pieces array contains 7 elements the "DrawPiece()" method will randomly draw one of those 7 pieces until the bag is empty. Then it automatically refills the bag.


Note instead of RemoveAt, one could actually use a slightly better approach since the order inside the bag doesn't matter. You could move the last element to the removed index position and always remove the last element. This avoids the required element-down-shift operation that is required when removing an element in between. However since we only have 7 elements max in the bag it's not really worth doing that. Such techniques are more important for larger lists (like 100+ elements). With 7 elements the average elements that need to be moved is lower than half the element count.

Comment
Add comment · Show 2 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image ravenkane · Apr 26, 2019 at 11:02 AM 0
Share

I work with strings because when I instantiate the Tetro$$anonymous$$oes, I do so by using Resources.Load. The returned string always has Prefab/ in front because it looks for that folder in the Resources folder. The generator specifies a Tetro$$anonymous$$o and instantiates it as a GameObject.

 nextTetro$$anonymous$$o = (GameObject)Instantiate(Resources.Load(GetRandomTetro$$anonymous$$o(), typeof(GameObject)), new Vector2(5.0f, 20.0f), Quaternion.identity);

But I'm about to try out this method so if it works, then thanks a ton.

avatar image ravenkane · Apr 26, 2019 at 11:30 AM 0
Share

This works absolutely beautiful. All pieces are randomised, the prefabs no longer have to be in a Resources folder, and the code is a lot easier to read. Cheers mate.

avatar image
0

Answer by surfuay · Apr 25, 2019 at 04:56 PM

I like what you did there, I would use an array in conjuction with the bools

so in script you have at the top I would make

   public gameObject[] tetrominos;

then in the editor i would declare thesize of it (8) in your case and put a prefab in each of those.

Now when I go back to my script to see if I can do anything I believe I would need 1 method (this will be a skeleton of it instead of a full thing, expand as you need).

  public void AvailableTetrominos()
  {
       //your local int variable for the random range
       
        if (TetrominosAll == true)
       {
               //when you're doing an int range you always have to go 1 higher than the number you want.  It does not include the final number as a possibility.  It only does that in a float
               int randomTet = random.Range(0, 9)
               random tet is selected
       }
       else if  and on and on.  
  }
Comment
Add comment · Show 1 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Bunny83 · Apr 26, 2019 at 02:08 AM 0
Share

Why would you use an array with 8 elements if you only have 7 pieces? Also why rolling a random number between 0-8 (9 different numbers) if you only have 8 or 7 elements ?


The whold boolean thing won't work. How do you actually exclude elements you have already picked? Using bools is just a mess here ;)

Follow this Question

Answers Answers and Comments

609 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Multiple Cars not working 1 Answer

Distribute terrain in zones 3 Answers

Is there a way to connect scripts in a way where they can be assembled like building blocks? 0 Answers

Play two Animations 1 Answer

Changing gravity direction... 5 Answers


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges