Ninjasharp commited on
Commit
3538126
Β·
verified Β·
1 Parent(s): caf0509

Upload 2 files

Browse files
Files changed (2) hide show
  1. app.py +248 -166
  2. requirements.txt +2 -1
app.py CHANGED
@@ -1,183 +1,265 @@
1
  import streamlit as st
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2
 
3
  def create_spin_wheel_app():
 
 
 
4
  # Set page config
5
  st.set_page_config(
6
- page_title="Spin the Wheel!",
7
  page_icon="🎯",
8
  layout="wide"
9
  )
10
 
11
- # Add title and description
12
- st.title("🎯 Spin the Wheel!")
13
- st.write("Click the wheel to spin and win tickets!")
14
-
15
- # HTML and JavaScript code for the spinning wheel
16
- html_code = """
17
- <!DOCTYPE html>
18
- <html lang="en">
19
- <head>
20
- <meta charset="UTF-8">
21
- <title>Spin the Wheel</title>
22
- <script src="https://d3js.org/d3.v3.min.js" charset="utf-8"></script>
23
- <style>
24
- text {
25
- font-family: Helvetica, Arial, sans-serif;
26
- font-size: 19px;
27
- pointer-events: none;
28
- }
29
- #chart {
30
- position: relative;
31
- width: 500px;
32
- height: 500px;
33
- margin: 0 auto;
34
- }
35
- #question {
36
- text-align: center;
37
- margin-top: 20px;
38
- }
39
- #question h1 {
40
- font-size: 32px;
41
- font-weight: bold;
42
- font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
43
- margin: 0;
44
- padding: 10px;
45
- }
46
- </style>
47
- </head>
48
- <body>
49
- <div id="chart"></div>
50
- <div id="question"><h1></h1></div>
51
-
52
- <script>
53
- var padding = {top:20, right:40, bottom:0, left:0},
54
- w = 360 - padding.left - padding.right,
55
- h = 360 - padding.top - padding.bottom,
56
- r = Math.min(w, h) / 2,
57
- rotation = 0,
58
- oldrotation = 0,
59
- picked = 100000,
60
- oldpick = [],
61
- color = d3.scale.category20();
62
-
63
- var data = [
64
- {"label": "🎟️", "value": 1, "question": "1 Ticket"},
65
- {"label": "🎟️", "value": 2, "question": "2 Tickets"},
66
- {"label": "🎟️", "value": 3, "question": "3 Tickets"},
67
- {"label": "🎟️", "value": 4, "question": "4 Tickets"},
68
- {"label": "🎟️", "value": 5, "question": "5 Tickets"},
69
- {"label": "🎟️", "value": 6, "question": "6 Tickets"},
70
- {"label": "🎟️", "value": 7, "question": "7 Tickets"},
71
- {"label": "🎟️", "value": 8, "question": "8 Tickets"},
72
- {"label": "🎟️", "value": 9, "question": "9 Tickets"},
73
- {"label": "🎟️", "value": 10, "question": "10 Tickets"}
74
- ];
75
-
76
- var svg = d3.select('#chart')
77
- .append("svg")
78
- .data([data])
79
- .attr("width", w + padding.left + padding.right)
80
- .attr("height", h + padding.top + padding.bottom);
81
-
82
- var container = svg.append("g")
83
- .attr("class", "chartholder")
84
- .attr("transform", "translate(" + (w/2 + padding.left) + "," + (h/2 + padding.top) + ")");
85
-
86
- var vis = container.append("g");
87
-
88
- var pie = d3.layout.pie().sort(null).value(function(d){ return 1; });
89
-
90
- var arc = d3.svg.arc().outerRadius(r);
91
-
92
- var arcs = vis.selectAll("g.slice")
93
- .data(pie)
94
- .enter()
95
- .append("g")
96
- .attr("class", "slice");
97
-
98
- arcs.append("path")
99
- .attr("fill", function(d, i){ return color(i); })
100
- .attr("d", function(d){ return arc(d); });
101
-
102
- arcs.append("text").attr("transform", function(d){
103
- d.innerRadius = 0;
104
- d.outerRadius = r;
105
- d.angle = (d.startAngle + d.endAngle) / 2;
106
- return "rotate(" + (d.angle * 180 / Math.PI - 90) + ")translate(" + (d.outerRadius - 10) + ")";
107
- })
108
- .attr("text-anchor", "end")
109
- .text(function(d, i){ return data[i].label; });
110
-
111
- container.on("click", spin);
112
-
113
- function spin(d){
114
- container.on("click", null);
115
- if(oldpick.length == data.length){
116
- oldpick = [];
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
117
  }
118
- var ps = 360/data.length,
119
- pieslice = Math.round(1440/data.length),
120
- rng = Math.floor((Math.random() * 1440) + 360);
121
- rotation = (Math.round(rng / ps) * ps);
122
- picked = Math.round(data.length - (rotation % 360)/ps);
123
- picked = picked >= data.length ? (picked % data.length) : picked;
124
- if(oldpick.indexOf(picked) !== -1){
125
- d3.select(this).call(spin);
126
- return;
127
- } else {
128
- oldpick.push(picked);
 
 
 
 
 
 
 
 
 
 
 
 
129
  }
130
- rotation += 90 - Math.round(ps/2);
131
- vis.transition()
132
- .duration(3000)
133
- .attrTween("transform", rotTween)
134
- .each("end", function(){
135
- d3.select("#question h1")
136
- .text(data[picked].question);
137
- oldrotation = rotation;
138
- container.on("click", spin);
139
- });
140
- }
141
-
142
- svg.append("g")
143
- .attr("transform", "translate(" + (w + padding.left + padding.right) + "," + ((h/2)+padding.top) + ")")
144
- .append("path")
145
- .attr("d", "M-" + (r*.15) + ",0L0," + (r*.05) + "L0,-" + (r*.05) + "Z")
146
- .style({"fill":"black"});
147
-
148
- container.append("circle")
149
- .attr("cx", 0)
150
- .attr("cy", 0)
151
- .attr("r", 60)
152
- .style({"fill":"white","cursor":"pointer"});
153
-
154
- container.append("text")
155
- .attr("x", 0)
156
- .attr("y", 15)
157
- .attr("text-anchor", "middle")
158
- .text("SPIN")
159
- .style({"font-weight":"bold", "font-size":"30px"});
160
-
161
- function rotTween(to) {
162
- var i = d3.interpolate(oldrotation % 360, rotation);
163
- return function(t) { return "rotate(" + i(t) + ")"; };
164
- }
165
- </script>
166
- </body>
167
- </html>
168
- """
169
-
170
- # Embed the HTML code using st.components.v1.html
171
- st.components.v1.html(html_code, height=600)
172
 
173
  # Add instructions
174
- with st.expander("How to Play"):
175
  st.write("""
176
- 1. Click the 'SPIN' button in the center of the wheel
177
- 2. Wait for the wheel to stop spinning
178
- 3. See how many tickets you've won!
179
- 4. The wheel can be spun multiple times
 
180
  """)
 
 
 
 
 
 
 
 
 
 
 
 
181
 
182
  if __name__ == "__main__":
183
- create_spin_wheel_app()
 
1
  import streamlit as st
2
+ import pandas as pd
3
+ from datetime import datetime
4
+
5
+ def initialize_session_state():
6
+ if 'spins_left' not in st.session_state:
7
+ st.session_state.spins_left = 3
8
+ if 'current_tickets' not in st.session_state:
9
+ st.session_state.current_tickets = 0
10
+ if 'high_scores' not in st.session_state:
11
+ st.session_state.high_scores = pd.DataFrame(
12
+ columns=['Player', 'Score', 'Date']
13
+ )
14
+ if 'game_active' not in st.session_state:
15
+ st.session_state.game_active = True
16
+
17
+ def submit_score():
18
+ player_name = st.session_state.player_name
19
+ if player_name.strip():
20
+ new_score = pd.DataFrame({
21
+ 'Player': [player_name],
22
+ 'Score': [st.session_state.current_tickets],
23
+ 'Date': [datetime.now().strftime("%Y-%m-%d %H:%M")]
24
+ })
25
+ st.session_state.high_scores = pd.concat([st.session_state.high_scores, new_score], ignore_index=True)
26
+ st.session_state.high_scores = st.session_state.high_scores.sort_values(by='Score', ascending=False).head(10)
27
+ # Reset game
28
+ st.session_state.spins_left = 3
29
+ st.session_state.current_tickets = 0
30
+ st.session_state.game_active = True
31
+ st.rerun()
32
 
33
  def create_spin_wheel_app():
34
+ # Initialize session state
35
+ initialize_session_state()
36
+
37
  # Set page config
38
  st.set_page_config(
39
+ page_title="Spin the Wheel Game!",
40
  page_icon="🎯",
41
  layout="wide"
42
  )
43
 
44
+ # Create two columns for layout
45
+ col1, col2 = st.columns([2, 1])
46
+
47
+ with col1:
48
+ st.title("🎯 Spin the Wheel Game!")
49
+ st.write(f"Spins left: {st.session_state.spins_left} | Current Tickets: {st.session_state.current_tickets}")
50
+
51
+ # HTML and JavaScript code for the spinning wheel
52
+ html_code = """
53
+ <!DOCTYPE html>
54
+ <html lang="en">
55
+ <head>
56
+ <meta charset="UTF-8">
57
+ <script src="https://d3js.org/d3.v3.min.js" charset="utf-8"></script>
58
+ <style>
59
+ text {
60
+ font-family: Helvetica, Arial, sans-serif;
61
+ font-size: 19px;
62
+ pointer-events: none;
63
+ }
64
+ #chart {
65
+ position: relative;
66
+ width: 500px;
67
+ height: 500px;
68
+ margin: 0 auto;
69
+ }
70
+ #question {
71
+ text-align: center;
72
+ margin-top: 20px;
73
+ }
74
+ #question h1 {
75
+ font-size: 32px;
76
+ font-weight: bold;
77
+ font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
78
+ margin: 0;
79
+ padding: 10px;
80
+ }
81
+ </style>
82
+ </head>
83
+ <body>
84
+ <div id="chart"></div>
85
+ <div id="question"><h1></h1></div>
86
+
87
+ <script>
88
+ var padding = {top:20, right:40, bottom:0, left:0},
89
+ w = 360 - padding.left - padding.right,
90
+ h = 360 - padding.top - padding.bottom,
91
+ r = Math.min(w, h) / 2,
92
+ rotation = 0,
93
+ oldrotation = 0,
94
+ picked = 100000,
95
+ oldpick = [],
96
+ color = d3.scale.category20();
97
+
98
+ var data = [
99
+ {"label": "10🎟️", "value": 10, "question": "10 Ticket"},
100
+ {"label": "20🎟️", "value": 20, "question": "20 Tickets"},
101
+ {"label": "30🎟️", "value": 30, "question": "30 Tickets"},
102
+ {"label": "40🎟️", "value": 40, "question": "40 Tickets"},
103
+ {"label": "50🎟️", "value": 50, "question": "50 Tickets"},
104
+ {"label": "60🎟️", "value": 60, "question": "60 Tickets"},
105
+ {"label": "70🎟️", "value": 70, "question": "70 Tickets"},
106
+ {"label": "80🎟️", "value": 80, "question": "80 Tickets"},
107
+ {"label": "90🎟️", "value": 90, "question": "90 Tickets"},
108
+ {"label": "100🎟️", "value": 100, "question": "100 Tickets"}
109
+ ];
110
+
111
+ var svg = d3.select('#chart')
112
+ .append("svg")
113
+ .data([data])
114
+ .attr("width", w + padding.left + padding.right)
115
+ .attr("height", h + padding.top + padding.bottom);
116
+
117
+ var container = svg.append("g")
118
+ .attr("class", "chartholder")
119
+ .attr("transform", "translate(" + (w/2 + padding.left) + "," + (h/2 + padding.top) + ")");
120
+
121
+ var vis = container.append("g");
122
+
123
+ var pie = d3.layout.pie().sort(null).value(function(d){ return 1; });
124
+
125
+ var arc = d3.svg.arc().outerRadius(r);
126
+
127
+ var arcs = vis.selectAll("g.slice")
128
+ .data(pie)
129
+ .enter()
130
+ .append("g")
131
+ .attr("class", "slice");
132
+
133
+ arcs.append("path")
134
+ .attr("fill", function(d, i){ return color(i); })
135
+ .attr("d", function(d){ return arc(d); });
136
+
137
+ arcs.append("text").attr("transform", function(d){
138
+ d.innerRadius = 0;
139
+ d.outerRadius = r;
140
+ d.angle = (d.startAngle + d.endAngle) / 2;
141
+ return "rotate(" + (d.angle * 180 / Math.PI - 90) + ")translate(" + (d.outerRadius - 10) + ")";
142
+ })
143
+ .attr("text-anchor", "end")
144
+ .text(function(d, i){ return data[i].label; });
145
+
146
+ container.on("click", spin);
147
+
148
+ function spin(d){
149
+ if (window.parent.document.querySelector('[data-testid="stMarkdownContainer"]').textContent.includes("Spins left: 0")) {
150
+ return;
151
+ }
152
+
153
+ container.on("click", null);
154
+ var ps = 360/data.length,
155
+ pieslice = Math.round(1440/data.length),
156
+ rng = Math.floor((Math.random() * 1440) + 360);
157
+ rotation = (Math.round(rng / ps) * ps);
158
+ picked = Math.round(data.length - (rotation % 360)/ps);
159
+ picked = picked >= data.length ? (picked % data.length) : picked;
160
+ rotation += 90 - Math.round(ps/2);
161
+
162
+ vis.transition()
163
+ .duration(3000)
164
+ .attrTween("transform", rotTween)
165
+ .each("end", function(){
166
+ d3.select("#question h1")
167
+ .text(data[picked].question);
168
+ oldrotation = rotation;
169
+ container.on("click", spin);
170
+
171
+ // Send message to Streamlit
172
+ window.parent.postMessage({
173
+ type: "spin_result",
174
+ value: data[picked].value
175
+ }, "*");
176
+ });
177
  }
178
+
179
+ svg.append("g")
180
+ .attr("transform", "translate(" + (w + padding.left + padding.right) + "," + ((h/2)+padding.top) + ")")
181
+ .append("path")
182
+ .attr("d", "M-" + (r*.15) + ",0L0," + (r*.05) + "L0,-" + (r*.05) + "Z")
183
+ .style({"fill":"black"});
184
+
185
+ container.append("circle")
186
+ .attr("cx", 0)
187
+ .attr("cy", 0)
188
+ .attr("r", 60)
189
+ .style({"fill":"white","cursor":"pointer"});
190
+
191
+ container.append("text")
192
+ .attr("x", 0)
193
+ .attr("y", 15)
194
+ .attr("text-anchor", "middle")
195
+ .text("SPIN")
196
+ .style({"font-weight":"bold", "font-size":"30px"});
197
+
198
+ function rotTween(to) {
199
+ var i = d3.interpolate(oldrotation % 360, rotation);
200
+ return function(t) { return "rotate(" + i(t) + ")"; };
201
  }
202
+
203
+ // Listen for messages from Streamlit
204
+ window.addEventListener("message", function(event) {
205
+ if (event.data.type === "update_spins") {
206
+ // Handle spin update
207
+ }
208
+ });
209
+ </script>
210
+ </body>
211
+ </html>
212
+ """
213
+
214
+ # Handle spin result
215
+ components_kwargs = dict(height=600)
216
+ if st.session_state.game_active:
217
+ components_kwargs["html"] = html_code
218
+ else:
219
+ st.write("Game Over! Submit your score to play again.")
220
+
221
+ st.components.v1.html(**components_kwargs)
222
+
223
+ with col2:
224
+ st.title("πŸ† High Scores")
225
+
226
+ # Display high scores table
227
+ if not st.session_state.high_scores.empty:
228
+ st.dataframe(
229
+ st.session_state.high_scores,
230
+ hide_index=True,
231
+ use_container_width=True
232
+ )
233
+ else:
234
+ st.write("No high scores yet!")
235
+
236
+ # Submit score section
237
+ if st.session_state.spins_left == 0 and st.session_state.game_active:
238
+ st.markdown("### Submit Your Score")
239
+ st.text_input("Enter your name:", key="player_name")
240
+ st.button("Submit Score", on_click=submit_score, disabled=not st.session_state.get('player_name', '').strip())
 
 
 
241
 
242
  # Add instructions
243
+ with st.sidebar.expander("How to Play"):
244
  st.write("""
245
+ 1. You have 3 spins per game
246
+ 2. Click the 'SPIN' button in the center of the wheel
247
+ 3. Collect as many tickets as possible
248
+ 4. After 3 spins, enter your name and submit your score
249
+ 5. Try to get on the leaderboard!
250
  """)
251
+ st.sidebar.info("build by darryl")
252
+ # Handle spin result from JavaScript
253
+ if st.session_state.spins_left > 0 and st.session_state.game_active:
254
+ current_value = st.query_params.get("spin_result", None)
255
+ if current_value is not None:
256
+ current_value = int(current_value)
257
+ st.session_state.current_tickets += current_value
258
+ st.session_state.spins_left -= 1
259
+ if st.session_state.spins_left == 0:
260
+ st.session_state.game_active = False
261
+ st.query_params.clear()
262
+ st.rerun()
263
 
264
  if __name__ == "__main__":
265
+ create_spin_wheel_app()
requirements.txt CHANGED
@@ -1 +1,2 @@
1
- streamlit
 
 
1
+ streamlit
2
+ pandas