[Question]
  [
The game [shapez.io](https://shapez.io) has a huge variety of shapes you can produce, such as:
[![enter image description here](https://i.stack.imgur.com/GbCUE.png)](https://i.stack.imgur.com/GbCUE.png)
Each shape has a unique *short code*, for example the above is `CrWbScRu`.
This means, going clockwise from top right, red circle (`Cr`), blue wedge (`Wb`), cyan star (`Sc`), uncolored rectangle (`Ru`).
There are four different shapes:
* Rectangle - `R`
* Wedge - `W`
* Star - `S`
* Circle - `C`
And eight different colours:
* uncolored - `u`
* red - `r`
* green - `g`
* blue - `b`
* yellow - `y`
* purple - `p`
* cyan - `c`
* white - `w`
A quadrant is made out of one of each of these - (shape)(color). A quadrant can also be *empty* with `--`. This means there are 33 possible quadrants.
Four quadrants concatenated together make a *layer*, of which there are \$33^4 - 1 = 1185920\$ possibilities. You can't have an empty layer (`--------`). These layers can be stacked on top of one another by joining with `:` - the code `CyCyCyCy:SrSrSrSr` looks like:
[![enter image description here](https://i.stack.imgur.com/8bQB7.png)](https://i.stack.imgur.com/8bQB7.png)
Shapes can be stacked up to 4. This means there are \$\left(33^{4}-1\right)+\left(33^{4}-1\right)^{2}+\left(33^{4}-1\right)^{3}+\left(33^{4}-1\right)^{4} = \$ 1.97 septillion possible shapes total.
Your challenge is to randomly generate one of these.
Your generation does not have to be uniformly random, as long as every possible shape has a nonzero chance of being chosen.
## Specs
* Each *quadrant* is one of `SWCR` followed by one of `ugbrycpw`, or `--`.
* A *layer* is four *quadrants* concatenated together.
* A *shape* is 1-4 *layers* joined by `:`
* You should generate a not-necessarily-uniformly-random *shape*.
You can view shapes at <https://viewer.shapez.io/>.
# Scoring
This is [code-golf](/questions/tagged/code-golf "show questions tagged 'code-golf'"), shortest wins!
  
[Answer]
# [05AB1E](https://github.com/Adriandmen/05AB1E), ~~35~~ ~~40~~ ~~38~~ 36 bytes
+5 to prevent empty output which would've occured with probability \$33^{-16}\$  
-2 bytes thanks to Kevin Cruijssen!
Quite slow, generates \$33^4\$ possible layers 4 times and chooses a random one each time. Layers of all `-` are removed.
```
[₄ε‘¥„W‘’»Õpcw’â„--ª4ãΩJ}'-8×K':ýDĀ#
```
[Try it online!](https://tio.run/##yy9OTMpM/f8/@lFTy7mtjxpmHFr6qGFeOJDxqGHmod2HpxYklwNZhxcBRXV1D60yObz43EqvWnVdi8PTvdWtDu91OdKg/P//f13dvHzdnMSqSgA "05AB1E – Try It Online")
At the cost of two bytes this can actually run fast: [Try it online!](https://tio.run/##yy9OTMpM/f8/2tDM59zWRw0zDi191DAvHMh41DDz0O7DUwuSy4Gsw4uAorq6h1adW1lrcniLl7quxeHp3upWh/e6HGlQ/v8fAA "05AB1E – Try It Online")
Because every quadrant in each layer has a \$1\$ in \$33\$ chance of being empty the resulting shapes are quite noisy:
[![SpSgCgRy:CyRgRcSw:RrCuScRu:ScSyWuCp](https://i.stack.imgur.com/KqmFos.png)](https://i.stack.imgur.com/KqmFo.png)
---
```
[    ...    Dg#              # until the the output is not empty, do the following:
₄                            # push constant 1000
  ε                     }    # for each digit in this number:
   ‘¥„W‘                     #   dictionary compressed string "SRCW"
        ’»Õpcw’              #   dictionary compressed string "rugbypcw"
               â             #   cartesian product of the two strings
                „--ª         #   append "--" to this list
                    4ã       #   4th cartesian power, all 4-element combinations from the length-2 strings
                      Ω      #   choose a random one
                       J     #   join into a single string
'-8×                         # string of 8 -'s
    K                        # remove all occurences from the list
     ':ý                     # join the list by ":"
```
[Answer]
# [Jelly](https://github.com/DennisMitchell/jelly), ~~38~~ ~~35~~ 34 bytes
```
“SWCR”p“¬,ĖṆḷ⁸»Żṗ4XʋⱮ4ẸƇƊṆ¿o⁾--j”:
```
[Try it online!](https://tio.run/##y0rNyan8//9Rw5zgcOegRw1zC4DMQ2t0jkx7uLPt4Y7tjxp3HNp9dPfDndNNIk51P9q4zuThrh3H2o91AaUP7c9/1LhPVzcLqM3q/38A "Jelly – Try It Online")
This *just* about finishes on TIO most of the time (it has a \$1\$ in \$33^{16}\$ chance of taking longer), taking around 55 seconds. Full program, as we require Jelly's smash-printing to get the correct output
-4 bytes thanks to [Jonathan Allan](https://codegolf.stackexchange.com/users/53748/jonathan-allan)!
The first sample output I got was:
[![generated shape](https://i.stack.imgur.com/jk18Ls.png)](https://i.stack.imgur.com/jk18Ls.png)
[External link](https://viewer.shapez.io?SbSyRwWy.WwWgRyCg.RrScRuWc.WgCyRuCr)
# How it works
```
“SWCR”p“¬,ĖṆḷ⁸»Żṗ4XʋⱮ4ẸƇƊṆ¿o⁾--j”: - Main link. No arguments. Left argument = 0
                        Ɗ          - Group the previous 3 links into a monad f(_): (ignores the argument)
“SWCR”                             -   Set the return value to “SWCR”
                   ʋ               -   Group the previous 4 links into a dyad g(“SWCR”, i): (ignores i)
       “¬,ĖṆḷ⁸»                    -     Compressed string: “rugbypcw”
      p                            -     Cartesian product with “SWCR”
               Ż                   -     Prepend a zero (represents “--”)
                ṗ4                 -     4th Cartesian power
                  X                -     Choose a random list
                    Ɱ4             -   Yield [g(“SWCR”,1), g(“SWCR”,2), g(“SWCR”,3), g(“SWCR”,4)]
                      ẸƇ           -   Remove any that are just zeros
                          ¿        - While:
                         Ṇ         -   The left argument is falsey ([] or 0)
                        Ɗ          -   Set the left argument to f(_)
                           o⁾--    - Replace all zeros with “--”
                               j”: - Join by ”: and smash-print
```
[Answer]
# [Python 3](https://docs.python.org/3/), 129 bytes
```
from random import*
print(':'.join(''.join(sample(q,4))for q in[[i+j for i in'RWSC'for j in'urgbypcw']*4+['--']*3]*randint(1,4)))
```
[Try it online!](https://tio.run/##K6gsycjPM/7/P60oP1ehKDEvBUhl5hbkF5VocRUUZeaVaKhbqetl5WfmaahD6eLE3IKcVI1CHRNNzbT8IoVChcy86OhM7SwFEC8TyFMPCg92VgfxskC80qL0pMqC5HL1WC0T7Wh1XV0gwzhWC2QbyAJDkEGa//8DAA "Python 3 – Try It Online")
For each layer, 4 items are picked from a distribution containing 3 empty quadrants and the other shape-colour combinations 4 times.
[Answer]
# [Japt](https://github.com/ETHproductions/japt), ~~40~~ ~~39~~ 38 [bytes](https://en.wikipedia.org/wiki/ISO/IEC_8859-1)
This version has a *very* high probability of having all 4 layers, using a similar approach as [Level's Ruby solution](https://codegolf.stackexchange.com/a/233743/58974) of generating all 4 layers, removing the ones consisting entirely of empty quadrants and making a recursive call if there are none left.
```
4Æ"RWCS"ï`Õ½wbgp` p-² ö4 qÃfÈr-Ãq': ªß
```
[Test it](https://petershaggynoble.github.io/Japt-Interpreter/?v=1.4.6&code=NMYiUldDUyLvYNW9d2JncGAgcC2yIPY0IHHDZshyLcNxJzogqt8)
## Original, 39 bytes
```
Ò4ö)ÆÈr-}a@"RWCS"ï`Õ½wbgp` p-² ö4 q
q':
```
[Test it](https://petershaggynoble.github.io/Japt-Interpreter/?v=1.4.6&code=0jT2KcbIci19YUAiUldDUyLvYNW9d2JncGAgcC2yIPY0IHEKcSc6)
```
Ò4ö)ÆÈr-}a@"RWCS"ï`Õ½wbgp` p-² ö4 q\nq':
Ò                                            :Negate the bitwise not of (i.e., increment)
 4ö                                          :  Random int in the range [0,4)
   )                                         :End bitwise op
    Æ                                        :Map the range [0,Ò4ö)
     È                                       :  Left function taking a string as argument
      r-                                     :    Remove all "-"s
        }                                    :  End function
         a                                   :  Return the first result of the right function that returns truthy (non-empty string) when passed through the left
          @                                  :  Right function
           "RWCS"ï                           :    Cartesian product of "RWCS" and
                  `Õ½wbgp`                   :      Compressed string "ucrywbgp"
                           p                 :    Push
                            -²               :      "-" duplicated
                               ö4            :    Choose 4 random elements
                                  q          :    Join
                                     q':     :Join with ":"
```
[Answer]
# C#[9.0] - ~~191, 235, 228, 204,~~ 203 Bytes (Condensed)
```
static Random r=new();static string g(){var z="";for(int j,i,l=r.Next(1,4);l-->0;z+=":")for(i=j=0;i++<4;)z+=r.Next()%8<1&&j++<3?"--":$"{"CRWS"[r.Next(0,3)]}{"rgbypcuw"[r.Next(0,7)]}";return z.Trim(':');}
```
* `+44` bytes due to a missed requirement.
* `-5` bytes by reducing `GetShape` to `g` per [@emanresu A](https://codegolf.stackexchange.com/users/100664/emanresu-a)'s recommendation.
* `-24` bytes by using `var`, consolidating declarations and using constant strings per [@Johan du Toit](https://codegolf.stackexchange.com/users/41374/johan-du-toit).
* `-1` byte by swapping `==0` for `<1` per [@ceilingcat](https://codegolf.stackexchange.com/users/52904/ceilingcat).
#### How it Works
```
// Create a new random number generator using C# 9.0's `new` invocation.
static Random r = new();
static string g() {
    // Create a variable to store the possible shapes.
    string s = "CRWS",
            // Create a variable to store the possible colors.
            c = "rgbypcuw",
            // Create a variable to store the result.
            z = "";
    // Create an iteration variable to iteratively create between 1 and 4 layers randomly.
    // Evaluate for stop then decrement.
    // Append `:` to the result.
    for (int l = r.Next(1, 4); l-- > 0; z+=":")
        // Create an iteration variable to iteratively create the four quadrants.
        // Create a variable for tracking the number of empty quadrants.
        for (int i = 0, j = 0; i++ < 4;)
            // If we haven't reached the maximum number of allowed empty quadrants, a new one can still be added.
            // Use a random number to determine if we should create an empty quadrant.
            // Since && short circuits, the increment of J doesn't occur unless we're adding an empty quadrant.
            if (r.Next() % 8 == 0 && j++ < 3)
                // Add an empty quadrant.
                z += "--";
            // Otherwise, add a shape and color from the variables above,
            //      using a random index within the bounds of the variables lengths.
            else
                z += $"{s[r.Next(0, 3)]}{c[r.Next(0, 7)]}";
    // Return the result and remove any trailing `:`.
    return z.Trim(':');
}
```
#### Sample Output
I called the method in a `for` loop over 10 iterations to sample the output for this post:
```
--CyCpCb:RpCu--Rc
RpCyWbWc:RcWuWyWc
CyWy--Cr:RrWpWuWg
Wp--WuRc
RpCcCgWp
CbWuWgCu:--RcRbWg:CcCuCpCc
RgRpCyCu:CbWyWuCu
CgCuRpCu
CyRc--Ru:WuRuRbRu:--CgRbWr
WpCgCpRu
```
#### Resulting Image Sample
I ran the shape code `CbWuWgCu:--RcRbWg:CcCuCpCc` through and got this result:
[![Screenshot of the image produced by the aforementioned code.](https://i.stack.imgur.com/JUhy8.png)](https://i.stack.imgur.com/JUhy8.png)
[Answer]
# [Charcoal](https://github.com/somebody1234/Charcoal), 51 bytes
```
⪫ＥＥ⊕‽⁴⊕‽⊖Ｘ³³¦⁴⭆Ｅ⁴÷ιＸ³³λ⎇﹪λ³³⁺§RWSCλ§urgbypcw÷λ⁴--¦:
```
[Try it online!](https://tio.run/##bY49C4MwEIb/Ssh0Qpzi1E6lLhYE0ULnNAk2EBNJo9Zfn0altUOH446H9@P4gzlumQ6hcsp4uFhloGT9OoXhTnbSeCmgZkbYDrIkIegPz@WOKjtJB5QSFNXJYmh8DG8/sdmS4HM1KiFBEbTr9aq@SmeYm6G0YtAWNEGURlzp4QknXxghX4DrW3PGi4OgLxtce597PuHfAr29QRBOU7wdh7iPIYR01G8 "Charcoal – Try It Online") Link is to verbose version of code. Explanation:
```
    ‽⁴                                              Random integer 0-3
   ⊕                                                Incremented
  Ｅ                                                 Map over implicit range
         Ｘ³³¦⁴                                      33⁴
        ⊖                                           Decremented
       ‽                                            Random integer
      ⊕                                             Incremented
 Ｅ                                                  Map over random integers
               Ｅ⁴                                   Map over quadrants
                 ÷ι                                 Current random integer
                 ÷                                  Integer divide by
                    ³³                              Literal integer `33`
                   Ｘ                                Raised to power
                      λ                             Current quadrant
              ⭆                                     Map over values and join
                         λ                          Current value
                        ﹪ ³³                        Modulo literal `33`
                       ⎇                            If nonzero then
                             §RWSCλ                 Cyclically indexed colour
                            ⁺                       Concatenated with
                                   §urgbypcw        Shape cyclically indexed by
                                             λ      Current value
                                            ÷       Integer divide by
                                              ⁴     Literal integer `4`
                                               --   Else literal string `--`
⪫                                                 : Join with literal `:`
                                                    Implicitly print
```
[Answer]
# [Vyxal](https://github.com/Vyxal/Vyxal) `rR`, 37 bytes
```
\:4℅ƛ«3⟩∑ḣ`«`SWRC`Ẋ‛--J33²²‹℅τ∑₅8ε-;j
```
[Try it Online!](https://lyxal.pythonanywhere.com?flags=rR&code=%5C%3A4%E2%84%85%C6%9B%C2%AB3%E2%9F%A9%E2%88%91%E1%B8%A3%60%C2%AB%60SWRC%60%E1%BA%8A%E2%80%9B--J33%C2%B2%C2%B2%E2%80%B9%E2%84%85%CF%84%E2%88%91%E2%82%858%CE%B5-%3Bj&inputs=&header=&footer=)
This uses a quite neat custom-base-decompression-based approach to ensure there'll never be an empty layer. It basically generates a random number between 1 and \$33^4 - 1\$, decompresses it with the key as all possible quadrants (with `--` first, so 0 can never occur, so empty layers won't either).
```
  4℅ƛ                              ;  # array of length (random 1-4) filled with...
                       33²²‹℅         # Random integer between 1 and 33^4-1 inclusive 
                             τ        # Decompressed by...
                  Ẋ                   # Cartesian product of...
     «3⟩∑ḣ`«                          # Compressed string `bcgpruwy`
            `SWRC`                    # String literal `SWRC`
                   ‛--J               # Prepend a `--`
                              ∑       # Concatenate all this
                               ₅8ε-   # Pad with `-` from the start
                                    j # Join the whole thing by...
\:                                    # Semicolons.
```
[Answer]
# [Ruby](https://www.ruby-lang.org/), ~~117~~ 114 bytes
```
->{s=((0..19).map{|i|i%5<1??::"-SWCR"[(r=rand 40)/8]+"rgbpucyw-"[r<8?8:r%8]}*'').gsub ?:+?-*8,''
s>''?s[1,99]:f[]}
```
[Try it online!](https://tio.run/##HcjBCoMgAADQ@74ihFArXcEGKpWH/cF22EE8ZFvhoRGajLC@vcHe8blg1mNoDtJG3yBUUlpxTKdujpvdbHqtKymFAOTxvN2BQq5x3eeVXEp8ZjoHbjRz6NcvAcrVTDLhUqb3DEJMRx9MIkUuScYKCE@@hVB6VRWcazEovR@c08VObx/nsPjkXz8 "Ruby – Try It Online")
A function returning a string.
**Commented code (original version)**
```
->{s=
 ((0..19).map{|i|i%5<1?     #Iterate 20 times to make an array. if i%5==0  
 ?::                        #put a colon, else...
  "-SWCR"[(r=rand 40)/8]+   #Select a shape
  (r<8??-:"rgbpucyw"[r%8])  #If selected shape is - then put another -, else put a colour
  }*'').                    #Convert the 20-element array into a string
  gsub(?:+?-*8,'')          #Delete all instances of :--------
  s<?!?f[]:s[1,99]}         #If s is empty, recursively call f[] to try again. Else output s (minus the initial colon) 
```
[Answer]
# [C (gcc)](https://gcc.gnu.org/), 137 bytes
```
#define r rand()
m;b;q(){m=r;m&30||q();}f(){for(q(b=5+r%4*5);--b;)printf(b%5?m&1<<b%5?"%c%c":"--":":"+!q(),"WRSC"[r%4],"rugbywcp"[r%8]);}
```
[Try it online!](https://tio.run/##HU5NC4IwAL37K9ZC2dKBUUI4pUP/oA4dwoObTgZt6TQk1L/eml0e7z14H5w0nFu7rWohdQ0MMKWuEPYUZbRDeFK5oSo4xPPsFF2Es8TLoA6xPAmNf9wlmBLCKG6N1INAzE/OKthn2Uqgz30OU0iIgxSGG9cRwfv1doEPly0iaN4N@4y8XfWpcANWlVIjDCYPgP7/ZZCqRjHG1DlunnqL/XLxLJvekvEH "C (gcc) – Try It Online")
-5 bytes thanks ceilingcat!
[Answer]
## [Perl 5](https://www.perl.org/), ~~95~~ 138 bytes
```
{@q=(qw(: --),map{$s=$_;map$s.$_,ugbrycpw=~/./g}C,R,W,S);@i=map$_%5?$==1+rand
33:0,1..rand 19;@i%5==4&&" @i "!~/ (1 ){4}/||redo;say@q[@i]}
```
[Try it online!](https://tio.run/##FcrdCoIwGIDh865iyRSluTV0Bzk@GnQHddBBhFiKCP3ohon4c@tLz94XnrrQL2FbU6CfoHwv7aAa8JvOT1AYBuSd1QM2gFO5FDYUp6QtH7p/1h3MjLJyOpEzuZJLIFUFq0ldccQAfKezT76JomRPOKXrIH5YkCsAYs9zkKqQs50Z8jkKhnhi46iL/CtN1qvmpqr7ZO0f "Perl 5 – Try It Online")
[Answer]
# [Java (JDK)](http://jdk.java.net/), ~~263~~ 253 bytes
-10 thanks to ceilingcat! Forgot that `|` exists and that ternary `if`s can be written without parentheses. D'oh!
```
String f(int i){var r=new Random();var q=""+"SWCR-".charAt(r.nextInt(5));q+=q.equals("-")?'-':"ugbrycpw".charAt(r.nextInt(8));return i<1?(f(2)+f(2)+f(2)+f(3)).substring(1):i<9?i>2|r.nextInt(2)<1?(":"+f(9)+f(9)+f(9)+f(9)).replace(":--------",f(1)):"":q;}
```
[Try it online!](https://tio.run/##bZA9T8MwEIb3/IqTl/oUYqVFSDRuqBATAwztwIAY3MQpLomTOE5LVfrbg9NEAiE8vNJ9vHfnZyf2ItilH50qqtJY2LmYtVblbCV0Whbc85JcNA08CaVPHoDSVppMJBKe@xBgbY3SW0ioq4BG7pJnz0ljhVUJdGM9u9QVnvbCgIm1PMCwgSLvU3VMiE/WLw@rgLDkXZh7Sw3T8tM@aktvEHntxzWTdSvyhpKA4HISTCLSbjfmmFSHf0y3zmSkbY0GtZguaUZn6P@Wa0TWtJvmciGdYqQW86W6m339zJhh7yQRce1z/CPIjKxyx8I1BOMjV5mbhBEhUc3PHe9RVO0mdyhGIvtSpVA4nHRA8/oGAgeWkJUGBlAQQ8j7u8OQK99HGBp64MfGyoKVrWWV89tcu5@FOJI/d98 "Java (JDK) – Try It Online")
Took forever to find something promising, ow my head...
This won't win any prices, but I liked the approach so here it is anyways. It uses the same function recursively with a different parameter to build different parts of the string.  
I hope I find the template for Java lambdas again, I keep forgetting how the boilerplate needs to look for them to work :(
## EDIT:
Function lamdas aren't shorter in this case, since you don't call but `apply()` them, which is WAY longer. Still, thanks for the template `Johan du Troit`!
### Explained:
```
// function is called with 0 to start
String f(int i) {
    // use var because it's shorter
    var r=new Random();
    // build a quadrant
    // decide on a type...
    var q=""+"SWCR-".charAt(r.nextInt(5));
    // ...and append the color. If the type is "-" then append a "-" instead
    q+=q.equals("-")?'-':"ugbrycpw".charAt(r.nextInt(8));
    
    // decide what to return
    return 
    // shape case: build full shape
    i<1?
      // a shape consists of four layers
      // each layer starts with a :, cut the first one off
      (f(2)+f(2)+f(2)+f(3)).substring(1)
    // not the starting case, check for layer case
    :i<9?
      // build one layer. It either doesn't exist or contains four shapes
      // note: 3 overrides the random decision and always returns a layer
      i>2|r.nextInt(2)<1?
        // replace an empty layer with a newly generated one...
        (":"+f(9)+f(9)+f(9)+f(9)).replace(":--------",f(1)) 
        // ...or return a nonexistant layer
        :""
    // not the shape case nor the layer case, return the quadrant calculated above
    :q;
}
```
[Answer]
# [APL(Dyalog Unicode)](https://dyalog.com), 64 bytes [SBCS](https://github.com/abrudz/SBCS)
A full program that prints the shape.
```
⊃{∊⍺':'⍵}/{∊((⊂'--'),,'RWCS'∘.,'urgbypcw')[?4⍴33]}⍣{∨/'-'≠⍺}¨⍳?4
```
[Try it on APLgolf!](https://razetime.github.io/APLgolf/?h=AwA&c=e9TVXP2oo@tR7y51K/VHvVtr9UFcDY1HXU3qurrqmjo66kHhzsHqjzpm6OmolxalJ1UWJJera0bbmzzq3WJsHFv7qHcxUMsKfXVd9UedC4AG1R5a8ah3s70JAA&f=AwA&i=AwA&r=tryapl&l=apl-dyalog&m=tradfn&n=f)
`?4` random integer between 1 and 4  
 `... ¨⍳` call the function on the left this many times and collect the results in a list:
`{ ... }⍣{∨/'-'≠⍺}` until any char in the result is not `-`:  
`'RWCS'∘.,'urgbypcw'` Cartesian product of the two strings  
`,` flatten into a list of 2-char strings  
`(⊂'--'),` prepend the empty quadrant  
`( ... )[?4⍴33]` get elements at 4 random indices between 1 and 33.  
`∊` flatten into a string
`{∊⍺':'⍵}/` join with `:`  
`⊃` get the first element from the nested output
[Answer]
# JavaScript, ~~125~~ ~~120~~ ~~119~~ ~~115~~ ~~112~~ 118 bytes
To avoid the possibility of an empty layer, we force the 4th quadrant to be non-empty *if* all previous quadrants are already empty (+6 bytes 'cause I realised I'd screwed that up).
Need to figure out a way to shorten the selection of the characters.
```
(r=x=>Math.random(g=s=>s[7]?l--?s+`:`+g``:s:g(s+`RWSC-`[c=r(5^s==`------`)]+`urgbypcw-`[c-4?r(8):8]))*x|0,l=r(4))=>g``
```
[Try it online!](https://tio.run/##HYyxDoIwFEV/p89aUhOMpPhgcHbRwYFgWlGqplLSItbEf6/o3U5Ozr2rUfnG3fqBjVlsMRKHAYutGq6JU93ZPohGj4WvVnVpGCs9lUJSLaXwQpOJdof9hsmqQUeWR48o2X8SaiqfTp/effP6eZaWjmQgshpgFj58bqYiBcBiOoutdSQgzwOl6wXnOTS289ZcEmM1aQlA/AI)
[Answer]
# [CSASM v2.5.1](https://github.com/absoluteAquarian/CSASM/releases/tag/v2.5.1), 514 bytes
```
func a:
lda 0
sta $1
lda ""
sta $2
push 1
push 5
extern Random.Next(i32,i32)
pop $a
.lbl a
push $a
brfalse b
dec $a
push 0
pop $1
push ""
pop $3
.lbl c
push $1
push 4
sub
brfalse d
inc $1
push "RWSC-"
push 5
extern Random.Next(i32)
dup
push 1
add
substr
dup
push "-"
sub
len
brtrue f
dup
add
br e
.lbl f
push "urgbypcw"
push 8
extern Random.Next(i32)
dup
push 1
add
substr
add
.lbl e
push $3
swap
add
dup
pop $3
push "--------"
sub
len
brtrue c
push 0
pop $1
push ""
pop $3
br c
.lbl d
push $2
push $3
add
pop $2
push $a
brfalse a
push $2
push ":"
add
pop $2
br a
.lbl b
push $2
print
ret
end
```
Whew, this was one mammoth of a program to write.
This submission defines a function `a` which generates then prints the random shape string as is specified by the challenge.
---
**Explained:**
```
func a:
    ; $a = random value in [1, 4]
    ; $1 = loop counter for quadrants
    ; $2 = final string
    ; $3 = build string
    lda 0
    sta $1
    ; Initialize $2 to an empty string
    lda ""
    sta $2
    
    ; Initialize $a to the random value specified above
    push 1
    push 5
    extern Random.Next(i32,i32)
    pop $a
    .lbl a
        ; Stop looping if $a == 0
        push $a
        brfalse b
        dec $a
        ; Reset $1 and $3
        push 0
        pop $1
        push ""
        pop $3
        .lbl c
            ; Stop looping if $1 == 4
            push $1
            push 4
            sub
            brfalse d
            inc $1
            
            ; Get a random letter in "RWSC-"
            push "RWSC-"
            push 5
            extern Random.Next(i32)
            dup
            push 1
            add
            substr
            ; Check if the letter was "-"
            dup
            push "-"
            sub
            len
            brtrue f
            ; Letter was "-"; just add the other one
            dup
            add
            br e
        .lbl f
            ; Letter was not "-"; Get the color
            push "urgbypcw"
            push 8
            extern Random.Next(i32)
            dup
            push 1
            add
            substr
            ; Add the two parts together
            add
        .lbl e
            ; Add the new piece to $3
            push $3
            swap
            add
            dup
            pop $3
            ; Check $3.  If it's "--------", generate another layer
            push "--------"
            sub
            len
            brtrue c
            
            ; Reset the quadrants counter and build string
            push 0
            pop $1
            push ""
            pop $3
            br c
        .lbl d
            ; Append the layer to the result
            push $2
            push $3
            add
            pop $2
            
            ; If $a == 0, don't add the ":"
            push $a
            brfalse a
            push $2
            push ":"
            add
            pop $2
            br a
.lbl b
    ; Print the result
    push $2
    print
    ret
end
```
---
The first run of this code produce the following shape:  
`--Cp----:--RgSg--:CgRwWbRr:WyWpWwWw`
[![Shape](https://i.stack.imgur.com/eOHxy.png)](https://i.stack.imgur.com/eOHxy.png)
More examples of shapes generated by the code:
```
--ScWyRp
WuWuCbRg:--RbSwRc:CwRuWrCb
CgSgRpCb:Cu--SrRb
Wc--CcCg:----CrRu
SyCbWc--
SrCbSc--:----WrWb
Ry--CgSr:--Cp--Sw
--CwWpCc:CbCpRcSy:CpWw--Cy:--Ru----
```
[Answer]
# [MathGolf](https://github.com/maxbergmark/mathgolf/blob/master/math_golf.txt), 49 [bytes](https://github.com/maxbergmark/mathgolf/blob/master/code_page.py)
```
{╘4{4{"CRSW"w"bcgpruwy"w+v¶╛æ;û--}Γy}Γ'-8*a-}↔':u
```
[Try it online.](https://tio.run/##y00syUjPz0n7/7/60dQZJtUm1UrOQcHhSuVKScnpBUWl5ZVK5dplh7Y9mjr78DLrw7t1dWvPTa4EYnVdC61E3dpHbVPUrUr//wcA)
The first output was: `CwRuRrRw:RpSwSbRp:RcWpRpCu:CpWwWgWc`:  
[![enter image description here](https://i.stack.imgur.com/EnkXXs.png)](https://i.stack.imgur.com/EnkXXs.png)
**Explanation:**
```
{ ... }↔          # Do while false without popping:
 ╘                #  Empty the stack (in case we've encountered a fully empty result)
  4{              #  Loop 4 times:
    4{            #   Inner loop 4 times:
      "CRSW"w     #    Push a random character from "CRSW"
      "bcgpruwy"w #    Push a random character from "bcgpruwy"
       +          #    Concat these two characters together
        v         #    Push a random integer in the range [-2147483648,2147483647]
         ¶╛       #    If this integer is a prime number,
           æ      #    use the following four character as inner code-block:
            ;     #     Discard the earlier character pair
             û--  #     Push "--"
     }            #   After the inner loop:
      Γ           #   Wrap the top four items into a list
       y          #   And join this list together to a single string
   }              #  After the outer loop:
    Γ             #  Wrap the top (up to) four items into a list
     '-8*a-      '#  Remove any strings consisting of 8 "-"
}↔                # After the do-while false:
  ':u            '# Join the list with ":" delimiter
                  # (after which the entire stack is output implicitly as result)
```
Compressed strings are pretty mediocre in MathGolf, so unfortunately it won't save any bytes here. `"CRSW"w` can be [`╖╖`'w+wδ`](https://tio.run/##y00syUjPz0n7///R1GlAlKBerl1@bsv//wA) which is 1 byte longer, and `"bcgpruwy"` can be [`╕█≈║☺ 'ußy`](https://tio.run/##ASEA3v9tYXRoZ29sZv//4pWV4paI4omI4pWR4pi6ICd1w595//8) which is the same byte-count.
[Answer]
# JavaScript (ES6), 117 bytes
*-2 thanks to [@l4m2](https://codegolf.stackexchange.com/users/76323/l4m2)*
Although this is not required, this solution has a uniform distribution.
```
f=(k=(R=Math.random)()*4|0,q=R(n=4)*1185920)=>n--?f(k,q/33)+'SWCR-'[((q%=33)&35)%7]+'ugbrycpw-'[q>>2]:k?f(k-1)+':':''
```
[Try it online!](https://tio.run/##LYu7DoJAFAV/ZRvkXmCRZ1R0sbC2wcLCUCAvEdyFBTUm/juiMaeZnMlck0fSp7JqB8pFlo9jwaBmELF9MlxMmfBM3BBQ896W0bEIOPNQs@2lv3IsZCGndFtAbXRz10VdPRx3EVVPAJ3CpmPm@qgsYl29l2f5Stvn5LowdOKg/lbUnpJgmjoWQkI15JIwYq3JjzbE@aOuI0kF70WTm40ooQDE8QM "JavaScript (Node.js) – Try It Online")
[Answer]
# [Bash](https://www.gnu.org/software/bash/), 158 bytes
```
p='eval printf %s, '
s=$($p {S,W,C,R}{u,g,b,r,y,c,p,w})--
l=`$p{$s}{$s}{$s}{$s}`
$p{$l}:{$l}:{$l}:{$l}|tr , \\n|sed -E "s/-{4}(:|$)//g;/(^|:)(:|$)/d"|shuf -n1
```
[Attempt This Online!](https://ato.pxeger.com/run?1=m70kKbE4Y8GCpaUlaboWN-cV2KqnliXmKBQUZeaVpCmoFusoqHMV26poqBQoVAfrhOs46wTVVpfqpOsk6RTpVOok6xTolNdq6upy5dgmqBRUqxTXIuMELpBYTq0VKlFTUqSgoxATk1dTnJqioOuqoFSsr1ttUqthVaOiqa-fbq2vEVdjpQnhpijVFGeUpino5hlCXAl1LMzRAA)
[Answer]
# [FMSLogo](https://fmslogo.sourceforge.io/manual), 106 bytes
```
show bl map[word pick bf invoke[(crossmap "word ? ? ? ?)]se[--]crossmap "word[RWCS urgbycpw]":]random 1500
```
Don't try it online. The [calormen.com](https://www.calormen.com/jslogo/#) logo interpreter does not support "templates" (which is what logo calls anonymous functions) on map, only procedure names; it's error messages also leave something to be desired.
The program works in FMSLogo 8.3.2 and propably MSWLogo and UCBLogo as well, as FMSLogo is based on them.
Explaination:
* Logo is based on lisp but allows omitting parentheses around procedures that use their default arity.
* `crossmap` generates all possible combinations of the members of its inputs, which can be given in a list. The first input is a function, or "template", which is passed each combination to combine them.
* I don't know a better way to remove the empty layer yet, so the first `crossmap` generates a 1185921 element list of every possible layer and then `bf` removes the first one. That's why this program takes approximately 27 seconds to run on my laptop.
* Numbers can be coerced to strings in logo, so `map` maps the big instruction list in the middle over the characters of a random number, which has some length between one and four. `repeat 1+random 4[...]` would not output the concatenation of the results, and using `map[...]iseq random 4 4` is 4 characters longer.
* I would not be able to tell, of course, but maybe some correlation in the random number generator makes some shapes actually impossible. I am not going to investigate.
Anonymous functions can not be called the normal way, unlike in javascript for example. They must be called by `apply`, `map`, or similar, which is why I consider
```
[bl map[word pick bf invoke[(crossmap "word ? ? ? ?)]se[--]crossmap "word[RWCS urgbycpw]":]random 1500]
```
to be an invalid submission.
Alternative much faster 5 characters longer solution, which, unlike the submission, can propably produce empty output:
## FMSLogo, 111 bytes
```
show bl map[invoke[if ?="--------: ["][?]]word map[pick se[--]crossmap "word[RWCS urgbcypw]]1234 ":]random 1500
```
Sample shape: `CpCuRpSc:SwSuCcWr:Sb--RwSb` (everyone seems to do this)
[![A Shape](https://i.stack.imgur.com/cvq6x.png)](https://i.stack.imgur.com/cvq6x.png)
[Answer]
# [Wolfram Language (Mathematica)](https://www.wolfram.com/wolframscript/), 155 bytes
```
r=RandomInteger
c=RandomChoice
t=Table
StringRiffle[StringJoin/@(Nest[#/.c@#->"--"&,#,r@2]&/@t[t[#<>#2&@@c@*Characters/@{"RWSC","urgbypcw"},4],r@3+1]),":"]
```
The distribution of the non-empty quadrants is uniform, but the distribution of shapes is not, as empty quadrants are generated after the fact.
*TIO* requires two extra bytes for symbol assignment so that the output can be printed.
[Try it online!](https://tio.run/##LY1PC4IwHEDvfowJ0p/ZyDpFyg881SFCgw6yw1xThzpj/iIi@uxLqOPj8Xi9wEb1ArUUztk4E@Y29AeDqlbWk39Om0FL5WF8EWWnvDbO0WpTZ7qqOlX84Dhow2B2UiMWPltJ8MOEhCEJqE8tRDxggMWk9okfBQASFmkjrJCo7MjgTbJrnhJKHrYuX3f5JB@65VO4Wa75nJId4e48bRBa9wU "Wolfram Language (Mathematica) – Try It Online")
[Answer]
# [JavaScript (V8)](https://v8.dev/), ~~117 116~~ 114 bytes
```
f=(k=n=5*~R(4))=>++n?n%5?R(~k%5)?'--'+f(k+1):'SWCR'[R(4)]+'ugbrycpw'[R(8)]+f(k):':'+f(n):''
R=n=>Math.random()*n|0
```
[Try it online!](https://tio.run/##FcxBC4IwHAXwe99D9v87lAkJok0PnbusQ4fosMxZaZtMM4Pwq9uEd3g8frynHGVf2kc3BGOyKO4CDdc89mcBW0SeU6oL7cWFgLnxYixIEBCqoKERpuR42gtyXuWFknd9td@y@6xD4gaHHElXrV0hG@GO84Mc7qGV@mZegL7@sUUZCxNn2UTpLmIsw9Lo3rRV2JoaFCAufw "JavaScript (V8) – Try It Online")
If already \$k\$ empty in this layer, then there's \$\frac 1{4-k}\$ probably be not empty, aka 1 when already 3 empty
]