def game_won(self):
# if roulette.choice_num == roulette.twist_num: # а что такое roulette? такого имени в текущем пространстве имен нет
if self.roulette.choice_num == self.roulette.twist_num: # обращаемся к именам в пространстве экземпляра.
print('You won!')
Так как Roulette.twist_num не определен в __init__, то пока не выполнится метод, в котором определяется это имя - будут ошибки. ->
все поля класса экземпляра инициализируем в __init__ хотя бы тем же None.
---------
except Exception:
print('Опаньки...Что-то ты сделал не так...\n')
Перехват всего без остановки - не надо так. Ловим только определенные исключения, даем остальным даем свалить программу, проще будет в отладке и понимании, что же именно пошло не так. Смотрим на конструкцию
except Exception as variable_name_here:
...
raise variable_name_here
----
def input_bet(self): # можно сильно упростить
try:
self.input_bet = int(input('Ваша ставка: \n'))
except Exception:
print('Не число')
self.input_bet = None # в случае проблемы - устанавливаем дефолтное значение. Как только появится основной цикл - проблема вылезет.