Roulette Game

15 minute read

Roulette App in Python

About

During a class I took at Berkeley, I designed an application to simulate a roulette game. The application is written in an object oriented programming structure.

To see the full application, see the drop down at the very end of the report.

Steps

To start the game, you simply run the python script from the command line:

python3 roulette.py

Player Info

The game then asks for some player info such as name, date of birth, and chip count. The player can just keep pressing enter to accept the defaults. But, there is a hidden Easter egg in the game: the letters in your name and number in your birthdate will influence the probabilities on the roulette wheel.

Get ready to gamble!
Next I will ask for some player info.
If you don't want to enter any player info, just keep pressing 'enter' to accept default values.
Press enter to continue.


What is your name? Trevor
Enter DOB (any numeric format seperated by '-' or '/'): 1/30
How many chips do you want to buy (default = 1,000)? 10000

Choose Action

Next, you’ll be asked to choose an action. Let’s select option 4 and choose to gamble.

Welcome to the roulette table.
What would you like to do?
1: Start over and re-define player attributes
2: View history (chip counts, and historical results)
3: Quit
4: Gamble!

Roulette Table

After selecting option 4, we get additional options for gambling strategies. There’s also a table printout to help you make a selection. When pasting the table text below, it did not render the colors. Thus, I’ve taken a screenshot of what you would see in your commandline.

RouletteTable

Take a look at the roulette table
Press enter to continue
Pick a gambling strategy. Type just one of the numbers below to select:

1: Straight-up (any number 1-36, '0', or '00') [PAYOUT = 35:1]
2: Split (any 2 numbers side by side) [PAYOUT = 17:1]
3: Street (any 3 numbers in a row) [PAYOUT = 11:1]
4: Six Line (a group of 6 numbers in 2 rows side by side) [PAYOUT = 5:1]
5: Columns (Horizontal long column) [PAYOUT = 2:1]
6: Dozens (1-12, 13-24, 25-36) [PAYOUT = 2:1]
7: Lows/Highs (half table) (1-18, 19-36) [PAYOUT = 1:1]
8: Colors (red, black) [PAYOUT = 1:1]
9: Evens/Odds [PAYOUT = 1:1]

Place Bets

After choosing a gambling strategy, you can place your bets. I chose to gamble $100 on evens. The wheel landed on 2, so I profited $100.

Enter wager amount:
100
Evens/Odds. Select an option:

1: Evens
2: Odds
1

You win!
Roulette wheel result: 2
You wagered 100 chips
Your payout: 100
Your profit: 100
New chip count: 10100

Press enter to continue

View History

After gambling several times, we can go back to the main menu and select a new option. Let’s take a look at the player history (option 2)

Welcome to the roulette table.
What would you like to do?
1: Start over and re-define player attributes
2: View history (chip counts, and historical results)
3: Quit
4: Gamble!

Historical Plots

We can see 4 different graph types. The screenshots below show all the different options.

Select graph type:
1: Spin History
2: Strategy History
3: Selection History
4: Chip History
5: Go back

Quit

Finally, the game ends when you run out of chips, or select the “Quit” option from the main menu.

The Code

roulette.py
# import libraries
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
from collections import Counter
import re
import string 


class col:
    """used for colored text printouts in the command line"""
    E = '\033[0m'
    R = '\033[0;37;41m'
    B = '\033[0;37;40m'
    G = '\033[0;37;42m'
    blue = '\033[94m'


class PlayerInfo:
    """An object of class PlayerInfo will contain many attributes about the player

    Attributes:
        player_name
        player_dob - year, month, day can be in any order but separated by '-'
        chips - current chip count
        chip_history - list of historical chip counts

    Methods:
        update_chips(n) - setter method to change the chip count. Also appends to chip_history
        log_spins(result) - keep track of historical roulette spins the player made
        log_setups(setup, subsetup) - keep track of historical gamble selections
        __str__ and __repr__ mehods return all player info
    """

    def __init__(self, player_name="", player_dob="", chips=1000):
        self.player_name = player_name
        self.player_dob = player_dob
        if chips == "":
            self.chips = 1000
        else:
            self.chips = int(chips)
        # player history
        self.chip_history = [self.chips]
        self.spin_history = []
        self.setup_history = []
        self.subsetup_history = []

    def update_chips(self, n):
        self.chips += n
        self.chip_history.append(self.chips)

    def log_spins(self, result):
        self.spin_history.append(result)

    def log_setups(self, setup, subsetup):
        self.setup_history.append(setup)
        self.subsetup_history.append(subsetup)

    def __str__(self):
        return "Name: " + self.player_name + "\n" + "DOB: " + self.player_dob + "\n" + "Chips: " + str(self.chips)

    def __repr__(self):
        return self.__str__()


class RouletteWheel:
    """Takes an object of class PlayerInfo as input, and builds a roulette wheel.
    Certain numbers are more likely to appear based on the player name
    and DOB.

    Attributes:
        roulette_df - dataframe of bets and odds to be used in later functions

    Methods:
        table_printout() - returns a picture of a roulette table
        return_df() - returns the roulette_df attribute
    """

    def __init__(self, playerinfo):
        if isinstance(playerinfo, type(PlayerInfo())):
            self.playerinfo = playerinfo

            # build roulette wheel df
            self.original_nums = list(map(lambda x: str(x), range(1, 37))) + ["0", "00"]
            # name scores, and dob scores
            self.player_info_nums = [str(ord(i) - 96) for i in self.playerinfo.player_name.lower()] + list(re.sub("-|/","", self.playerinfo.player_dob))
            self.all_nums = self.original_nums + self.player_info_nums
            self.probs = np.array(list(Counter(self.all_nums).values())) / len(self.all_nums)

            self.roulette_df = pd.DataFrame({
                "numbers": self.original_nums,
                "Colors": ["Red", "Black"] * 5 + ["Black", "Red"] * 4 + ["Black"] +
                          ["Black", "Red"] * 4 + ["Red", "Black"] * 4 + ["Red"] + ["Green"] * 2,
                "Evens_Odds": ["Even" if i % 2 == 0 else "Odd" for i in range(1, 37)] + [None, None],
                "probs": self.probs,
                # For certain types of simple bets, we can set up when this row wins
                "Street": ['1-3'] * 3 + ['4-6'] * 3 + ['7-9'] * 3 + ['10-12'] * 3 + ['13-15'] * 3 + ['16-18'] * 3 +
                          ['19-21'] * 3 + ['22-24'] * 3 + ['25-27'] * 3 + ['28-30'] * 3 + ['31-33'] * 3 + [
                              "34-36"] * 3 + [None, None],
                "Column": ["Column 1", "Column 2", "Column 3"] * 12 + [None, None],
                "Dozen": ["1-12"] * 12 + ["13-24"] * 12 + ["25-36"] * 12 + [None, None],
                "Lows_Highs": ["1-18"] * 18 + ["19-36"] * 18 + [None, None]
            })
        else:
            raise Exception("Input must be of type PlayerInfo")

    def table_printout(self):
        print(f"""
           / ̅ ̅ ̅|-------------------------------------------------------------------|
          /    |{col.R} 3 {col.E}|{col.B} 6 {col.E}|{col.R} 9 {col.E}|{col.R} 12 {col.E}|{col.B} 15 {col.E}|{col.R} 18 {col.E}|{col.R} 21 {col.E}|{col.B} 24 {col.E}|{col.R} 27 {col.E}|{col.R} 30 {col.E}|{col.B} 33 {col.E}|{col.R} 36 {col.E}| Column 3 |
         / {col.G} 0 {col.E} |----------------|-------------------|-------------------|----------|
        |------|{col.B} 2 {col.E}|{col.R} 5 {col.E}|{col.B} 8 {col.E}|{col.B} 11 {col.E}|{col.R} 14 {col.E}|{col.B} 17 {col.E}|{col.B} 20 {col.E}|{col.R} 23 {col.E}|{col.B} 26 {col.E}|{col.B} 29 {col.E}|{col.R} 32 {col.E}|{col.B} 35 {col.E}| Column 2 |
         \ {col.G} 00 {col.E}|----------------|-------------------|-------------------|----------|
          \    |{col.R} 1 {col.E}|{col.B} 4 {col.E}|{col.R} 7 {col.E}|{col.B} 10 {col.E}|{col.B} 13 {col.E}|{col.R} 16 {col.E}|{col.R} 19 {col.E}|{col.B} 22 {col.E}|{col.R} 25 {col.E}|{col.B} 28 {col.E}|{col.B} 31 {col.E}|{col.R} 34 {col.E}| Column 1 |
           \___|----------------|-------------------|-------------------|----------|
               |    1st Dozen   |     2nd Dozen     |     3rd Dozen     |          
               |--------------------------------------------------------|
               |  1-18  |  Even |{col.R}   Red   {col.E}|{col.B}  Black  {col.E}|  Odd  |   19-36   | 
               |________|_______|_________|_________|_______|___________|
        """)

    def return_df(self):
        return self.roulette_df


class GambleSetup:
    """Contains all the info about how the user wants to gamble.

    Attributes:
        gamble_dict - dictionary on setup options
        gamble_df - dataframe of subsetup options (i.e. the specific bet options: red, odds, 1 7 or 23 etc.)
        setup - the users chosen strategy setup (i.e. Columns, Colors, etc.)
        subsetup - the user's selected options (i.e. which numbers to gamble on)
        wager = amount user wants to gamble per selected option. 

    Methods:
        gamble_setup() - prompts input statements for user to specify overall gamble type
        return_setup() - getter method to printout the setup the user selected
        return_subsetup() - getter method to printout the subsetup (specific numbers) user selected
        return_payout() - getter method to prinout the potential payout for their strategy setup
    """

    # each object of class GambleSetup will have wheel options
    # and a gamble_df with gambling options
    def __init__(self):
        self.gamble_dict = {
            1: "Straight-up (any number 1-36, '0', or '00') [PAYOUT = 35:1]",
            2: "Split (any 2 numbers side by side) [PAYOUT = 17:1]",
            3: "Street (any 3 numbers in a row) [PAYOUT = 11:1]",
            4: "Six Line (a group of 6 numbers in 2 rows side by side) [PAYOUT = 5:1]",
            5: "Columns (Horizontal long column) [PAYOUT = 2:1]",
            6: "Dozens (1-12, 13-24, 25-36) [PAYOUT = 2:1]",
            7: "Lows/Highs (half table) (1-18, 19-36) [PAYOUT = 1:1]",
            8: "Colors (red, black) [PAYOUT = 1:1]",
            9: "Evens/Odds [PAYOUT = 1:1]"
        }

        self.gamble_df = pd.DataFrame({
            "row": list(range(1, 10)),
            "setup": ["Straight-up", "Split", "Street", "Six_Line", "Column", "Dozen", "Lows_Highs",
                      "Colors", "Evens_Odds"],
            "options": [["1-36", "0", "00"], ["2 numbers side by side"],
                        ["1-3", "4-6", "7-9", "10-12", "13-15", "16-18", "19-21", "22-24", "25-27", "28-30",
                         "31-33", "34-36"],
                        ["6 numbers in 2 rows"],
                        ["Column 1", "Column 2", "Column 3"],
                        ["1-12", "13-24", "25-36"],
                        ["1-18", "19-36"],
                        ["Red", "Black"],
                        ["Even", "Odd"]],
            "payout": [35, 17, 11, 5, 2, 2, 1, 1, 1]
        })

        # default values:
        self.setup = 0
        self.subsetup = 0
        self.wager = ""

    # Setter method to set the gambling type.
    # Later the object will have the necessary parameters to 
    # sample from the roulette wheel
    # based on inputs into this object.
    def gamble_setup(self):

        s = "Pick a gambling strategy. Type just one of the numbers below to select: \n\n"
        for i in range(1, len(self.gamble_dict) + 1):
            s += str(i) + ": " + self.gamble_dict[i] + "\n"

        while self.setup == "" or self.setup not in [str(i) for i in range(1,10)]:
            self.setup = input(s+"\n")
        
        self.setup = int(self.setup)

        # error checking
        if self.setup not in [i for i in range(11)]:
            raise Exception("Invalid input, start over")

        # define payout
        self.payout = self.gamble_df["payout"][
            self.gamble_df["row"] == self.setup
            ].item()

        self.wager = ""
        if self.setup == 1:
            while self.wager in string.ascii_letters:
                self.wager = input("Enter wager amount per number:\n")
            self.wager = int(self.wager)

            subsetup1 = input("Straight-up. Enter a list of numbers, '0', or '00' separated by commas or spaces.\
                \nAny invalid inputs will be as if you just tossed your chips in the trash.\n")
            self.subsetup = re.split(" |,", subsetup1.strip())

        elif self.setup == 2:
            while self.wager in string.ascii_letters:
                self.wager = input("Enter wager amount per number pair:\n")
            self.wager = int(self.wager)

            subsetup1 = input("Split. Enter any two numbers that are side by side on the board, separated by commas or spaces.\nAny invalid inputs will be as if you just tossed your chips in the trash.\n")
            self.subsetup = re.split(" |,", subsetup1.strip())

        elif self.setup == 3:
            while self.wager in string.ascii_letters:
                self.wager = input("Enter wager amount:\n")
            self.wager = int(self.wager)

            self.subsetup = input("Street. Select an option:\n1: 1-3 \n2: 4-6 \n3: 7-9 \n4: 10-12 \n5: 13-15\
            \n6: 16-187: 19-21 \n8: 22-24 \n9: 25-27 \n10: 28-30 \n11: 31-33 \n12: 34-36\n")
            # if the user does not select a correct number, it asks them again
            while self.subsetup not in [str(i) for i in range(1, 13)]:
                self.subsetup = input("Street. Select an option:\n1: 1-3 \n2: 4-6 \n3: 7-9 \n4: 10-12 \n5: 13-15\
            \n6: 16-187: 19-21 \n8: 22-24 \n9: 25-27 \n10: 28-30 \n11: 31-33 \n12: 34-36\n")

        elif self.setup == 4:
            while self.wager in string.ascii_letters:
                self.wager = input("Enter wager amount:\n")
            self.wager = int(self.wager)

            self.subsetup = input("Six Line. Select an option:\n1: 1-6\n2: 4-9\n3: 7-12\n4: 10-15\n5: 13-18\
            \n6: 16-21 \n7: 19-24\n8: 22-27\n9: 25-30 \n10: 28-33 \n11: 31-36\n")
            while self.subsetup not in [str(i) for i in range(1, 12)]:
                self.subsetup = input("Six Line. Select an option:\n1: 1-6\n2: 4-9\n3: 7-12\n4: 10-15\n5: 13-18\
            \n6: 16-21 \n7: 19-24\n8: 22-27\n9: 25-30 \n10: 28-33 \n11: 31-36\n")

        elif self.setup == 5:
            while self.wager in string.ascii_letters:
                self.wager = input("Enter wager amount:\n")
            self.wager = int(self.wager)

            self.subsetup = input("Column. Select an option:\n\n1: Column 1\n2: Column 2\n3: Column 3\n")
            while self.subsetup not in ["1", "2", "3"]:
                self.subsetup = input("Column. Select an option:\n\n1: Column 1\n2: Column 2\n3: Column 3\n")

        elif self.setup == 6:
            while self.wager in string.ascii_letters:
                self.wager = input("Enter wager amount:\n")
            self.wager = int(self.wager)

            self.subsetup = input("Dozen. Select an option:\n\n1: 1-12\n2: 13-24\n3: 25-36\n")
            while self.subsetup not in ["1", "2", "3"]:
                self.subsetup = input("Dozen. Select an option:\n\n1: 1-12\n2: 13-24\n3: 25-36\n")

        elif self.setup == 7:
            while self.wager in string.ascii_letters:
                self.wager = input("Enter wager amount:\n")
            self.wager = int(self.wager)

            self.subsetup = input("Lows/Highs. Select an option:\n\n1: 1-18\n2: 19-36\n")
            while self.subsetup not in ["1", "2"]:
                self.subsetup = input("Lows/Highs. Select an option:\n\n1: 1-18\n2: 19-36\n")

        elif self.setup == 8:
            while self.wager in string.ascii_letters:
                self.wager = input("Enter wager amount:\n")
            self.wager = int(self.wager)

            self.subsetup = input("Colors. Select an option:\n\n1: Red\n2: Black\n")
            while self.subsetup not in ["1", "2"]:
                self.subsetup = input("Colors. Select an option:\n\n1: Red\n2: Black\n")

        elif self.setup == 9:
            while self.wager in string.ascii_letters:
                self.wager = input("Enter wager amount:\n")
            self.wager = int(self.wager)
            
            self.subsetup = input("Evens/Odds. Select an option:\n\n1: Evens\n2: Odds\n")
            while self.subsetup not in ["1", "2"]:
                self.subsetup = input("Evens/Odds. Select an option:\n\n1: Evens\n2: Odds\n")

        else:
            return "invalid selection"

    def return_setup(self):
        output = self.gamble_df["setup"][self.gamble_df["row"] == self.setup]
        return output

    def return_subsetup(self):
        if self.setup in [1, 2]:
            output = self.subsetup
        elif self.setup == 4:
            temp_dict = {1: "1-6", 2: '4-9', 3: '7-12', 4: '10-15', 5: '13-18',
                         6: '16-21', 7: '19-24', 8: '22-27', 9: '25-30', 10: '28-33', 11: '31-36'}
            output = temp_dict[int(self.subsetup)]
        else:
            output = list(self.gamble_df["options"][self.gamble_df["row"] == self.setup])[0][int(self.subsetup) - 1]

        return output

    def return_payout(self):
        return self.payout


class Results:
    """Contains info about the roulette spin results.

    Attributes:
        roulette_wheel_input: object of class RouletteWheel
        gamble_setup_input: object of class GambleSetup

    Methods:
        spin: randomly samples a number from the roulette wheel. Must proceed the other methods.
        evaluate_win: returns a boolean on whether or not the user won.
    """

    def __init__(self, player_info_input, roulette_wheel_input, gamble_setup_input):
        # inputs from other class objects
        self.chips = player_info_input.chips
        self.rw = roulette_wheel_input
        self.gs = gamble_setup_input
        self.payout = gamble_setup_input.payout
        self.wager = gamble_setup_input.wager
        
        # set defaults
        self.roulette_number = "0"
        self.win = False
        self.chip_delta = 0

    def spin(self):
        self.roulette_number = np.random.choice(
            self.rw.roulette_df["numbers"], size=1,
            p=self.rw.roulette_df["probs"])[0]

    def evaluate_win(self):
        gamblesetup = self.gs.return_setup()
        gamblesubsetup = self.gs.return_subsetup()

        row_num = list(self.rw.roulette_df["numbers"]).index(self.roulette_number)
        possible_wins = list(self.rw.roulette_df.iloc[row_num, :])

        # win is False until proven True
        if (gamblesetup == "Straight-up").bool():
            wager_multiplier = len(gamblesubsetup)
            if self.roulette_number in gamblesubsetup:
                self.win = True
                # if they bet on the same number multiple times, multiply the payout
                self.payout *= gamblesubsetup.count(self.roulette_number)
        
        elif (gamblesetup == "Split").bool():
            wager_multiplier = len(gamblesubsetup)/2
            if self.roulette_number in gamblesubsetup:
                self.win = True
                # if they bet on the same number multiple times, multiply the payout
                self.payout *= gamblesubsetup.count(self.roulette_number)

        elif (gamblesetup == "Six_Line").bool():
            wager_multiplier = 1
            spread = list(map(lambda x: int(x), gamblesubsetup.split("-")))
            if int(self.roulette_number) >= spread[0] and int(self.roulette_number) <= spread[1]:
                self.win = True

        elif gamblesetup.isin(["Street", "Column", "Dozen", "Lows_Highs", "Colors", "Evens_Odds"]).bool():
            wager_multiplier = 1
            if gamblesubsetup in possible_wins:
                self.win = True

        if self.win:
            self.chip_delta = self.wager*self.payout*wager_multiplier
            text = """
You win!
Roulette wheel result: {}
You wagered {} chips
Your payout: {}
Your profit: {}
New chip count: {}
            """.format(self.roulette_number, self.wager*wager_multiplier, self.wager*self.payout, self.chip_delta, self.chips + self.chip_delta)
            return text
        else:
            self.chip_delta = self.wager*wager_multiplier*-1
            text = """
You lose
Roulette wheel result: {}
You wagered {} chips
Your payout: {}
Your profit: {}
New chip count: {}
                """.format(self.roulette_number, self.chip_delta*-1, 0, self.chip_delta, self.chips + self.chip_delta)

        return text


class RouletteGraph:
    """Takes a PlayerInfo object as input, returns matplotlib plots

    Methods:
        spin_barchart() - returns barchart of spin history
        strategy_barchart() - returns barchart of historical strategy selections
        subsetup_barchart() - returns barchart of historical gamble selections
        chip_line() - time series plot of chip history
    """

    def __init__(self, playerinfo):
        self.pi = playerinfo

    def spin_barchart(self):
        x = self.pi.spin_history
        x_distinct = list(set(x))
        x_counts = [x.count(i) for i in x_distinct]
        plt.bar(x_distinct, x_counts, color = "green")
        plt.xlabel("Historical Roulette Numbers")
        plt.ylabel("Count")
        plt.show()
    
    def strategy_barchart(self):
        x = self.pi.setup_history
        x_distinct = list(set(x))
        x_counts = [x.count(i) for i in x_distinct]
        plt.bar(x_distinct, x_counts, color = "green")
        plt.xlabel("Historical Strategies")
        plt.ylabel("Count")
        plt.show()
    
    def subsetup_barchart(self):
        x = self.pi.subsetup_history
        x = list(map(lambda x: str(x), x))
        x_distinct = list(set(x))
        x_counts = [x.count(i) for i in x_distinct]
        plt.bar(x_distinct, x_counts, color = "green")
        plt.xlabel("Historical Selections")
        plt.ylabel("Count")
        plt.show()
    
    def chip_line(self):
        x = self.pi.chip_history
        move = [i for i in range(len(x))]
        plt.plot(move, x)
        plt.xlabel("Moves")
        plt.ylabel("Chip Count")
        plt.show()


class ControlPanel:

    """Object will contain methods to navigate the classes above

    Methods:
        run_setups() - Initialize the game by prompting inputs to setup
        main_menu() - Display 4 main options of the game
        play_game() - Continues to ask user questions while playing the game
    """

    def __init__(self):
        self.Player1 = "0"
        self.RouletteWheel1 = "0"
        self.GambleSetup1 = "0"
    
    def run_setups(self):
        input(f"""
Get ready to gamble! 
Next I will ask for some player info. 
If you don't want to enter any player info, just keep pressing 'enter' to accept default values.
Press {col.blue}enter{col.E} to continue.\n\n""")

        self.Player1 = PlayerInfo(player_name=input("What is your name?"),
                     player_dob=input("Enter DOB (any numeric format seperated by '-' or '/'):"),
                     chips=input("How many chips do you want to buy (default = 1,000)?"))
        self.RouletteWheel1 = RouletteWheel(self.Player1)
        self.GambleSetup1 = GambleSetup()
    
    def main_menu(self):
        #decision = input(f"Welcome to the roulette table.\nWhat would you like to do?\n1: Start over and re-define player attributes\n2: View history (chip counts, and historical results)\n3: Quit\n4: Gamble!\n")
        decision = input(f"""
Welcome to the roulette table.
What would you like to do?
1: Start over and re-define player attributes
2: View history (chip counts, and historical results)
3: Quit
4: Gamble!\n\n""")
        return decision
    
    def play_game(self):

        while True:

            if self.Player1.chips <= 0:
                print(f"{col.R}You ran out of money. Game over.{col.E}")
                break

            decision = self.main_menu()

            # If player chooses to start over and re-define player attributes
            if decision == "1":
                self.Player1 = PlayerInfo(player_name=input("What is your name?"),
                                    player_dob=input("Enter DOB (any numeric format seperated by '-' or '/'):"),
                                    chips=input("How many chips do you want to buy?"))

                self.RouletteWheel1 = RouletteWheel(self.Player1)
                self.GambleSetup1 = GambleSetup()

            # If player chooses to view history
            elif decision == "2":
                
                rg = RouletteGraph(self.Player1)

                while True:
                    plot_select = int(input("Select graph type:\n1: Spin History\n2: Strategy History\n3: Selection History\n4: Chip History\n5: Go back\n"))

                    if plot_select == 1:
                        rg.spin_barchart()
                        continue
                    elif plot_select == 2:
                        rg.strategy_barchart()
                        continue
                    elif plot_select == 3:
                        rg.subsetup_barchart()
                        continue
                    elif plot_select == 4:
                        rg.chip_line()
                        continue
                    elif plot_select == 5:
                        break
                    else:
                        raise Exception("Invalid selection")

            # If player chooses to quit
            elif decision == "3":
                print("Thanks for playing")
                break

            # If player chooses to gamble
            elif decision == "4":

                self.RouletteWheel1.table_printout()
                input(f"Take a look at the roulette table\nPress {col.blue}enter{col.E} to continue")
                self.GambleSetup1.gamble_setup()
                Results1 = Results(player_info_input=self.Player1, roulette_wheel_input=self.RouletteWheel1, gamble_setup_input=self.GambleSetup1)
                Results1.spin()
                Results1.roulette_number
                print(Results1.evaluate_win())

                # store this historical results
                self.Player1.log_spins(Results1.roulette_number)
                self.Player1.log_setups(self.GambleSetup1.return_setup().item(), self.GambleSetup1.return_subsetup())
                self.Player1.update_chips(Results1.chip_delta)
                input(f"Press {col.blue}enter{col.E} to continue")
            else:
                print("Invalid selection")

#------------------------------------------------------------
#------------------------------------------------------------
# run game
game = ControlPanel()
game.run_setups()
game.play_game()