Roulette game in C++
Since there aren't any loops in your code that aren't waiting for the user to provide some input, it's probably way premature to talk about efficiency. Is your code measurably slow? Does it leave you hanging? If not, unless you have an unusual need, save questions on efficiency for later.

So let's talk about some more important things: readability and maintainability. Here are some tips on ways to improve the readability and maintainability of your code. These aren't hard rules that you should never break (especially the one on comments); they are guidelines on ways to make your life easier that you should learn to bend when the guideline makes things awkward instead.

I hope this helps, even though it may be a lot to take in all at once. Feel free to ask follow-up questions and get other opinions.

Avoid Redundancy

Redundancy can show up in many forms. One example of it is in your declaration of arrays, using code like int betType[11] = {35, 17, 8, 11, 5, 2, 1, 1, 2, 1, 1};. Unless there's something very special about the number 11, there's no reason to call it out. Instead just say int betType[] = {35, 17, 8, 11, 5, 2, 1, 1, 2, 1, 1}; which will automatically determine the size of the array for you.

When you later check your bounds with while (betChoice &lt; 1 || betChoice &gt; 11) {, you can instead use a calculated size (_countof(betType) or sizeof(betType)/sizeof(betType[0])), or even use a std::vector&lt;int&gt; instead of an int[], and check against the vector's size().

This will help you avoid magic numbers that don't mean much later. After all, if someone asks you what's special about 11, would you think it's the number of available bet types? But if they asked what betTypes.size() meant, it would be easy to answer.

Another way redundancy shows up is in large blocks of repeating code. For instance, case 1 and case 2 have almost the same code. In fact I had to read it a couple times to find the part that was different. Sometimes this can be best handled by refactoring similar parts of code into functions, and passing parameters to them that control how they differ. Sometimes it's better just to extract the parts that are identical into simpler functions, and use them. I'll touch on this more below, but I certainly don't have the answer.

Avoid Obfuscation

In the code commented Displays a large dollar sign, there are a lot of casts from int to char so that cout prints the value as a character. But the characters in question are not that unusual. Just use the actual character you want to show, for example replacing 

cout &lt;&lt; endl &lt;&lt; "       " &lt;&lt; (char)36 &lt;&lt; (char)36 &lt;&lt; (char)36 &lt;&lt; (char)36 &lt;&lt; (char)36;


with

cout &lt;&lt; endl &lt;&lt; "       $$$$$"


This will not only be easier to type or update, it will be easier to read.

Avoid Comments

This recommendation is somewhat controversial, but it begins to target your question about functions. Instead of commenting what a line of code does, comment how a block of code does something unusual. When you're first starting out, everything seems unusual, but eventually you will see patterns and only need to comment on things that are not common patterns.

But then, instead of commenting what a block of code does, give it a name instead by putting it in a function. For example, you have several cases where you ask how much the user wants to bet on a number, then loop until they enter a valid number. You could extract this loop into a helper function like this:

int getBetAmount(int bankAccount)
{
    int betAmount;
    cin &gt;&gt; betAmount;
    while (betAmount &lt; 1 || betAmount &gt; bankAccount)
    {
        cout &lt;&lt; endl &lt;&lt; "You have $" &lt;&lt; bankAccount &lt;&lt; " in your bank account: $";
        cin &gt;&gt; betAmount;
    }
    return betAmount;
}

int _tmain() {
    : : :
    case 1:
        : : :
        cout &lt;&lt; endl &lt;&lt; "How much would you like to bet on the number" &lt;&lt; betNumber &lt;&lt; "? $";
        betAmount = getBetAmount(bankAccount);
        : : :
    : : :
    case 2:
        : : :
        cout &lt;&lt; endl &lt;&lt; "How much would you like to bet on the numbers" &lt;&lt; betNumber &lt;&lt; " and " &lt;&lt; betNumber + 3 &lt;&lt; "? $";
        betAmount = getBetAmount(bankAccount);
        : : :
}


Find some other code that doesn't change much and extract that into functions as well. For example, the code commented Checks if player won or lost their bet, I see creating a function you'd call like this:

case 1:
    : : :
    bankAccout = awardWinnings(betNumber == randomNumber, betAmount, betOdds, bankAccount);
    break;
case 2:
    : : :
    bankAccount = awardWinnings(betNumber == randomNumber || betNumber + 3 == randomNumber, betAmount, betOdds, bankAccount);
    break;


After you make these changes, ideally the parts that are different will start to stand out, and the parts that are the same will have good names that tell you what they do even if they don't have a comment. And then you can more easily avoid incorrect comments like case 2's Check if number is valid (between 1 and 36) that actually checks for 33.

You can also avoid comments by naming constants. Instead of starting with int bankAccount = 500 and then 500 lines later referencing 500 to figure out your overall winnings, perhaps declare const int StartingBankAccount = 500; and use the name instead of the number in both places. If you decide to change the initial account wealth, this also helps ensure your ending summary remains correct.

Avoid Bad Dice

While this is a toy program, and a person is unlikely to play long enough for it to matter, rand() % max is a flawed approach to generating random numbers. It's flawed in ways too subtle for me to explain (I understand it, but not well enough to explain it). However Stephan T. Lavavej knows it much better and explains it in a video called rand() Considered Harmful; watch it and use the approach he recommends if you want a more uniformly distributed random number.