File size: 3,980 Bytes
a797471
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
e64c363
a797471
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
e64c363
 
a797471
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
from collections import defaultdict


import streamlit as st
import streamlit.components.v1 as components
import plotly.express as px


st.set_page_config(page_title='Can you be truly random ?', layout = 'wide', page_icon = 'favicon.jpg', initial_sidebar_state = 'auto')



# Custom CSS to styles
st.markdown("""
    <style>
        button {
            padding-top: 50px !important;
            padding-bottom: 50px !important;
        }
    </style>
""", unsafe_allow_html=True)


max_history = 4


def set_state(x):
    if x == 1: st.toast('The journey begins!', icon='😍')
    if x == 2: st.toast('Welcome!', icon='πŸ™ƒ')
    if x == 3: st.toast("Let's play!", icon='πŸ₯°')
    if x == 4: st.toast("Meet your friends!", icon='πŸ€ͺ')
    st.session_state.stage = x

        
def reset_game():
    set_state(0)
    if 'n_buttons' not in st.session_state:
        st.session_state.n_buttons = 2
    st.session_state.history = []
    st.session_state.preds = defaultdict(lambda: defaultdict(int))
    st.session_state.pnl = [0]

if 'stage' not in st.session_state:
    reset_game()

st.title('How random can you truly be?')

if st.session_state.stage == 0:
    st.button('Begin', on_click=set_state, args=[1],use_container_width=True)
    
    st.session_state.n_buttons = st.slider(label="How many buttons to play with?", min_value=2, max_value=5,value=2)
    
    st.markdown(f'You will be presented with {st.session_state.n_buttons} buttons to randomly choose from')
    
    st.markdown("At each round, I will try to predict which button you click :-)")
    st.markdown(f"If I get it right, I earn {st.session_state.n_buttons-1} point(s), otherwise you earn 1 point")
    st.markdown(f"Play as long as you want and try to beat me!")
    
        
    

def get_prev_seqs(history):
    # st.write(history)
    
    seqs = []
    for h in range(max_history+1):
        if len(history) >= h:
            previous_seq = ''.join(history[-h:]) if h > 0 else ""
            # st.write(previous_seq)
            seqs.append(previous_seq) # from small to largest
    return seqs
    
def refresh_preds():
    played = st.session_state.history[-1]
    seqs = get_prev_seqs(st.session_state.history[:-1])
    for seq in seqs:
        # st.write(f'"{seq}"',played)
        st.session_state.preds[seq][played] += 1

def make_pred():
    seqs = get_prev_seqs(st.session_state.history)
    # st.write('seqs',seqs)
    scores = defaultdict(float)
    denominator = 0
    for i,seq in enumerate(seqs):
        weight = (i+1)**2
        preds = st.session_state.preds[seq]
        total = sum(preds.values())
        
        if total:
            for played,value in preds.items():
                scores[played] += weight*value/total
            denominator += weight
    if denominator:
        scores = {played:value/denominator for played,value in scores.items()}
        return scores
    else:
        return {str(i):1/st.session_state.n_buttons for i in range(st.session_state.n_buttons)}
        

def update_pnl(user_win):
    current_score = st.session_state.pnl[-1]
    current_score += -1 if user_win else (st.session_state.n_buttons-1)
    st.session_state.pnl.append(current_score)
    
def user_select(i,choice):
    st.session_state.history.append(str(i))
    if i == choice:
        st.toast("I win!", icon='πŸ€ͺ')
        update_pnl(user_win=False)
    else:
        st.toast('Well done!', icon='😍')
        update_pnl(user_win=True)
    
    refresh_preds()
    
    

if st.session_state.stage == 1:
    pred = make_pred()
    choice = max(pred,key=pred.get)
    
    cols = st.columns(st.session_state.n_buttons)
    for i,col in enumerate(cols):
        col.button(str(i),on_click=user_select, args=[str(i),choice],
        use_container_width=True)

    st.title('My earnings so far... :-)')
    st.plotly_chart(px.line(st.session_state.pnl), use_container_width=True)
    
    st.button('Start over', on_click=reset_game, args=[],
        use_container_width=True)